Head First Design Patterns 阅读笔记之四: Factory Pattern

new 的问题

每当你使用 new 实例化一个具体的类时,那这就是一种实现而不是接口,而具体的实现会导致代码脆弱并且不灵活。
从技术上说,new 没有问题。问题在于需求不断变化,而这些变化又会影响 new 的使用。所以该如何解决问题呢?


以 Pizza 店为例

假设你有一家 pizza 店,你有很多种 pizza,可能就会写下这样的代码:

Pizza orderPizza(String type) 
{ 
    Pizza pizza;

    if (type.equals(“cheese”)) pizza = new CheesePizza();
    else if (type.equals(“greek”) pizza = new GreekPizza();
    else if (type.equals(“pepperoni”) pizza = new PepperoniPizza();

    pizza.prepare(); 
    pizza.bake(); 
    pizza.cut(); 
    pizza.box(); 
    return pizza;
}

每当新加一种 pizza 时,都需要改变上面的 if 块,这对于维护人员来说太痛苦了!
这时需要利用一个设计原则:

identify the aspects that vary and seperate them from what stays the same.

于是我们把中间那段创建很多不同对象的代码移除,放到一个新的对象中去,这个对象一般叫做工厂(Factory),工厂专门解决对象创建的细节。现在可以画出这样一个图:
Pizza Store

现在假设你已经打败了其他竞争者,全国都开有分店,但是不同的地方需要不同的口味。有一种方法来解决这样的问题:把前面提到的工厂删掉,然后根据地方创建工厂,比如:CaliforniaPizzaFactory, ChicagoPizzaFactory, NYPizzaFactory。最后把 PizzaStore 和最合适的工厂结合在一起,就万事大吉了。就像这样:
按地区创建工厂

但是,这么做,你就完全控制不了这些当地工厂的生产行为。那究竟应该如何在保持灵活性的同时,可以控制行为呢?


pizza 店的一个框架

现在把 createPizza() 方法放回 PizzaStore 类中,但这次是一个抽象方法,然后再根据地区创建子类。

public abstract class PizzaStore 
{
    public Pizza orderPizza(String type) 
    { 
        Pizza pizza;

        pizza = createPizza(type);

        pizza.prepare(); 
        pizza.bake(); 
        pizza.cut(); 
        pizza.box();
        return pizza;
    } 
    abstract Pizza createPizza(String type);
}

现在创建 NYPizzaStore

// 纽约地区 pizza
public class NYPizzaStore extends PizzaStore 
{
    Pizza createPizza(String item) 
    {
        if (item.equals("cheese")) return new NYStyleCheesePizza();
        else if (item.equals("veggie")) return new NYStyleVeggiePizza();
        else if (item.equals("clam")) return new NYStyleClamPizza();
        else if (item.equals("pepperoni")) return new NYStylePepperoniPizza();
        else return null;
    }
}

之后类似的创建 ChicagePizzaStore 和 CaliforniaPizzaStore。

最后完整的代码参见 Factory Pattern—Github


最后看看工厂模式

All factory patterns encapsulate object creation. The Factory Method Pattern encapsulates object creation by letting subclasses decide what objects to create.

直观的图形表示:
Factory Pattern

现在下一个正式定义:

The Factory Method Pattern defines an interface for creating an object, but lets subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.

上面的定义说 Factory Method 让子类决定实例化哪个类,这里的决定并不是指子类在 runtime 决定,而是指 creator 类并不知道创建了哪些真正的 product ,product 的创建完全是由使用的子类的选择所决定。

As in the official definition, you’ll often hear developers say that the Factory Method lets subclasses decide which class to instantiate. They say decides not because the pattern allows subclasses themselves to decide at runtime, but because the creator class is written without knowledge of the actual products that will be created, which is decided purely by the choice of the subclass that is used.

这里提出一个新的设计原则 Dependency Inversion Principle:

Depend upon abstractions. Do not depend upon concrete classes.

这一原则看上去和

Program to an interface, not an implementation.

很像。但是他的要求更强,这条原则建议高层次组件和低层次组件都依赖于抽象,而不是高层次依赖于低层次。工厂模式能够满足这一原则。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值