我正在构建一个具有大量类的系统,所有类都具有共同的功能,但是由于重叠的类子集共享了较少的功能。实现这个的最佳方式是什么?
作为一个例子,我将采用SVG(我正在实施化学的子集),尽管我在其他领域有例如化学。这个以及相关的问题在XML Schema中有明确的,不可改变的设计规范。
有一个基类SVGElement
,它有很多共同的功能。所有其他类(SVGLine
,SVGCircle
...)都直接来自此。然后,他们在规范中定义了其他功能(通过XMLattributes),例如:
- x
- width
- fill
- opacity
还有更多。请注意,设计是给定的 - 我们无法重新创建新元素或属性。例如,SVG同时包含circle
和ellipse
(经典问题),其中一个使用r(adius)
,另一个使用width
和height
。子类共享通用功能时,可以使用通用代码。
似乎有以下解决方案:
hasWidth
)并为每个(WidthImplementor
)创建一个委托子类。然后每个类都有一个接口列表(每个SVG属性可能最多20个),可能有100-200个这样的实现者。也许是其他人。
我知道还有其他关于如何设计抽象的SO问题,但这里很大程度上是固定的。我想要一个通用的解决方案,而不仅仅是一个SVG(它被用作一个可以理解的例子)。例如,化学标记语言(CML)还具有100-200个子类和100-200个属性,以稀疏矩阵进行扩展。
答案 0 :(得分:2)
您可能需要考虑将“常用”功能实施为“Decorators”。然后,您可以在解析SVG元素时在运行时应用这些装饰器。
abstract class SVGElement {
public void draw (void) {
return;
}
public boolean hasWidth (void) {
return false;
}
public boolean hasHeight (void) {
return false;
}
// ..
}
// An abstract decorator
abstract class SVGElementDecorator extends SVGElement {
protected SVGElement decoratedElement;
public SVGElementDecorator (SVGElement decoratedElement) {
this.decoratedElement = decoratedElement;
}
public void draw (void) {
decoratedElement.draw ();
}
}
// Decorator to add width functionality
class WidthDecorator extends SVGElementDecorator {
private double width;
public WidthAndHeightDecorator (SVGElement decoratedElement) {
super(decoratedElement);
}
// override base class implementation
public boolean hasWidth (void) {
return true;
}
// implement a new method
public double getWidth (void) {
return width;
}
public void draw (void) {
// do special stuff for width
// ..
// then draw the rest
decoratedElement.draw ();
}
}
然后,当你看到一个椭圆:
SVGElement ellipse = new SVGElement();
ellipse = new WidthDecorator (ellipse);
ellipse = new HeightDecorator (ellipse);