Java AbstractFactory中声明静态方法的缺点
根据Head-First设计模式,在工厂类中声明静态方法的缺点是——“您不能子类化和更改getPizza方法的行为”。工厂类使用getPizza方法来决定返回哪种类型的对象。如果我理解正确,我的班级是Java AbstractFactory中声明静态方法的缺点,java,design-patterns,factory-pattern,Java,Design Patterns,Factory Pattern,根据Head-First设计模式,在工厂类中声明静态方法的缺点是——“您不能子类化和更改getPizza方法的行为”。工厂类使用getPizza方法来决定返回哪种类型的对象。如果我理解正确,我的班级是 public class PizzaFactory { public static Pizza getPizza(String type) { if (type.equals("cheese")) return new
public class PizzaFactory {
public static Pizza getPizza(String type) {
if (type.equals("cheese"))
return new CheesePizza();
else if (type.equalsIgnoreCase("thisCrust"))
return new ThinCrustPizza();
return null;
}
}
即使这个方法是静态的,我也可以创建一个子类,比如-
public class DelhiPizzaFactory extends PizzaFactory {
public static Pizza getPizza(String type) {
if (type.equals("cheese"))
return new CheesePizza();
else if (type.equalsIgnoreCase("thisCrust"))
return new ThinCrustPizza();
return null;
}
}
我可以交替使用超类和子类
public class PizzaStore {
Pizza pizza;
public void orderPizza(String type) {
pizza = DelhiPizzaFactory.getPizza(type);
pizza.prepare();
pizza.bake();
}
}
那么缺点是什么呢?既然要防止重写,就需要将方法设置为final,例如:
公共类比萨饼工厂{
公共静态最终Pizza getPizza(字符串类型){
[...]
}
通过这种方式,您可以防止重写,如果这是您在本例中想要的,尽管在其他情况下,是的,通过不使其成为
final
来允许重写也会很有用。因为您想要防止重写,所以您需要使您的方法成为final
,例如:
公共类比萨饼工厂{
公共静态最终Pizza getPizza(字符串类型){
[...]
}
通过这种方式,您可以防止覆盖,如果这是您在本例中想要的,尽管在其他情况下,是的,通过不使其成为
final
来允许覆盖也很有用。这是一个用例问题。
考虑情况,您使用的API有以下几种全局API的方法。
public void setPizzaFactory(PizzaFactory factory) {
this.pizzaFactory=factory;
// set pizza factory and
}
通常,您可以将两个工厂作为参数传递给该方法,但如果我们的API将使用您刚才设置的PizzaFactory,并调用其getPizza()
方法,它将始终使用getPizza()
方法在PizzaClass
中声明,尽管您可能已将其他派生类作为工厂对象传递
如果您的工厂中有非静态方法,那么您可以这样做
api.setPizzaFactory(新的DoubleCheesePizzaFactory)
whereDoubleCheesePizzaFactory
覆盖getPizza
方法,始终在每个比萨饼中添加额外的奶酪。这样,内部“烘焙”api将使用来自DoubleCheesePizzaFactory的getCheese
方法版本,而不是PizzaFactory.getPizza
版本(又名super.getPizza
)
因此,缺点就是这样:您不能(通过重写)更改
super
类中方法的行为。这是一个用例问题。
考虑情况,您使用的API有以下几种全局API的方法。
public void setPizzaFactory(PizzaFactory factory) {
this.pizzaFactory=factory;
// set pizza factory and
}
通常,您可以将两个工厂作为参数传递给该方法,但如果我们的API将使用您刚才设置的PizzaFactory,并调用其getPizza()
方法,它将始终使用getPizza()
方法在PizzaClass
中声明,尽管您可能已将其他派生类作为工厂对象传递
如果您的工厂中有非静态方法,那么您可以这样做
api.setPizzaFactory(新的DoubleCheesePizzaFactory)
whereDoubleCheesePizzaFactory
覆盖getPizza
方法,始终在每个比萨饼中添加额外的奶酪。这样,内部“烘焙”api将使用来自DoubleCheesePizzaFactory的getCheese
方法版本,而不是PizzaFactory.getPizza
版本(又名super.getPizza
)
因此,不利因素就是这样:您无法改变行为(通过重写)
super
类中的方法。停止重写也必须是final
停止重写也必须是final
停止重写我在eclipse中尝试了这一点,这正是您所说的!如果我不想重写getPizza方法,那么我应该声明它为final。如果我只使用静态,子类将不知道ir新的实现是否会被采用。现在有意义了。谢谢!很高兴我能提供帮助。因此,一般来说,没有必要将方法声明为static final,因为不需要这样做-它们不会像非static方法一样被重写。仅供参考-使用“重写”时您将观察到的相同行为私有字段。我在eclipse中尝试过这一点,这正是您所说的!如果我不想覆盖getPizza方法,那么我应该将其声明为final。如果我只使用static,子类将不知道它们的新实现是否会被接受。这现在是有意义的。谢谢!很高兴我能提供帮助。所以总体而言,decla没有什么意义re方法静态最终,因为没有这种需要-它们不会像非静态方法一样被重写。仅供参考-使用“重写”私有字段时您将观察到的相同行为。