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

素食 :

可以说我有一个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);
}

}

jferard:

您的解决方案不是最佳的,因为:1)您必须为具体的Shapes 创建专用的构造函数,并且您将在编译时松开参数的类型检查。2)init混凝土工厂方法容易出错。

这就是我要做的。具体工厂应携带具体Shapes构造函数的参数,但不能包含不确定的字符串(如果从用户输入中获取字符串,请在创建具体工厂之前对其进行转换):

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;
    }
}

我什至可以使用enumfor形状类型而不是字符串,并使用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();
    }
}

客户端必须知道Shapeand ShapeFactory接口和ShapeType枚举。“服务器”提供了具体ShapeFactoryImpl实例。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

当类构造函数具有参数时,如何在Java中初始化数组?

Kotlin中具有延迟初始化和通用工厂方法的类型推断

如何初始化具有构造函数的动态类

使用带有类型参数的工厂方法,使用参数化的构造函数创建派生类

具有从工厂方法创建的私有构造函数的单元测试类

如何在Objective-C中调用具有多个参数的Swift初始化方法

如何在C ++中使用构造函数(只是构造函数)在类中初始化大型私有数组?

PHP是否具有减少类和构造函数中参数声明和初始化重复的功能?

强制子类具有特定的工厂方法或构造函数

如何在PHP中实例化具有参数化构造函数的.NET类?

如何在 Scala 中没有早期初始化程序的情况下为超类构造函数创建参数

在具有私有构造函数的类中初始化静态变量

如何在类构造函数中使用参数初始化std :: array的大小?

如何在派生类构造函数中初始化基类成员变量?

在派生类构造函数(或工厂)中初始化基类的模式

我们如何在构造函数方法中的 react typescript 中初始化状态,如果它具有特定的接口类型

如何在Objective C的参数化构造函数中初始化NSDate?

在没有构造函数的类中初始化变量

如何使可以使用Typescript中的对象或常规参数构造函数初始化的类?

如何在C ++ 11中初始化未初始化其构造函数中所有成员的类

如何在运行时使用构造函数初始化类中私有的数组?

C ++中的初始化程序列表和类初始化。我有无参数构造函数,但仍必须使用初始化列表?

如何在类的其他方法中使用在构造函数中初始化的对象

如何通过参数初始化构造函数中的数组?

如何在工厂方法中为Hashmap <String Boolean>创建构造函数?

Java-如何允许类的所有方法访问在构造函数中初始化的数组?

如何在类构造函数中初始化匿名结构?

如何在空类构造函数中初始化List <E>?

如何在类的构造函数中初始化对象的2D向量?(C ++)