PHP设计模式(三),工厂方法模式

工厂方法模式又称为工厂模式。它属于类创建型模式。它定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类。
工厂方法模式是简单工厂模式的进一步抽象和扩展。在工厂方法模式中,核心的工厂类不在负责所有产品的创建。而是将具体创建工作交给子类去做,这个核心类,仅仅负责给出具体工厂必须实现的接口,而不负责哪一个产品类被实例化,这使得工厂方法模式可以允许系统在不修改工厂角色的情况下引进新的产品。
先让我们看一下类图,了解一下工厂模式
PHP设计模式(三),工厂方法模式_第1张图片
正如第一段所说,常常听到其他开发人员说:工厂方法让子类决定要实例的类是哪一个。其实所谓的“决定”并不是指模式允许子类本身在运行时做决定,而是在编写创建者类时,不需要知道实际创建的产品是那一个个,选择了使用那个子类,就决定了 实际创建的产品的类型。让我们看一下代码:

abstract class Factory {
    public product = null;
    abstract public creator();
}

class MyFactory extends Factory {
    public function creator() {
        $this->product = new MyProduct();
    }
}

首先我们创建了一个抽象的Factory类,包含一个抽象的方法creator,这样Factory所有的子类就必须自己实现这个方法。然后我们定定义了一个MyFactory的类,用来返回MyProduct类型的对象。试想,如果除了MyProduct,我们还有其他同类MyProductB怎么办? 对,结合我们之前的简单工厂模式,我们来传入一个参数,根据参数来创建指定类型的对象:

class MyFactory extends Factory {
    public function creator($type) {
        switch($type) {
            case "A":
                $this->product = new MyProductA();
                break;
            cas "B":
                $this->product = new MyProductB();
                break;
            default :
                echo 'wrong type!'; 
        }
        $this->product = new MyProduct();
    }
}

简单的改造之后,我们就能通过MyProduct来创建更多的类型的对象,而这一切,父类Factory根本不知道! 当然这样我们还是不满足的。试想,如果把这个方法同样放到支付业务中,假设MyProduct对应银行A工厂,A银行拥有储蓄卡支付、信用卡支付、快捷支付等方式,我们可以根据传入不同的type,来分别对应不同的支付方式,但现在我们可能需要接入其他支付方式,怎么办?对,我们还需要其他“工厂”,比如YourFactory()。这部分代码有兴趣的话,自己补一下吧。
到现在,类图中的Factory部分就算说完了。但是还要注意一下左侧,也就是我们的产品部分(Product)。需要注意的是,Product类,应该也是抽象的,因为我们需要创建出来的产品同拥有一样的行为,这样我们在使用工厂创建对象之后,只需要调用一样的方法,就能实现一样的功能,比如发起某种请求,更新数据库等。如果不这么做,我们在使用product的时候,就需要根据不同的类型使用不同方式,偏离了设计的初衷。
简单写一下Product的代码:

abstract class Product {
    //这个方法需要子类自己实现
    abstract public function sendCode();

    //公共方法, 更新数据库
    public function function saveToDB() {
        $db->save();
    }
}

这样我们在实例化某种类型的Product之后,就可以直接调用某个行为了

$myProduct -> saveToDB();

大致写到这里,之后会补全类图。有不对的地方,欢迎大家批评指正。

你可能感兴趣的:(php)