我有一个简单的程序,它根据用户提供的鼠标数据绘制几何图形。
我有一个处理鼠标跟踪的类(它获取带有鼠标移动历史记录的列表)和一个
名为 Shape 的抽象类。从这个类中,我派生了一些额外的形状,如圆形、矩形等,并且它们中的每一个都覆盖了抽象的 Draw() 函数。
一切都很好,但是当我希望用户能够切换所需的形状时,问题就来了
手动。我得到了鼠标数据,我知道我应该画什么形状。问题是如何让代码“知道”应该创建并传递哪个对象
为构造函数提供适当的参数。此时也不可能添加新的 Shape 导数,这显然是错误的。
我显然不想写出这样的代码:
List<Shape> Shapes = new List<Shape>();
// somwhere later
if(CurrentShape == "polyline"){
Shapes.Add(new Polyline(Points));
}
else if (CurrentShape == "rectangle"){
Shapes.Add(new Rectangle(BeginPoint, EndPoint));
}
// and so on.
上面的代码显然违反了开闭原则。问题是我不知道如何克服它。主要问题是形状不同
有不同参数的构造函数,这使得它变得更加麻烦。
我很确定这是一个常见问题,但我不知道如何解决它。你有什么想法吗?
当您需要创建全部派生自单个类或实现相同接口的对象时,一种常见的方法是使用factory http://en.wikipedia.org/wiki/Factory_method_pattern。然而,就您而言,一个简单的工厂可能还不够,因为工厂本身需要可扩展。
一种实现方法如下:
interface IShapeMaker {
IShape Make(IList<Point> points);
}
class RectMaker : IShapeMaker {
public Make(IList<Point> points) {
// Check if the points are good to make a rectangle
...
if (pointsAreGoodForRectangle) {
return new Rectangle(...);
}
return null; // Cannot make a rectangle
}
}
class PolylineMaker : IShapeMaker {
public Make(IList<Point> points) {
// Check if the points are good to make a polyline
...
if (pointsAreGoodForPolyline) {
return new Polyline(...);
}
return null; // Cannot make a polyline
}
}
用这些Maker
手头有课程,您可以制作制造商注册表(一个简单的List<IShapeMaker>
)通过制作者将点传递给他们,并在返回非空形状时停止。
该系统仍然是可扩展的,因为您可以添加一对NewShape
and NewShapeMaker
,并将它们“插入”现有框架:一次NewShapeMaker
进入注册表后,系统的其余部分立即准备好识别和使用您的NewShape
.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)