| 创建型模式主要是为了解决创建对象的时候的问题而存在的。 创建型设计模式有两个主导思想:一是将系统使用的具体类封装起来,二是隐藏这些具体类的实例创建和结合方式。 创建型模式主要分为以下五种: 简单工厂模式(Simple Factory)和工厂方法模式(Factory method)抽象工厂模式(Abstract factory)单例模式(Singleton)建造者模式(Builder)原型模式(Prototype)
 单例模式单例模式的重点是,对象有且仅有一次实例化。组成部分主要是:
 私有化成员变量,存储实例化的对象私有化构造方法,防止外部创建私有化克隆方法,防止对象复制公有的静态方法,对外界提供实例
 上代码噻~ <?php
class Test{
    
    private static $instance = NULL;
    
    private function __construct(){}
    
    private function __clone(){}
    
    public static function getInstance(){
        if (!isset(self::$instance)) {
            self::$instance = new self();
        }
        return self::$instance;
    }
}
 案例:数据库连接
 简单工厂模式工厂模式:父类中提供一个创建对象的接口,用来允许子类决定实例化的类型 简单工厂模式:有抽象类,实现类,工厂类,把创建类这部分放在工厂类里面 <?php
    
    abstract class Math{
        abstract function getValue($x, $y){}
    }
    
    
    class Add extends Math
     {
        public function getValue($x, $y) {
            return $x + $y;
        }
    }
    
    class Sub extends Math{
        public function getValue($x, $y) {
            return $x - $y;
        }
    }
    
    
    class MyMath{
        static function getClass($type) {
            switch ($type) {
                case "+":
                    return new Add();
                case "-":
                	return new Sub();
            }
        }
    }
    
    
    $myMath = MyMath::getClass("+");
    return $myMath->getValue(2, 3);
    
 好处是调用简单, 创建对象和实例化分开,但是新增功能的时候需要修改工厂类,但是对其他部分代码不影响,定位问题也会更快。 工厂方法模式封装类中不变的部分,提取善变的部分为独立类,通过依赖注入的方式达到解耦,复用和方便后期维护 抽象工厂-------工艺的流程和顺序具体工厂-------隐藏背后产品的细节抽象产品-------产品生产工艺具体产品-------具体产品怎么生产,可以有个性化设置,只要工序按照抽象标准生产即可
 <?php
    
    abstract class Math{
        abstract function getValue($x, $y){}
    }
    
    
    class Add extends Math
     {
        public function getValue($x, $y) {
            return $x + $y;
        }
    }
    
    
    class Sub extends Math{
        public function getValue($x, $y) {
            return $x - $y;
        }
    }
    
    
    abstract class iFactory{
        abstract function getObj(){}
    }
    
    
    class FactoryAdd extends iFactory{
        static function getObj(){
            return new Add();
        }
    }
    
    class FactorySub extends iFactory{
        static function getObj(){
            return new Sub();
        }
    }
    
    $client = FactoryAdd::getObj();
    return $client->getValue(2, 3);
    
    
 应用例子:支付的话,支付宝支付,银行支付,微信支付。可以看作是一个典型的例子。另一个例子就是PHP链接数据库的时候,不管是mysql还是sqlserver都抽象成同样的链接方式,查询方式,忽略底层不同的实现方式。
 抽象工厂模式产品类:
<?php
interface AutoProduct
{
    public function dirve();
}
class AudiA4Product implements AutoProduct
{
    
    public function dirve()
    {
        echo "开奥迪A4"."<br>";
    }
}
class BenzC200Product implements AutoProduct
{
    
    public function dirve()
    {
        echo "开奔驰C200"."<br>";
    }
}
interface AirCondition
{
    public function blow();
}
class GreeAirCondition implements AirCondition
{
    public function blow()
    {
        echo "吹格力空调某型号"."<br>";
    }
}
class HaierAirCondition implements AirCondition
{
    public function blow()
    {
        echo "吹海尔空调某型号"."<br>";
    }
}
工厂类:
interface Factory
{
    public function getAuto();
    public function getAirCondition();
}
class AFactory implements Factory
{
    
    public function getAuto()
    {
        return new AudiA4Product();
    }
    
    public function getAirCondition()
    {
        return new HaierAirCondition();
    }
}
class BFactory implements Factory
{
    
    public function getAuto()
    {
        return new BenzC200Product();
    }
    
    public function getAirCondition()
    {
        return new GreeAirCondition();
    }
}
$factoryA = new AFactory();
$factoryB = new BFactory();
$auto_carA = $factoryA->getAuto();
$auto_airA = $factoryA->getAirCondition();
$auto_carB = $factoryB->getAuto();
$auto_airB = $factoryB->getAirCondition();
$auto_carA->dirve();
$auto_airA->blow(); 
$auto_carB->dirve();
$auto_airB->blow(); 
?>
 对比工厂方法模式:
 一个抽象产品类,可以派生出多个具体产品类。
 一个抽象工厂类,可以派生出多个具体工厂类。
 每个具体工厂类只能创建一个具体产品类的实例。
 抽象工厂模式:多个抽象产品类,每个抽象产品类可以派生出多个具体产品类。
 一个抽象工厂类,可以派生出多个具体工厂类。
 每个具体工厂类可以创建多个具体产品类的实例。
 简单工厂 :用来生产同一等级结构中的任意产品。(对于增加新的产品,无能为力)工厂方法 :用来生产同一等级结构中的固定产品。(支持增加任意产品)
 抽象工厂 :用来生产不同产品族的全部产品。(对于增加新的产品,无能为力;支持增加产品族)
 建造者模式定义了处理其他对象的复杂构建的对象设计将一个复杂对象的建造和调用者分离。调用者只需要给出指定对象的类型和那天。
 建造者模式负责按照顺序创建复杂的对象/
 组成部分:
 建造请求(Builder):定义一个抽象接口,规范产品各个组成成分的建造,包括建造方法和返回结果的方法具体建造者(Concrete Builder):实现builder定义的方法,建造结束之后返回一个产品实例
 指挥者角色(Director):调用具体的建造者角色建造那个产品,
 产品角色(Product):在指挥者的指导下由具体建造者建造的那个复杂的对象
 优点:
 易于解耦,建造者模式可以很好的将一个对象的实现和相关业务逻辑分离,将产品本身和创建过程分类,可以使用相同的过程来创建不同的产品。
 易于精确的控制对象,将负责对象的创建划分在不同的方法中,过程更加清晰
 易于扩展,增加新的建造者无需修改原来的类库
 缺点:
 建造者模式的产品有较多的共同点,组成部分类似,如果产品之间差异较大则不适合,如果产品的内部变化复杂,需要定义更多的具体建造者来配合,导致系统变得庞大
 建造者接口修改会导致所有执行类的修改
 使用场景:
 需要生成的产品对象有复杂的内部结构,属性相互依赖,建造者模式可以强迫生成顺序
 在对象创建过程中会使用到系统的一些其他对象,这些对象在产品创建过程中不易得到
 <?php
    
    abstract class Builder{
        
        public abstract function buildWheel(){}
        
        
        public abstract function buildChair(){}
        
       
       public abstract function buildEngine(){}
       
       
       public abstract function getCar(){}
    }
    
    
    class Director{
        public function assemble(Builder $builder) {
            $builder->buildChair();
            $builder->buildWheel();
            $builder->buildEngine();
        }
    }
    
    
    class Car{
        private $buildList = [];
        
        public function add($part) {
            $this->buildList[] = $part;
        }
        
        
        public function show() {
            foreach ($this->buildList as $key => $builder) {
                echo '组件' . $builder . '安装好了</br>';
            }
            print_r('组装完毕');
        }
    }
    
    
    class ConcreteBuilder extends Builder{
        private $car;
        
        public function __construct() {
            $this->car = new Car();
        }
        
        public function buildChair() {
            $this->car->add('装椅子');
        }
        
        public function buildWheel() {
            $this->car->add('装轮子');
        }
        
         public function buildEngine() {
            $this->car->add('装引擎');
        }
        
        public function getCar()
        {
            return $this->car;
        }
    }
    
    
     class ConcreteBuilder2 extends Builder{
        private $car;
        
        public function __construct() {
            $this->car = new Car();
        }
        
        public function buildChair() {
            $this->car->add('装好椅子');
        }
        
        public function buildWheel() {
            $this->car->add('装好轮子');
        }
        
         public function buildEngine() {
            $this->car->add('装好引擎');
        }
        
        public function getCar()
        {
            return $this->car;
        }
    }
    
    
    
    $director = new Director();
    
   
   $builder = new ConcretrBuilder();
   $director->assemble($builder);
   $car = $builder->getCar();
   
   
   $builder2 = new ConcretrBuilder2();
   $director->assemble($builder2);
   $car2 = $builder2->getCar();
 原型模式通过创建一个原型对象,然后复制原型对象来避免通过标准的方式(这里说的是new)创建大量的对象产生的开销。 代码: <?php
abstract class CloneMe
{
    public $name;
    public $picture;
    
    abstract function __clone();
}
class Person extends CloneMe
{
    public function __construct()
    {
        $this->picture = 'CloneMan.png';
        $this->name = 'Origin';
        
        public function display()
        {
            echo "<img src = $this->picture>";
            echo "<br/> $this->name<p/>";
        }
        
        function __clone(){
            
        }
    }
}
$worker = new Person();
$worker->display();
$slacker = clone $worker;
$slacker->name = "Cloned";
$slacker->display();
 有一个小的tips就是,克隆的时候并不会执行构造函数。 原型模式的优缺点优点:
 可以在运行时刻增加和删除产品
 可以改变结构以指定新对象
 可以改变值以指定新对象
 减少子类的构造
 用类动态配置应用
 缺点:
 每个类必须配一个克隆方法。
 也就是说,当实例化的类是在运行时刻才知道的时候,比较适合原型模式。
 |