PHP面向对象编程的基本原则,以及三种基本设计模式

面向对象编程的基本原则

1.单一职责:一个类,只需要做好一件事情

2.开放封闭:一个类,应该是可扩展的,而不可修改的

3.依赖倒置:一个类,不应该强依赖另一个类。每个类对于另外一个类都是可替换的

4.配置化:尽可能地使用配置,而不是硬编码

5.面向接口编程:只需要关心接口,不需要关心实现

PSR-0命名规范

1. 命名空间必须与绝对路径一致

2. 类名首字母必须大写
3. 除入口文件外,其他“.php”必须只有一个类

开发符合PSR-0规范的基础框架

1. 全部使用明明空间
2. 所有PHP文件必须自动载入,不能有include/require
3. 单一入口

类的自动载入

Test1.php

<?php

class Test1{

    static function test(){

        echo __METHOD__;

    }

}

Test2.php

<?php

class Test2{

    static function test(){

        echo __METHOD__;

    }

}

test.php

<?php

spl_autoload_register('autoload1');

spl_autoload_register('autoload2');

function autoload1($class){

    require __DIR__.'/'.$class.'.php';
    
}

function autoload2($class){

    require __DIR__.'/'.$class.'.php';
    
}

Test1::test();

Test2::test();

 运行test.php会得到这样的结果:

Test1::testTest2::test

__autoload()函数只可以存在一个,如果重复定义会报致命错误,所以目前一般使用spl_autoload_regisiter()来实现类的自动加载。

PHP链式调用的实现

Database.php

<?php

class Database{

    function where($where){

        ...

    }

    function order($order){

        ...

    }

    function limit($limit){

        ...

    }

}

如果Database.php是这样,那么在index.php中就需要这样来写以实现sql查询:

index.php

<?php

$db=new Database();

$db->where("id=2");

$db->where("name=2");

$db->order("id desc");

$db->limit(10);

 要实现链式调用只需要这样做:

Database.php

<?php

class Database{

    function where($where){

        return $this;

    }

    function order($order){

        return $this;

    }

    function limit($limit){

        return $this;

    }

}

在每个方法的末尾加上'return $this;',然后就可以:

Data

<?php

$db->where("id=1")->where("name=2")->order("id desc")->limit(10);

三种基础的设计模式包括工厂模式、单例模式和注册器模式。

工厂模式

Factory.php

<?php
class Factory{
    static function createDatabase(){
        $db = new Database();
        return $db;
    }
}
$db = Factory::createDatabase();

工厂模式的作用在于不在类外实例化对象。

单例模式

Database.php

<?php
class Database{
    protected $db;
    // 第一步
    private function __construct(){
        // private可以屏蔽外部new这个类
    }
    // 第二步
    static function getInstance(){
        if(self::$db){
            return self::$db;
        }else{
            self::$db = new self();
            return self::$db;
        }
    }
}
$db = Database::getInstance();

单例模式用于数据库连接等只需要一个对象的场景,避免资源的浪费。

注册器模式

Register.php

<?php
class Register{
    protected static $objects;
    static function set($name, $object){
        self::objects[$name] = $object;
    }
    static function get($name){
        return self::objects[$name];
    }
    static function _unset($name){
        unset(self::objects[$name]);
    }
}
Register::set('db1',$db);
$db = Register::get('$db1');

适配器模式

1.适配器模式,可以将截然不同的函数接口封装成统一的API

2.实际应用举例,PHP的数据库操作有mysql,musqli,pdo三种,可以用适配器模式统一成一致。类似的场景还有cache适配器,将memcache,redis,file,apc等不同的缓存函数,统一成一致

Database.php

<?php
interdace IDatabase{
    function connect($host, $user, $passwd, $dbname);
    function query($sql);
    function close();
}

在Database.php中定义了数据库操作的接口,接下来将MySQL、MySQLi、PDO三种数据库操作适配为接口中定义的方法。

MySQL.php

<?php
namespace Database;
class MySQL implements IDatabase{
    protected $conn;
    function connect($host, $user, $passwd, $dbname){
        $conn = mysql_connect($host, $user, $passwd);
        mysql_select_db($dbname, $conn);
        this->conn = $conn;
    }
    function query($sql){
        $res = mysql_query($sql, $this->conn);
        return $res;
    }
    function close(){
        mysql_close($this->conn);
    }
}

MySQLi.php

<?php
namespace Database;
class MySQLi implements IDatabase{
    protected $conn;
    function connect($host, $user, $passwd, $dbname){
        $conn = mysqli_connect($host, $user, $passwd, $dbname);
        this->conn = $conn;
    }
    function query($sql){
        $res = mysqli_query($this->conn, $sql);
        return $res;
    }
    function close(){
        mysqli_close($this->conn);
    }

PDO.php

<?php
namespace Database;
class PDO implements IDatabase{
    protected $conn;
    function connect($host, $user, $passwd, $dbname){
        new \PDO("mysql:host=$host;dbname=$dbname", $user, $passwd);
        $this->conn = $conn;
    }
    function query($sql){
        return $this->conn->query($sql);
    }
    function close(){
        unset($this->conn);
    }

然后在应用中可以这样使用:

index.php

<?php
$db = new Database\MySQL();
$db->connect('localhost', 'root', 'root', 'test');
$db->query('show database');
$db->close();

或者实例化其他类型的数据库,只需要使用同一种标准。