如何在工厂方法中初始化具有多个参数构造函数的类

假设我有一个计算形状面积的 Shape 接口。我添加了 2 个实现矩形和正方形。我看到的挑战是两种实现都有自己的多参数构造函数。如何使用工厂模式初始化它们。我想用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);

}

}



哆啦的时光机
浏览 109回答 1
1回答

潇潇雨雨

您的解决方案不是最佳的,因为:1)您必须为具体的构造函数创建专用的构造函数Shape,并且您失去了参数的类型检查(在编译时)。2)init具体工厂的方法容易出错。这就是我要做的。具体工厂应该携带具体构造函数的参数Shape,但不能作为不确定的字符串(如果从用户输入获取字符串,请在创建具体工厂之前转换它们):public interface ShapeFactory {&nbsp; &nbsp; public Shape make(String shapeType);}public class ShapeFactoryImpl implements ShapeFactory {&nbsp; &nbsp; private int circleRadius;&nbsp; &nbsp; private int rectangleLength;&nbsp; &nbsp; private int rectangleBreadth;&nbsp; &nbsp; public ShapeFactoryImpl(int circleRadius, int rectangleLength, int rectangleBreadth){&nbsp; &nbsp; &nbsp; &nbsp; this.circleRadius = circleRadius;&nbsp; &nbsp; &nbsp; &nbsp; this.rectangleLength = rectangleLength;&nbsp; &nbsp; &nbsp; &nbsp; this.rectangleBreadth = rectangleBreadth;&nbsp; &nbsp; }&nbsp; &nbsp; public Shape make(String shapeType) {&nbsp; &nbsp; &nbsp; &nbsp; switch (shapeType) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case "Circle": return new Circle(this.circleRadius);&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case "Rectangle": return new Rectangle(this.rectangleLength, this.rectangleBreadth);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; default: throw new Exception("...");&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}客户不需要知道ShapeFactory他正在使用的混凝土,也不必担心Shape他得到的混凝土。依赖关系是相反的:发挥关键作用的是抽象,而不是细节。但如果可能的形状数量增加,您将得到一个具有许多相似参数的构造函数。这是另一个解决方案:public class ShapeFactoryImpl implements ShapeFactory {&nbsp; &nbsp; private Shape circle;&nbsp; &nbsp; private Shape rectangle;&nbsp; &nbsp; public ShapeFactoryImpl(Circle circle, Rectangle rectangle){&nbsp; &nbsp; &nbsp; &nbsp; this.circle = circle;&nbsp; &nbsp; &nbsp; &nbsp; this.rectangle = rectangle;&nbsp; &nbsp; }&nbsp; &nbsp; public Shape make(String shapeType) {&nbsp; &nbsp; &nbsp; &nbsp; switch (shapeType) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case "Circle": return this.circle.clone();&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case "Rectangle": return this.rectangle.clone();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; default: throw new Exception("...");&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}这更好,因为您不会混合参数:每种混凝土都Shape包含自己的参数。如果你想让它更灵活,你可以使用 Map 将交换机的责任移出具体工厂:public class ShapeFactoryImpl implements ShapeFactory {&nbsp; &nbsp; private Map<String, Shape> shapeByType;&nbsp; &nbsp; public ShapeFactoryImpl(Map<String, Shape> shapeByType){&nbsp; &nbsp; &nbsp; &nbsp; this.shapeByType = shapeByType;&nbsp; &nbsp; }&nbsp; &nbsp; public Shape make(String shapeType) {&nbsp; &nbsp; &nbsp; &nbsp; Shape shape = this.shapeByType.get(Type).clone();&nbsp; &nbsp; &nbsp; &nbsp; if (shape == null) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; throw new Exception("...");&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; return shape;&nbsp; &nbsp; }}我什至会使用 anenum来代替形状类型而不是字符串,并使用 anEnumMap来处理开关:public class ShapeFactoryImpl implements ShapeFactory {&nbsp; &nbsp; private EnumMap<ShapeType, Shape> shapeByType;&nbsp; &nbsp; public ShapeFactoryImpl(Map<ShapeType, Shape> shapeByType){&nbsp; &nbsp; &nbsp; &nbsp; this.shapeByType = shapeByType;&nbsp; &nbsp; }&nbsp; &nbsp; public Shape make(ShapeType shapeType) {&nbsp; &nbsp; &nbsp; &nbsp; return this.shapeByType.get(Type).clone();&nbsp; &nbsp; }}客户端必须知道Shape接口ShapeFactory和ShapeType枚举。“服务器”提供具体ShapeFactoryImpl实例。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java