• 设计模式(PHP)


    设计模式是对典型问题的典型解决方案,是一种套路。比如说前端如何写选项卡,如何在网页弹窗,都是有固定套路的,前辈们都总结出来了,我们学会就好。

    开发中所谓的“面向接口开发”,涉及到“调用”的概念。服务器端和客户端由不同的人员开发,但是不必要互相认识,开发的时候只需要对接口负责,就能够共同合作完成任务。生产插座的厂商和电器厂商并不是互相了解,但是只各自遵循插座插头规范,就能够做出可用的产品。

    简单工厂

    <?php
    
    //客户端和服务器端共同的接口
    interface db{
        function conn();
    }
    
    //服务端开发,不知道将会被谁调用
    class dbmysql implements db{
        public function conn(){
            echo '连接上了Mysql';
        }
    }
    
    class dbsqlite implements db{
        public function conn(){
            echo '连接上了sqlite';
        }
    }
    //简单工厂
    class Factory{
        public static function createDB($type){
            if ($type=='mysql') {
                return new dbmysql();
            }
            else if($type == 'sqlite'){
                return new dbsqlite();
            }
            else{
                throw new Exception('错误的数据库类型');
            }
        }
    }
    
    //客户端,不知道服务端到底有哪些类,只知道对方开放了一个Factory::createDB方法,并且方法允许传递数据库名称
    $mysql = Factory::createDB('mysql');
    $mysql->conn();
    
    $sqlite = Factory::createDB('sqlite');
    $sqlite->conn();

    从上面的代码中可以看出来,如果服务端要新增一个oracle类型,根据开闭原则(对于修改是封闭的,对于扩展是开放的),在不修改服务端源代码的情况下,是不容易做到的。

    工厂方法:

    <?php
    
    //客户端和服务器端共同的接口
    interface db{
        function conn();
    }
    
    interface Factory{
        function createDB();
    }
    
    //服务端开发,不知道将会被谁调用
    class dbmysql implements db{
        public function conn(){
            echo '连接上了Mysql';
        }
    }
    
    class dbsqlite implements db{
        public function conn(){
            echo '连接上了sqlite';
        }
    }
    
    class mysqlFactory implements Factory{
        public function createDB(){
            return new dbmysql();
        }
    }    
    class sqliteFactory implements Factory{
        public function createDB(){
            return new dbsqlite();
        }
    }
    
    //服务端添加oracle类
    class dboracle implements db{
        public function conn(){
            echo '连接上了orecle';
        }
    }
    
    class oracleFactory implements Factory{
        public function createDB(){
            return new dboracle();
        }
    }
    
    //客户端开始
    
    $fact = new mysqlFactory();
    $db = $fact->createDB();
    $db->conn();
    
    $fact = new sqliteFactory();
    $db = $fact->createDB();
    $db->conn();
    
    $fact = new oracleFactory();
    $db = $fact->createDB();
    $db->conn();

     单例模式。当我们需要数据库对象,cookie对象或者upload对象的时候,通常需要用到单例模式。

     实现思路:封闭外部的new操作,内部可以new,如果有,就直接返回,没有就new出来。最后再防止外部覆盖或者克隆。

    <?php
    
    class single{
        protected static $ins = null;
        public static function getIns(){
            if (self::$ins === null) {
                self::$ins = new self();
            }
            return self::$ins;
        }
        final protected function __construct(){
    
        }
        final protected function __clone(){
    
        }
    }

    观察者模式

    用javascript实现观察者模式

    <!doctype html>
    <html lang="en">
    <head>
    <meta charset="utf-8">
    <title>用观察者模式切换页面风格</title>
    <style>
    div{
        float: left;
        width: 200px;
        height: 200px;
        margin: 10px;
        border: 1px solid black;
    }
    </style>
    <script>
    window.onload = function(){
        //服务端
        var oSwitch = document.getElementById('switch');
        oSwitch.observers = {};
        oSwitch.attach = function(key,obj){
            this.observers[key] = obj;
        };
        oSwitch.detach = function(key){
            delete this.observers[key];
        };
        oSwitch.onchange = oSwitch.modify = function(){
            //这里还是很关键的
            for(var key in this.observers){
                this.observers[key].update(this);
            }
        };
        //客户端
        var oColor = document.getElementById('color');
        var oAd = document.getElementById('ad');
        oColor.update = function(observe){
            if (observe.value == 'male') {
                this.style.background = 'gray';
            }
            else if(observe.value == 'female'){
                this.style.background = 'pink';
            }
        }
        oAd.update = function(observe){
            if (observe.value == 'male') {
                this.innerHTML = '汽车';
            }
            else if(observe.value == 'female'){
                this.innerHTML = '化妆品';
            }
        }
    
        //观察select的变化
        oSwitch.attach('color',oColor);
        oSwitch.attach('ad',oAd);
    
        //如果要扩展hobby
        var oHobby = document.getElementById('hobby');
        oHobby.update = function(observe){
            if (observe.value == 'male') {
                this.innerHTML = '爱好是打篮球';
            }
            else if(observe.value == 'female'){
                this.innerHTML = '爱好是逛街';
            }
        }
    
        //观察爱好
        document.getElementById('confirm').onclick = function(){
            oSwitch.attach('hobby',oHobby);
        };
        document.getElementById('cancel').onclick = function(){
            oSwitch.attach('hobby');
        };
    };
    </script>
    </head>
    <body>
        <select name="" id="switch">
            <option value="male">男士风格</option>
            <option value="female">女士风格</option>
        </select>
        <input type="button" value="观察爱好" id="confirm">
        <input type="button" value="取消观察爱好" id="cancel">
        <div id="color">我是颜色</div>
        <div id="ad">我是广告</div>
        <div id="hobby">我是爱好</div>
    </body>
    </html>

    用php实现观察者模式

    <?php
    
    //PHP5中提供了观察者observer与被观察者subject的接口
    class user implements SplSubject{
        public $times;
        public $hobby;
    
        protected $observers = null;
        public function __construct($hobby){
            $this->times = rand(1,10);
            $this->hobby = $hobby;
            $this->observers = new SplObjectStorage();
        }
        public function login(){
            //操作session
            $this->notify();
        }
        public function attach(SPLObserver $observer){
            $this->observers->attach($observer);
        }
        public function detach(SPLObserver $observer){
            $this->observers->detach($observer);
        }
        public function notify(){
            $this->observers->rewind();
            while ($this->observers->valid()) {
                $observer = $this->observers->current();
                $observer->update($this);
                $this->observers->next();
            }
        }
    }
    
    
    class security implements SPLObserver{
        public function update(SplSubject $subject){
            if ($subject->times < 3) {
                echo '这是第'.$subject->times.'次安全登陆'.'<br/>';
            }
            else{
                echo '这是第'.$subject->times.'次登陆,异常'.'<br/>';
            }
        }
    }
    
    class ad implements SPLObserver{
        public function update(SplSubject $subject){
            if ($subject->hobby == 'sports') {
                echo '台球世锦赛';
            }
            else{
                echo '好好学习';
            }
        }
    }
    
    
    //实施观察
    $user = new user('sports');
    $user->attach(new security());
    $user->attach(new ad());
    
    $user->login();
    ?>

    职责链模式

  • 相关阅读:
    C复制字符串
    C语言分解数组
    perlCGI编程之测试环境
    linux下c语言 读取文件
    C++的组合(Composite)模式
    C#GDI+绘制多行文本和格式化文本
    shell中引号的应用
    perlCGI编程之Apache服务器安装配置
    求二叉树的深度
    perlCGI编程之页面参数传递
  • 原文地址:https://www.cnblogs.com/zhaojianbin/p/6060969.html
Copyright © 2020-2023  润新知