好好爱自己!

php 设计模式系列(一)

参考文章:http://duchengjiu.iteye.com/blog/2227452

多态代码

// 多态, 在JAVA中是这样用的, 其实在PHP当中可以自然消除, 因为参数是动态的, 你传什么过来都可以, 不限制类型, 直接调用类的方法 

// 多态, 在JAVA中是这样用的, 其实在PHP当中可以自然消除, 因为参数是动态的, 你传什么过来都可以, 不限制类型, 直接调用类的方法
abstract class Tiger {
    public abstract function climb();
}

class XTiger extends Tiger {
    public function  climb() {
        echo '摔下来';
    }
}

class MTiger extends Tiger {
    public function climb() {
        echo '爬到树顶';
    }
}

class Client {
    public static function call(Tiger $animal) {
        $animal->climb();
    }
}

Client::call(new XTiger());
Client::call(new MTiger());

  

面向接口开发代码

// 面向对象里面有一个面向接口开发, 就是一个共同的规格, 你生产插座, 我生产插头

// 共同接口
interface db {
    function conn();
}

// 服务端开发(不知道将会被谁调用)
class dbmysql implements db{
    public function conn() {
        echo '连上了MySQL';
    }
}

class dbsqlite implements db{
    public function conn() {
        echo '连上了sqlite';
    }
}

// 客户端, 看不到dbmysql, dbsqlite的内部细节的, 只知道上两个类实现了db接口.

$db = new dbmysql();
$db->conn();          // 因为知道这个类实现了db接口, 所以知道有这个conn类

$sqlite = new dbsqlite();
$sqlite->conn();

// 我连我有哪些类我都不希望告诉客户端, 那么怎么进一步进行封装
// 发生连接的双方知道的越少越好, 你还知道我有两个类

  简单工厂模式代码 

// 简单工厂

// 面向对象里面有一个面向接口开发, 就是一个共同的规格, 你生产插座, 我生产插头

// 共同接口
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();
        } elseif ($type=='sqlite') {
            return new dbsqlite();
        } else {
            throw new Exception("Error db type", 1);
        }
    }
}

// 客户端现在不知道对方到底有哪些类名了
// 只知道对方开放了一个Factory::createDB方法
// 方法允许传递数据库名称

$mysql = Factory::createDB('mysql');
$mysql->conn();

$sqlite = Factory::createDB('sqlite');
$sqlite->conn();

// 原本你知道服务器端的两个类名, 觉得你知道的太多, 再封装起来, 只给一个通道, 更好的适应变化
// 如果以后新增oracle类型, 怎么办?
// 我们PHP随手改了就行, 像JAVA打包一次很麻烦, 又要修改服务端内容
// 服务端要修改Factory的内容(在java, c++中, 改后还得再编译)
// 这个时候就想如何来改进呢
// 在OOD(面向对象设计)的法则中, 有重要的开闭原则--对于修改是封闭的, 对于扩展是开放的.
// 你可以新增一个源代码, 不要修改旧的代码

//现在用第二种办法, 叫工厂方法

  工厂方法代码

// 共同接口
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 mysqliFactory 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 '连接上了oracle';
    }
}

class oracleFactory implements Factory {
    public function createDB() {
        return new dboracle();
    }
}


// 客户端开始, 对方给了两个api, 一个db的api, 一个是创造数据库的api
$fact = new mysqliFactory();
$db = $fact->createDB();
$db->conn();

$fact = new sqliteFactory();
$db = $fact->createDB();
$db->conn();

  单例设计模式代码

// 单例
// 一般来说一个中小型网站一个db去连接数据库就行了
// 想想, 能不能只有一个db类, 一个upload类, 一个cookie类
// 类肯定只有一个, 如何保证类的实例也只有一个

// 2个对象是同一个的时候才全等

// 单例模式

class single {
    protected static $ins = null;

    // 控制权限, 封锁new操作, 把大门关上了, 需要留一个小窗户
    // 方法前加final, 则方法不能被覆盖, 类前加final, 则类不能被继承
    final protected function __construct() {}
    // 防clone
    final protected function __clone(){}
    
    //留一个接口来new对象
    public static function getIns() {
        if(self::$ins == null) {
            self::$ins = new self();
        }
        return self::$ins;
    }
}

$s1 = single::getIns();
$s2 = single::getIns();

if ($s1 === $s2) {
    echo '是一个对象';
} else {
    echo '不是一个对象';
}

  

posted @ 2016-08-20 17:24  立志做一个好的程序员  阅读(261)  评论(0编辑  收藏  举报

不断学习创作,与自己快乐相处