在 AbstractFactory 中声明静态方法的缺点
Demerit of declaring static method in AbstractFactory
根据 Head First 设计模式 - "you can't subclass and change the behavior of getPizza method",在工厂中声明静态方法的缺点 class。 Factory class 使用 getPizza 方法来决定要 return 的对象类型。如果我没理解错的话,我的 class 是
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;
}
}
尽管该方法是静态的,但我始终可以创建一个子class,例如 -
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;
}
}
我可以交替使用 superclass 和 subclass。
public class PizzaStore {
Pizza pizza;
public void orderPizza(String type) {
pizza = DelhiPizzaFactory.getPizza(type);
pizza.prepare();
pizza.bake();
}
}
那么缺点是什么?
因为你想防止覆盖,你需要使你的方法 final
,即。像这样:
public class PizzaFactory {
public static <b>final</b> Pizza getPizza(String type) {
[...]
}</pre>
这样,您可以防止覆盖,如果这是您在这种情况下想要的,虽然在其他情况下,是的,通过不进行覆盖来允许覆盖 final
也很有用。
这是用例问题。
考虑一下情况,您使用的 API 具有以下某些全局方法 API.
public void setPizzaFactory(PizzaFactory factory) {
this.pizzaFactory=factory;
// set pizza factory and
}
通常,您可以将两个工厂作为参数传递给该方法,但如果我们的 API 将使用您刚刚设置的 PizzaFactory,并调用它的 getPizza()
方法,它将始终使用 PizzaClass
中声明的 getPizza()
方法,尽管事实上您可能已经传递了一些其他派生的 class 作为工厂对象。
如果你的工厂中有非静态方法,那么你可以做类似的事情
api.setPizzaFactory(new DoubleCheesePizzaFactory)
其中 DoubleCheesePizzaFactory
覆盖 getPizza
方法以始终向每个比萨添加额外的奶酪。这样,内部 "baking" api 将使用 DoubleCheesePizzaFactory
的 getCheese
方法版本代替 PizzaFactory.getPizza
版本(又名 super.getPizza
)
所以缺点就是这样:您不能更改 super
class.
中方法的行为(通过覆盖)
根据 Head First 设计模式 - "you can't subclass and change the behavior of getPizza method",在工厂中声明静态方法的缺点 class。 Factory class 使用 getPizza 方法来决定要 return 的对象类型。如果我没理解错的话,我的 class 是
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;
}
}
尽管该方法是静态的,但我始终可以创建一个子class,例如 -
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;
}
}
我可以交替使用 superclass 和 subclass。
public class PizzaStore {
Pizza pizza;
public void orderPizza(String type) {
pizza = DelhiPizzaFactory.getPizza(type);
pizza.prepare();
pizza.bake();
}
}
那么缺点是什么?
因为你想防止覆盖,你需要使你的方法 final
,即。像这样:
public class PizzaFactory { public static <b>final</b> Pizza getPizza(String type) { [...] }</pre>
这样,您可以防止覆盖,如果这是您在这种情况下想要的,虽然在其他情况下,是的,通过不进行覆盖来允许覆盖
final
也很有用。
这是用例问题。 考虑一下情况,您使用的 API 具有以下某些全局方法 API.
public void setPizzaFactory(PizzaFactory factory) {
this.pizzaFactory=factory;
// set pizza factory and
}
通常,您可以将两个工厂作为参数传递给该方法,但如果我们的 API 将使用您刚刚设置的 PizzaFactory,并调用它的 getPizza()
方法,它将始终使用 PizzaClass
中声明的 getPizza()
方法,尽管事实上您可能已经传递了一些其他派生的 class 作为工厂对象。
如果你的工厂中有非静态方法,那么你可以做类似的事情
api.setPizzaFactory(new DoubleCheesePizzaFactory)
其中 DoubleCheesePizzaFactory
覆盖 getPizza
方法以始终向每个比萨添加额外的奶酪。这样,内部 "baking" api 将使用 DoubleCheesePizzaFactory
的 getCheese
方法版本代替 PizzaFactory.getPizza
版本(又名 super.getPizza
)
所以缺点就是这样:您不能更改 super
class.