策略模式(strategy)

<?php
/**
 * Created by PhpStorm.
 * User: zhangheg
 * Date: 2018/5/6
 * Time: 10:05
 * 设计模式
 */
/**
 * 设计模式的根本意图是适应需求的变化
 * 增加功能不修改原来的代码
 *   基本原则
 * 单一职责:
 * 开放封闭
 * 策略模式(strategy)
 * thinkphp 多种数据库策略模式,记录日志缓存策咯模式 uml图()
 * http://design-patterns.readthedocs.io/zh_CN/latest/read_uml.html
 */


interface FileExporter
{
    /**
     * 写文件
     */
    public function writeFile($fileName,$data);

}


class XmlFile implements FileExporter
{

    public function writeFile($fileName,$data)
    {
        $xml=$this->arrayToXml($data);
        file_put_contents($fileName.'.xml', $xml);
    }

    private function arrayToXml($arr)
    {
        $xml = '<xml version="1.0" standalone="yes">';
        foreach ($arr as $item) {
            $xml .= "\n <item>";
            foreach($item as $key => $val){
                $xml .="\n    <$key>$val</$key>";
            }
            $xml .="\n </item>";
        }
        $xml .= "\n</xml>";
        return $xml;
    }
}

class CvsFile implements FileExporter
{
    public function writeFile($fileName,$data)
    {

        $fh=fopen($fileName.'.csv', 'w');
        foreach ($data as $key => $value) {
            fputcsv($fh, $value);
        }
        fclose($fh);
    }
}

class JsonFile implements FileExporter{
    public function writeFile($fileName, $data)
    {
        // TODO: Implement writeFile() method.
        if(is_array($data)){
            $data = json_encode($data);
        }else{
            file_put_contents('log.txt','数据格式只支持数组');
        }
        file_put_contents($fileName.".json",$data);
    }
}



class MyTool{

    private $fileName;
    private $exporter;

    public function __construct($fileName='default'){
        $this->fileName=$fileName;
    }

    public function setFileExporter(FileExporter $exporter){
        $this->exporter=$exporter;
    }

    public function export($data){
        $this->exporter->writeFile($this->fileName,$data);
        echo "done!";
    }


}


$data = [
    ['date'=>'2011-04-21','wu'=>'test'],
    ['date'=>'2014-04-21','wu'=>'good'],
    ['date'=>'2011-12-22','wu'=>'great'],
    ['date'=>'2012-05-21','wu'=>'hahah'],
    ['date'=>'2013-08-13','wu'=>'test'],
    ['date'=>'2011-04-25','wu'=>'yes'],
    ['date'=>'2014-04-14','wu'=>'no'],
];

$tool=new MyTool();
//$tool->setFileExporter( new XmlFile() );
//$tool->export($data);
//
//$tool->setFileExporter( new CvsFile() );
//$tool->export($data);
$tool->setFileExporter(new JsonFile());
$tool->export($data);

模板模式

/**
 * Created by PhpStorm.
 * User: zhangheg
 * Date: 2018/5/6
 * Time: 15:07
 * 组合优于继承
 * 模板模式
 * 适用场景
 * 适用场景及优势:

1、完成某一细节层次一致的一个过程或一系列步骤,但其个别步骤在更详细的层次上的实现可能不同时。我们通常考虑用模板模式来处理。

2、当不变的和可变的行为在方法的子类实现中混合在一起的时候,不变的行为就会在子类中重复出现,我们通过模板模式把这些行为搬移到单一的地方,这样就帮助子类摆脱重复的不变行为的纠缠。

3、模板模式通过把不变的行为搬移到超级抽象类,去除子类中的重复代码来体现它的优势。模板模式提供了一个很好的代码复用平台。
 *
 * 如果我们要封装的算法适合于提供给用户任意使用,是"一整个算法",那么用Strategy模式较好;

*如果要封装的变化是一个算法中的部分(换言之,大算法的步骤是固定的),而且我们不希望用户直接使用这些方法,那么应该使用Template Method模式.
 */

//抽象模板角色:抽象模板类,定义了具体的算法流程和一些留给子类必须实现的抽象方法

abstract class MakePhone{
    protected $name;
    public function __construct($name)
    {
        $this->name = $name;
    }
    final public function MakeFlow(){
        $this->MakeBattery();
        $this->MakeCamera();
        $this->MakeScreen();
        echo $this->name."手机生产完毕!".PHP_EOL;
    }

    public abstract function MakeBattery();
    public abstract function MakeCamera();
    public abstract function MakeScreen();
}


//具体子类角色:实现MakePhone中的抽象方法,子类可以有自己独特的实现形式,但是执行流程受MakePhone控制


class XiaoMi extends MakePhone{
    public function __construct($name)
    {
        parent::__construct($name);
    }

    public function MakeBattery()
    {
        // TODO: Implement MakeBattery() method.
        echo "小米电池生产完毕".PHP_EOL;
    }

    public function MakeCamera()
    {
        // TODO: Implement MakeCamera() method.
        echo "小米相机生产完毕".PHP_EOL;
    }

    public function MakeScreen()
    {
        // TODO: Implement MakeScreen() method.
        echo "小米屏幕生成完毕".PHP_EOL;
    }
}

class MeiZhu extends MakePhone{
    public function __construct($name)
    {
        parent::__construct($name);
    }

    public function MakeBattery()
    {
        // TODO: Implement MakeBattery() method.
        echo "魅族电池生产完毕".PHP_EOL;
    }

    public function MakeCamera()
    {
        // TODO: Implement MakeCamera() method.
        echo "魅族相机生产完毕".PHP_EOL;
    }

    public function MakeScreen()
    {
        // TODO: Implement MakeScreen() method.
        echo "魅族屏幕生成完毕".PHP_EOL;
    }
}

$mi = new XiaoMi();
$mi->MakeFlow();

$meizhu = new MeiZhu();
$meizhu->MakeFlow();