0
点赞
收藏
分享

微信扫一扫

编程中的设计模式之原型模式

介绍

原型模式用来创建重复的对象,减少对象创建初始化的性能开销,属于创建型模式。

处理文件实例

模拟一个需求,文件类要处理 Word 和 Excel 两种文件类型,先定义了一个文件抽象类,再由具体的 Word 类和 Excel 类去实现,抽象类中定义了 clone 方法,会在具体的子类实现时初始化文件类型属性type,由产品类将这两个文件类封装在属性中,在根据业务需求调用不同对象的同时执行 clone 操作,复制新对象。

<?php
abstract class FilePrototype
{
    public $type;

    public function read()
    {
        echo "read $this->type file";
    }

    public function write()
    {
        echo "write $this->type file";
    }

    abstract public function getType();
    abstract public function setType($type);

    public function __clone()
    {
        $this->type = '';
    }
}

class WordFile extends FilePrototype
{
    public function __construct()
    {
        $this->type = 'word';
    }

    public function getType()
    {
        return $this->type;
    }

    public function setType($type)
    {
        $this->type = $type;
    }
}

class ExcelFile extends FilePrototype
{
    public function __construct()
    {
        $this->type = 'word';
    }

    public function getType()
    {
        return $this->type;
    }

    public function setType($type)
    {
        $this->type = $type;
    }
}

class ProductPrototype
{
    public $map = [];

    /**
     * @param $id string 对象名称
     */
    public function getMap($id)
    {
        if($this->map){
            return clone $this->map[$id];
        }

        return false;
    }

    /**
     * 对象存储入数组
     * @param $objectName string 目标对象
     */
    public function setMap($objectName)
    {
        if($objectName){
            $this->map[$objectName] = new $objectName;
        }

        return false;
    }

    public function coll()
    {
        $this->setMap('WordFile');
        $this->setMap('ExcelFile');
    }
}

$productPrototype = new ProductPrototype();
$productPrototype->coll();

$wordFile = $productPrototype->getMap('WordFile');
$wordFile->setType('text');  #对象复制后,可对属性进行重新赋值,改变对象
$wordFile->read();  #read text file
$wordFile->write(); #write text file

$excelFile = $productPrototype->getMap('ExcelFile');
$excelFile ->setType('xlsx');  #对象复制后,可对属性进行重新赋值,改变对象
$excelFile->read();  #read xlsx file
$excelFile->write();  #write xlsx file
总结

原型模式是创建对象的一种模式,对象的创建过程,在实际的工作中往往是复杂的,一个构造函数会同时去做权限的判断,属性的赋值,配置文件的读取,是个消耗资源很多的过程,而内存的复制往往是快速高效的,并且在一个生命周期中一个对象往往会多次用到,仅仅只是修改了个别属性,却要去重新创建对象,这样是划不来的,通过原型模式获取克隆后的对象后,像例子中的修改type属性,就可以改变输出。但原型模式在创建克隆对象时往往要考虑类的整体功能,对新建立的类不会麻烦,对于过去存在的类,改动是比较困难的。

举报

相关推荐

0 条评论