标签 设计模式 下的文章

面向对象的软件开发中,有一个基本原则,那就是单一原则,是设计模式的重点。单一原则,功能单一的类,避免万能类。如果一个类的空能多于一点,就应该拆分成2个类。是面向对象的设计模式中最重要的一个原则。
举个例子,在智能手机刚刚出现的时候,诺基亚占据世界大半壁江山。智能手机可以打电话,发短信,浏览网页,玩游戏,拍照,录像等等,但是,拿拍照来说,拍照比不过傻瓜相机(如今也比不过单反)。尽管将大量的功能融合为一台设备,携带和充电更方便,但是效果并不如单一功能的强大。这就引入了“单一原则”。
在软件开发过程中,单一原则是设计模式中非常重要的思想。如果,你能够在一个类中找到多于一个的功能,那么,这个类就该进行抽象和拆分了。在OOP中有一个大忌讳,就是万能类。一个成千上万行的类,臃肿而庞大,为什么不柴分成多个类呢?每个类负责一个功能,各思其职。

策略模式,策略就是算法和变化,策略模式就是对算法和变化的封装。是条件选择从客户端到服务端的转移。客户端与算法类的彻底隔离。

<?php
abstract class Strategy{
    public $paramA = '';
    public $paramB = '';
    public function getResult(){

    }
}
class AlgorithmA extends Strategy{
    public function algorithmA(){
        //算法A的实现
    }
}
class AlgorithmB extends Strategy{
    public function algorithmB(){
        //算法B的实现
    }
}
class AlgorithmC extends Strategy{
    public function algorithmC(){
        //算法C的实现
    }
}
?>

场景: 沃尔玛要做一个收银软件。有打8折,打5折等,有每满100减20等。

<?php
//抽象类
abstract class Pay{
    public $cash = '';
    public $total = '';
    public function getResult(){
        return $this->total;
    }
}
//打折
class Discount extends Pay{
    public function algorithm($cash, $discount=0.8){
        $this->total = $cash * $discount;
        return $this->getResult();
    }
}
//满多少减多少
class Reduce extends Pay{
    public function algorithm($cash, $satisfied=100, $returnCash=20){
        $this->total = $cash - floor($cash / $satisfied) * $returnCash;
        return $this->getResult();
    }
}
class Context{
    private $obj;
    public function __construct($type){
        switch($type){
            case 1:
                $this->obj = new Discount();
                break;
            case 2:
                $this->obj = new Reduce();
                break;
        }
    }
    public function algorithm(){
        $this->obj->algorithm();
    }
}
//客户端
$obj = new Context($_GET['type']);
echo $obj->algorithm();
?>

优点:客户端不需要做条件判断,而且仅仅需要认识一个类即可。乍一看和简单工厂很相似呢。

昨晚开始看设计模式,我决定没看一种,就把它记录下来。一是晚上看,早上到公司,边写边回味。二是决定每看一章就写一篇博客,可以监督自己不会看着看着半途而废。
这应该就是一个系列博客了,书目录总共28种设计模式。这本书是我去赶集面试时推荐给我的,推荐了2本,一本大话设计模式,一本大话数据结构。想来想去,明白了一点,语言只是工具,真正的核心在于算法,设计模式,数据结构。本系列将已PHP为代码实现
设计模式是对OOP的思维体操,本篇是设计模式之简单工厂模式。
场景:实现PHP连接Mysql。

<?php
$conn = mysql_connect('localhost', 'root', '');
mysql_select_db('blog', $conn);
?>

就这个?搞笑呢?项目里难道也用面向过程的?

<?php
class MysqlDb{
    private $conn = '';
    public function connect($host, $username, $password){
        if(empty($conn)){
            $this->conn = mysql_connect($host, $username, $password);
        }
    }

    public function selectDb($dbName){
        mysql_select_db($dbName, $this->conn);
    }
}
?>

现在,请给我加一个查询方法

<?php
class MysqlDb{
    private $conn = '';
    public function connect($host, $username, $password){
        if(empty($conn)){
            $this->conn = mysql_connect($host, $username, $password);
        }
    }

    public function selectDb($dbName){
        mysql_select_db($dbName, $this->conn);
    }

    public function query($sql){
        return mysql_query($sql);
    }
 
    public function selectOne($id){
        $sql = "SELECT * FROM `tableName` WHERE `id` = '".$id."' LIMIT 0, 1";
        return $this->query($sql);
    }

    public function selectList($id = ''){
        if(!empty($id)){
             $where = "WHERE `id` = '".$id."'";
        }
        $sql = "SELECT * FROM `tableName`".$where;
        return $this->query($sql);
    }
}
?>

好,现在项目发展了,单单Mysql不能满足需求了,请给我添加一个Redis。

<?php
class RedisDb{
    private $conn = '';
    public function connect($host, $username, $password){
        if(empty($conn)){
            $this->conn = new Redis();
            $this->conn->connect($host, $port);
            $this->conn->auth($password);
            $this->conn->select($dbName);
        }
    }
 
    public function getValue($key){
        return $this->conn->get($key);
    }

    public function setValue($key, $value){
        return $this->conn->set($key, $value);
    }
}
?>

好了,难道每次都要在代码里调用这2个类?当然不!

<?php
/**
 * 数据库工厂类 - 这就是简单工厂模式的分发。调用上面的几个类
 */
class DbFactory{
    private static $dbObj = '';
    public static function init($dbType){
        if(empty(self::$dbObj)){
            self::$dbObj = self::dbSwitch($dbType);
        }
        return $dbObj;
    }
  
    private static function dbSwitch($dbType){
        $dbType = strtolower($dbType);
        $obj = '';
        switch($dbType){
            case 'mysql':
                $obj = new MysqlDb();
                break;
            case 'redis':
                $obj = new RedisDb();
                break;
            case 'mysqli':
                $obj = new MysqliDb();
                break;
            case 'pdo':
                $obj = new PdoDb();
                break;
             default :
                exit('非法操作');
        }
        return $obj;
    }
}
?>