创建模式-工厂模式

普通工厂模式

首先我们创建继承于animal的猫狗类,使用普通工厂模式,通过制定传入值的不同,确定调用那种具体实现类。

<?php
//抽象类
abstract class animal{
    public abstract function eat();
}
//具体实现类
class cat extends animal{
    public function eat()
    {
        echo 'cat eats fish<br>';
    }
}
class dog extends animal{
    public function eat(){
        echo 'dog eats meat';
    }
}

读取输入值如果是cat调用cat的eat方法,dog则调用dog的eat方法,其他返回空。

<?php
require_once 'animal.php';
class factory{
    public function eat($type){
        switch($type){
            case 'cat':
                $cat = new cat();
                return $cat->eat();
            case 'dog':
                $dog = new dog();
                return $dog->eat();
            default:
                return null;
        }
    }
}
//测试
$factory = new factory();
$factory->eat('dog');

这种方法直观易懂,但依赖于输入值,当程序简单时,并没有什么问题。假设我的程序很复杂,包含很多实现类名称,如果每次调用都要将类名称一字不差的输入,难度较大。这时可以将调用方法放到工厂类中,通过实例化工厂的方式调用相应的方法。

工厂方法

与普通工厂通过传入值不同的方法进行实例化的方式不同,工厂方法将不同类的实例化写成相应的方法,通过实例化工厂调用不同工厂方法的方式,调用不同的类。

<?php
require_once 'animal.php';
class factory{
    //猫的工厂方法
    public function catFactory(){
        $cat = new cat();
        return $cat->eat();
    }  
    //狗的工厂方法
    public function dogFactory(){
        $dog = new dog();
        return $dog->eat();
    } 
}
//测试
$factory = new factory();
$factory->dogFactory();

每次调用都需要实例化工厂方法有点复杂,我们可以把工厂类中的方法改为static,无需实现即可调用。
#静态工厂方法
将工厂方法中的方法改为static,调用时不实例化工厂,直接调用。

class factory{
    public static function catFactory(){
        $cat = new cat();
        return $cat->eat();
    }  
    public static function dogFactory(){
        $dog = new dog();
        return $dog->eat();
    } 
}
//测试
factory::catFactory();

我们避免了因为拼写错误而调用错误的类,但是,如果需求更改,要求增加一个duck类呢,于是我们创建继承animal的duck类

class duck extends animal{
	public function eat(){
		echo 'duck eats beans';
	}
}

接着我们在工厂方法类中增加duck的实现方法

<?php
require_once 'animal.php';
class factory{
    .......
    //duck 工厂方法
    public static function duckFactory(){
        $duck = new duck();
        return $duck->eat();
    }
}

如果我们要添加chicken,penguin,pig,bear,bird等等的类呢?每次都需要修改factory工厂,这似乎违反了开闭原则。

开闭原则:对于扩展是开放的,对于修改是关闭的,这意味着模块的行为是可以扩展的。当应用的需求改变时,我们可以对模块进行扩展,使其具有满足那些改变的新行为。

抽象工厂

提供一个创建一系列或相互依赖对象的接口,而无需指定它们具体的类。

<?php
require_once 'animal.php';
//抽象工厂
abstract class abstractfactory{
    abstract function eat($type);
}
//具体工厂实现
class catFactory extends abstractfactory{
    public function eat(){
        $cat = new cat();
        return $cat->eat();
    }
}
class dogFactory extends abstractfactory{
    public function eat(){
        $dog = new dog();
        return $dog->eat();
    }
}
//测试
$factory = new dogFactory();
$factory->eat();

一般每个工厂实现类只需要一个实例,在这个例子中,catFactory和dogFactory都只需要一个实例,因此最好将这种类实现为一个单例类Singleton。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值