>我从这个链接中获取了工厂模式示例:http://howtodoinjava.com/2012/10/23/implementing-factory-design-pattern-in-java/
但是,当我将代码复制到我自己的 IDE 中时,我收到一条警告,指出我的构造函数中有一个可重写的方法调用。我明白这意味着什么,我只是认为工厂模式应该解决这个问题吗?教程有缺陷吗?我应该做一些不同的事情吗?
我只包括了一种汽车类型,只是为了节省我粘贴的代码量:
Car
类 :
package FactoryPattern;
public abstract class Car {
public Car(CarType model){
this.model = model;
arrangeParts();
}
private void arrangeParts(){
//Do one time processing herer
}
//Do subclass level processing in this method
protected abstract void construct();
private CarType model = null;
public CarType getModel(){
return model;
}
public void setModel (CarType model){
this.model = model;
}
}
CarFactory
类 :
package FactoryPattern;
public class CarFactory {
public static Car buildCar(CarType model){
Car car = null;
switch (model) {
case SMALL:
car = new SmallCar();
break;
case SEDAN:
car = new SedanCar();
break;
case LUXURY:
car = new LuxuryCar();
break;
default:
//throw an exception
break;
}
return car;
}
}
FactoryPattern
类 :
package FactoryPattern;
public enum CarType {
SMALL, SEDAN, LUXURY
}
package FactoryPattern;
public class LuxuryCar extends Car {
LuxuryCar(){
super(CarType.LUXURY);
construct();
}
@Override
protected void construct(){
System.out.println("Building Luxury Car");
}
}
CarFactoryTest
类 :
package FactoryPattern;
public class CarFactoryTest {
public static void main(String[] args) {
CarFactory.buildCar(CarType.SMALL);
CarFactory.buildCar(CarType.SEDAN);
CarFactory.buildCar(CarType.LUXURY);
}
}
警告来自这里
LuxuryCar(){
super(CarType.LUXURY);
construct();
}
construct()
方法是protected
的,因此可以在 LuxuryCar
的子类中重写。如果一个不知情的开发人员重写了该方法并尝试使用父类中尚未初始化的字段,那么很多事情都可能会出错。这就是 IDE 向您发出警告的原因。
例如
public class LuxuryCar extends Car {
protected Televesion tv;
LuxuryCar(){
super(CarType.LUXURY);
construct(); // will call the overriden method in the sub class
}
@Override
protected void construct(){
tv = new Television();
}
}
public class BetterLuxuryCar extends LuxuryCar {
BetterLuxuryCar(){
super();
}
@Override
protected void construct(){
tv.upgrade(); // oops NullPointerException
}
}
请注意,像 construct()
这样的方法似乎属于工厂本身。此外,Car
类不需要CarType
字段,子类型已经知道它是什么类型。