首页 PHP 正文
193

设计模式之工厂方法模式

工厂方法模式是将具体产品的实例化推迟到子类中去实现。它由以下几部分组成:
1、抽象工厂接口,用来派生具体工厂类,它对外提供了统一的获取产品的方法名。
2、具体工厂类,继承/派生自抽象工厂接口,由具体工厂类实现具体产品的创建。
3、抽象产品接口,用来派生具体的产品,它规范了所有产品的统一类型,保证客户端得到的产品超类型的一致。
4、具体产品类,继承/派生自抽象产品接口。特别要注意的是,这些具体产品仍属于同一个产品树,举个例子:如果鞋子是抽象产品类的话,那么皮鞋、运行鞋就是具体的产品。
/**
*抽象工厂方法接口
*/
interface FactoryMethod{
    
    /**
    *统一生成产品的方法
    */
    public function createProduct();
}

/**
*生产产品A的具体工厂方法A
*/
class ConcreteFactoryA implements FactoryMethod{
    
    /**
    *实现接口
    */
    public function createProduct(){
        return new ConcreteProductA();
    }
}

/**
*生产产品B的具体工厂方法B
*/
class ConcreteFactoryB implements FactoryMethod{
    
    /**
    *实现接口
    */
    public function createProduct(){
        return new ConcreteProductB();
    }
}

/**
*抽象产品接口
*/
interface Product{
    
    public function show();
}

/**
*产品A
*/
class ConcreteProductA implements Product{
    
    /**
    *实现接口方法
    */
    public function show(){
        echo 'This is product A<br>';
    }
}

/**
*产品B
*/
class ConcreteProductB implements Product{
    
    /**
    *实现接口方法
    */
    public function show(){
        echo 'This is product B<br>';
    }
}

//A工厂负责生产A产品
$concreteFactoryA = new ConcreteFactoryA();
$product = $concreteFactoryA->createProduct();
$product->show();

//B工厂负责生产B产品
$concreteFactoryB = new ConcreteFactoryB();
$product = $concreteFactoryB->createProduct();
$product->show();
简单工厂模式违背了对修改关闭的原则,当需要增加新的产品,必须去修改简单工厂类的内部代码(增加条件判断),从而要重新编绎这个类。
工厂方法模式有效地克服了简单工厂的缺点,当要增加新的产品时,只需要增加一个对应的具体工厂类就好了(对扩展开放原则)。但是缺点也是很明显的,每增加一个产品就得对应增加一个工厂类,如果产品种类多的话,那么工厂类的数量也相应增多。

《Head First Pattern》中披萨店生产披萨的示例:
abstract class PizzaStore{
    public function orderPizza(){  
        $pizza = $this->createPizza();//将稳定的部分封装在抽象类里面
        $pizza->prepare();
        $pizza->bake();
        $pizza->cut();
        $pizza->box();
        return $pizza;
    }
    
    abstract public function createPizza(); //实例化产品类推迟到子类去实现。
}

class NYPizzaStore extends PizzaStore{
    public function createPizza(){
        return new NYPizza();
    }
}

class WDCPizzaStore extends PizzaStore{
    public function createPizza(){
        return new WDCPizza();
    }
}

abstract class Pizza{
    abstract public function prepare();
    abstract public function bake();
    abstract public function cut();
    abstract public function box();
}

class NYPizza extends Pizza{
    public function prepare(){
        echo 'NYPizza is preparing<br>';
    }
    public function bake(){
        echo 'NYPizza is baking<br>';
    }
    public function cut(){
        echo 'NYPizza is cutting<br>';
    }
    public function box(){
        echo 'NYPizza is boxing<br>';
    }
}

class WDCPizza extends Pizza{
    public function prepare(){
        echo 'WDCPizza is preparing<br>';
    }
    public function bake(){
        echo 'WDCPizza is baking<br>';
    }
    public function cut(){
        echo 'WDCPizza is cutting<br>';
    }
    public function box(){
        echo 'WDCPizza is boxing<br>';
    }
}
$pizzaStore = new NYPizzaStore();
$pizza = $pizzaStore->orderPizza();
$pizzaStore = new WDCPizzaStore();
$pizza = $pizzaStore->orderPizza();

正在加载评论...