这更像是一个风格问题,我不确定我的问题的解决方案是什么“最干净”。
实施细节并不重要,我想做的是:
我有一个抽象类,它由几个子类扩展,这些子类本质上非常相似。我想从客户端隐藏这些类,只能通过超类中的静态方法使它们可实例化,该方法返回对子类实例的超类引用(具体类由方法参数确定)。 到目前为止,我认为这是一件很常见的事情。
现在,我正在谈论的这些子类可以分为两组,一组,其成员需要两个参数才能构建,另一组,其成员需要一个额外的参数。
所以现在我的问题是:如何让客户端通过上面提到的静态方法获得这两种类型。我是否提供了两种带有不同参数列表的静态方法?我是否强制客户端在第一组不需要的第三个可选参数上传递零值?这有设计模式吗? (我已经考虑过Effective Java中的Builder模式,但据我所知,通常在不同的上下文中使用它)。或者我是否修改了继承层次结构?
任何答案都将不胜感激!
编辑:
我认为我的问题目前有点复杂,所有都添加了一些代码以使其更清晰:
abstract class SuperClass{
public static SuperClass getSuperClass(String type, int i1, int i2, int optional) {
/*
*'type' alone determines which concrete subclass is instanciated
*'optional' is only needed for the construction for some of those 'types'
*so the implementation of this method might look like this:
*/
switch(type) {
case "1":
return new Subclass1(i1, i2);
break;
case "2":
return new Subclass2(i1, i2, optional);
break;
/*
*So the problem is this: always passing 'optional' is weird if it
*is then simply discarded in some cases.
*Overloading is weird as well because I don't want to split up
*the switch statement or check for exceptions in every case
*(when optional is/is not declared for types where it
*shouldn't/should be)
*/
}
}
答案 0 :(得分:1)
您有两种选择:
选项1
超类中的static factory method
可以使用var-args实现:
public static SuperClass newInstace(int...parameters) {
SuperClass superClass = null;
if(parameters.length == 2) {
if(parameters[1]>=5) {//instantiate a subclass based on a value
super = new SubClass1(parameters[0],parameters[1]);
} else {
super = new SubClass2(parameters[0],parameters[1]);
}
} else if(parameters.length == 3) {
if(parameters[2]>=5) {
super = new SubClass3(parameters[0],parameters[1],parameters[2]);
} else {
super = new SubClass4(parameters[0],parameters[1],parameters[2]);
}
} else {
throw new IllegalArgumentException("Invalid number of parameters passed to newInstance. Expected number of parameters [min = 2, max = 3]")
}
return superClass;
}
选项2
或者,您可以重载newInstance
方法,并使用一个接受2个参数,另一个接受3个参数。
两种方法的优点和缺点如下所述:
答案 1 :(得分:0)
您可以传递配置字符串或配置对象(例如,属性),其中包含与实现需求一样多的详细信息。它可以是1或100个参数。但是,对于调用者来说,只传递了一个包装参数。
答案 2 :(得分:0)
这取决于。听起来你的超类静态方法返回一个SuperClass
实例。如果是这样,您可以根据附加参数返回不同的子类实例。
考虑一个抽象类Vehicle
。现在两个抽象类SingleDeckVehicle
和MultiDeckVehicle
扩展Vehicle
,让前两个参数为车轮数和座位数,附加参数为车辆甲板数。然后,甲板的数量将是重要的,如果他/她想要1
实例,您的客户确实会传递SingleDeckVehicle
作为第三个参数。
但是,您也可以创建另一个静态方法。假设您已定义静态方法Vehicle.getVehicle(int wheelNo, int seatNo, int deckNo)
。您还可以定义另一个:Vehicle.getSingleDeckVehicle(int wheelNo, int seatNo)
,返回Vehicle.getVehicle(wheelNo, seatNo, 1);
。
一个类似的例子是BorderFactory: http://docs.oracle.com/javase/7/docs/api/javax/swing/BorderFactory.html。我希望我能正确理解你的问题......