拥有 Shape 接口通常是一个糟糕的设计,因为它非常有限。您需要不同的信息来描述不同的形状。调整大小就是一个很好的例子。对于圆形,您需要更改半径,对于矩形,您需要更改两侧,这意味着传递两个参数而不是一个参数。
您可以通过传递某种形状描述符来克服这个问题,例如实际形状必须适合的矩形。因此,假设您的所有形状都使用类预定义并且您想要缩放它们,则可以正确调整它的大小。如果您想要自定义形状,则必须以某种方式扩展形状描述符以包含自定义形状所需的所有信息,但要与现有形状保持兼容。这不一定很难,您可以添加可以为空的属性或参数。这里我只添加新参数。
private interface ShapeFactory{
public Shape create(float x, float y, float width, float height);
}
private class CircleFactory implements ShapeFactory{
public Shape create(float x, float y, float width, float height){
float radius = Math.min(width, height);
return new Circle(radius, x, y);
}
}
另一个想法是您通常以这种方式使用工厂(根据您的需要,鞋面也可以很好):
private interface ShapeFactory{
public Shape create(float x, float y, float width, float height, bool isCircle);
}
private class MyShapeFactory implements ShapeFactory{
public Shape create(float x, float y, float width, float height, bool isCircle){
if (isCircle)
return new Circle(Math.min(width, height), x, y);
else
return new Rectangle(width, height, x, y);
}
}
所以工厂不一定和构造函数有相同的参数。很多人都有这种印象,因为我猜他们试图自动化工厂并且只传递一个类列表而没有任何关于如何实例化它们的信息。自动化 DI 容器也会犯同样的错误。
这里真正重要的是,上层代码是否想知道它返回的是哪种 Shape 实现。但在某些情况下,您可能拥有或重构为某种通用描述符。例如,您不一定有Shape.scale(width, height)
方法,如果有,您将无法调整圆形或矩形的大小,因为就像构造函数一样,那里的缩放比例是不同的。但是如果你想要的只是调用类似的东西Shape.draw(canvas)
,那么我想你很高兴。
同时我发现了一个类似的问题,有类似的答案,也许你也可以从中学习:https ://softwareengineering.stackexchange.com/a/389507/65755