在 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 将使用 DoubleCheesePizzaFactorygetCheese 方法版本代替 PizzaFactory.getPizza 版本(又名 super.getPizza

所以缺点就是这样:您不能更改 super class.

中方法的行为(通过覆盖)