可以说我有一个Shape界面,可以计算形状的面积。我添加2个实现Rectangle和Square。我看到的挑战是两个实现都有自己的多个参数构造函数。如何使用工厂模式初始化它们。我想使用Java解决它。
public class Rectangle implements Shape {
int length;
int breadth;
public Rectangle(List<String> parameters) {
this.length = Integer.parseInt(parameters.get(0));
this.breadth = Integer.parseInt(parameters.get(1));
}
@Override
public int area() {
return length * breadth;
}
}
public class Square implements Shape {
int edge;
public Square(List<String> parameters) {
this.edge = Integer.parseInt(parameters.get(0));
}
@Override
public int area() {
return edge * edge;
}
}
public interface Shape {
int area();
}
public interface ShapeFactory {
public Shape make(String shapeType);
public List<String> getParameters(String shapeType);
}
public class ShapeFactoryImpl implements ShapeFactory {
Map<String, List<String>> shapeInitMap = new HashMap<>();
public void init(){
shapeInitMap.put("Circle", Arrays.asList(new String[]{"4"}));
shapeInitMap.put("Rectangle", Arrays.asList(new String[]{"2","3"}));
}
@Override
public Shape make(String shapeType) {
switch (shapeType) {
case "Circle":
return new Square(getParameters(shapeType));
case "Square":
return new Rectangle(getParameters(shapeType));
default:
break;
}
return null;
}
@Override
public List<String> getParameters(String shapeType) {
return shapeInitMap.get(shapeType);
}
}
您的解决方案不是最佳的,因为:1)您必须为具体的Shape
s 创建专用的构造函数,并且您将在编译时松开参数的类型检查。2)init
混凝土工厂的方法容易出错。
这就是我要做的。具体工厂应携带具体Shape
s构造函数的参数,但不能包含不确定的字符串(如果从用户输入中获取字符串,请在创建具体工厂之前对其进行转换):
public interface ShapeFactory {
public Shape make(String shapeType);
}
public class ShapeFactoryImpl implements ShapeFactory {
private int circleRadius;
private int rectangleLength;
private int rectangleBreadth;
public ShapeFactoryImpl(int circleRadius, int rectangleLength, int rectangleBreadth){
this.circleRadius = circleRadius;
this.rectangleLength = rectangleLength;
this.rectangleBreadth = rectangleBreadth;
}
public Shape make(String shapeType) {
switch (shapeType) {
case "Circle": return new Circle(this.circleRadius);
case "Rectangle": return new Rectangle(this.rectangleLength, this.rectangleBreadth);
default: throw new Exception("...");
}
}
}
客户不需要知道ShapeFactory
他正在使用的混凝土,也不必担心Shape
他得到的混凝土。依赖性是相反的:关键是抽象而不是细节。但是,如果可能的形状数量增加,您将获得带有许多相似参数的构造函数。这是另一个解决方案:
public class ShapeFactoryImpl implements ShapeFactory {
private Shape circle;
private Shape rectangle;
public ShapeFactoryImpl(Circle circle, Rectangle rectangle){
this.circle = circle;
this.rectangle = rectangle;
}
public Shape make(String shapeType) {
switch (shapeType) {
case "Circle": return this.circle.clone();
case "Rectangle": return this.rectangle.clone();
default: throw new Exception("...");
}
}
}
这样比较好,因为您不会混合参数:每个混凝土都Shape
包含自己的参数。如果要使其更加灵活,可以使用地图将开关的职责移出具体工厂:
public class ShapeFactoryImpl implements ShapeFactory {
private Map<String, Shape> shapeByType;
public ShapeFactoryImpl(Map<String, Shape> shapeByType){
this.shapeByType = shapeByType;
}
public Shape make(String shapeType) {
Shape shape = this.shapeByType.get(Type).clone();
if (shape == null) {
throw new Exception("...");
}
return shape;
}
}
我什至可以使用enum
for形状类型而不是字符串,并使用a EnumMap
来处理开关:
public class ShapeFactoryImpl implements ShapeFactory {
private EnumMap<ShapeType, Shape> shapeByType;
public ShapeFactoryImpl(Map<ShapeType, Shape> shapeByType){
this.shapeByType = shapeByType;
}
public Shape make(ShapeType shapeType) {
return this.shapeByType.get(Type).clone();
}
}
客户端必须知道Shape
and ShapeFactory
接口和ShapeType
枚举。“服务器”提供了具体ShapeFactoryImpl
实例。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句