成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

PHP面向?qū)ο笤O(shè)計(jì)的五大原則

adam1q84 / 1862人閱讀

摘要:面向?qū)ο笤O(shè)計(jì)的五大原則單一職責(zé)原則接口隔離原則開(kāi)放封閉原則替換原則依賴倒置原則。主要是針對(duì)繼承的設(shè)計(jì)原則,繼承與派生多態(tài)是的主要特性。

面向?qū)ο笤O(shè)計(jì)的五大原則:?jiǎn)我宦氊?zé)原則、接口隔離原則、開(kāi)放-封閉原則、替換原則、依賴倒置原則。這些原則主要是由Robert C.Martin在《敏捷軟件開(kāi)發(fā)——原則、方法、與實(shí)踐》一書中總結(jié)出來(lái),這五大原則也是23種設(shè)計(jì)模式的基礎(chǔ)。

單一職責(zé)原則 Single Pesponsibility Principle, SRP

在MVC框架中,對(duì)于表單插入數(shù)據(jù)庫(kù)字段過(guò)濾與安全檢查應(yīng)該是放在control層處理還是model層處理,這類問(wèn)題都可以歸到單一職責(zé)的范圍。

單一職責(zé)有兩個(gè)含義:

避免相同的職責(zé)分散到不同的類中

一個(gè)類承擔(dān)太多職責(zé)

遵守SRP的好處:

減少類之間的耦合

提高類的復(fù)用性

在實(shí)際代碼開(kāi)發(fā)中的應(yīng)用:工廠模式、命令模式、代理模式等。
工廠模式(Factory)允許在代碼執(zhí)行時(shí)實(shí)例化對(duì)象。之所以被稱為工廠模式是因?yàn)樗?fù)責(zé)“生產(chǎn)”對(duì)象。以數(shù)據(jù)庫(kù)為例,工廠需要的就是根據(jù)不同的參數(shù),生成不同的實(shí)例化對(duì)象。它只負(fù)責(zé)生產(chǎn)對(duì)象,而不負(fù)責(zé)對(duì)象的具體內(nèi)容。

定義一個(gè)適配器接口:


定義MySQL數(shù)據(jù)庫(kù)操作類:

_dbLink = @mysql_connect($config->host .
            (empty($config->port) ? "" : ":" . $config->port),
        $config->user, $config->password, true)) {
            if(@mysql_select_db($config->database, $this->_dbLink)){
                if($config->charset){
                    mysql_query("SET NAMES "{$config->charset}"", $this->_dbLink);
                }
                return $this->_dbLink;
            }
        }
        //數(shù)據(jù)庫(kù)異常
        throw new DbException(@mysql_error($this->_dbLink));
    }
    
    /**
    * 執(zhí)行數(shù)據(jù)庫(kù)查詢
    * @param string $query 數(shù)據(jù)庫(kù)查詢SQL字符串
    * @param mixed $handle 連接對(duì)象
    * @return resource
    */
    public function query($query, $handle)
    {
        if ($resource = @mysql_query($query, $handle)) {
            return $resource;
        }
    }
}
?>

SQLite數(shù)據(jù)庫(kù)操作類:

_dbLink = sqlite_open($config->file, 0666, $error)) {
            return $this->_dbLink;
        }
        
        throw new DbException($error);
    }
    
    /**
    * 執(zhí)行數(shù)據(jù)庫(kù)查詢
    * @param string $query 數(shù)據(jù)庫(kù)查詢SQL字符串
    * @param mixed $handle 連接對(duì)象
    * @return resource
    */
    public function query($query, $handle)
    {
        if ($resource = @sqlite_query($query, $handle)) {
            return $resource;
        }
    }
}
?>

定義一個(gè)工廠類,根據(jù)傳入不同的參數(shù)生成需要的類:

調(diào)用:

$db = sqlFactory::factory("MySQL");
$db = sqlFactory::factory("SQLite");

命令模式分離“命令的請(qǐng)求者”和“命令的實(shí)現(xiàn)者”方面的職責(zé)。


模擬服務(wù)員與廚師的過(guò)程:

cook = $cook;
    }
    
    public function execute(){
        $this->cook->meal();//把消息傳遞給廚師,讓廚師做飯
    }
}

class DrinkCommand implements Command
{
    private $cook;
    
    //綁定命令接受者
    public function __construct(cook $cook){
        $this->cook = $cook;
    }
    
    public function execute(){
        $this->cook->drink();
    }
}
?>

模擬顧客與服務(wù)員的過(guò)程:

mealCommand = $mealCommand;
        $this->drinkCommand = $drinkCommand;
    }
    
    public function callMeal(){
        $this->mealCommand->execute();
    }
    
    public function callDrink(){
        $this->drinkCommand->execute();
    }
}    
?>

實(shí)現(xiàn)命令模式:

$control = new cookControl;
$cook = new cook;
$mealCommand = new MealCommand($cook);
$drinkCommand = new DrinkCommand($cook);
$control->addCommand($mealCommand, $drinkCommand);
$control->callMeal();
$control->callDrink();

接口隔離原則 Interface Segregation Principle,ISP
接口隔離原則(Interface Segregation Principle,ISP)表明客戶端不應(yīng)該被強(qiáng)迫實(shí)現(xiàn)一些不會(huì)使用的接口,應(yīng)該把胖接口分組,用多個(gè)接口代替它,每個(gè)接口服務(wù)于一個(gè)子模塊。簡(jiǎn)單地說(shuō),就是使用多個(gè)專門的接口比使用單個(gè)接口要好很多。
ISP主要觀點(diǎn):
1.一個(gè)類對(duì)另外一個(gè)類的依賴性應(yīng)當(dāng)是建立在最小接口上的。
ISP可以達(dá)到不強(qiáng)迫客戶(接口使用者)依賴于他們不用的方法,接口的實(shí)現(xiàn)類應(yīng)該只呈現(xiàn)為單一職責(zé)的角色(遵守SRP原則)。
ISP可以降低客戶之間的相互影響——當(dāng)某個(gè)客戶程序要求提供新的職責(zé)(需求變化)而迫使接口發(fā)生變化時(shí),影響到其他客戶程序的可能性會(huì)最小。
2.客戶端程序不應(yīng)該依賴它不需要的接口方法(功能)。

ISP強(qiáng)調(diào)的是接口對(duì)客戶端的承諾越少越好,并且要做到專一。
接口污染就是為接口添加不必要的職責(zé)。“接口隔離”其實(shí)就是定制化服務(wù)設(shè)計(jì)的原則。使用接口的多重繼承實(shí)現(xiàn)對(duì)不同的接口的組合,從而對(duì)外提供組合功能——達(dá)到“按需提供服務(wù)”。

對(duì)于接口的污染,使用下面兩種處理方式:

利用委托分離接口。

利用多繼承分離接口。

委托模式中,有兩個(gè)對(duì)象參與處理同一個(gè)請(qǐng)求,接受請(qǐng)求的對(duì)象將請(qǐng)求委托給另一個(gè)對(duì)象來(lái)處理,如策略模式、代理模式等都應(yīng)用到了委托的概念。

開(kāi)放-封閉原則
隨著軟件系統(tǒng)的規(guī)模不斷增大,軟件系統(tǒng)的維護(hù)和修改的復(fù)雜性不斷提高,這種困境促使法國(guó)工程院士Bertrand Meyer在1998年提出了“開(kāi)放-封閉”(Open-Close Principle, OCP)原則,基本思想是:
Open(Open for extension)模塊的行為必須是開(kāi)放的、支持?jǐn)U展的,而不是僵化的。
Closed(Closed for modification)在對(duì)模塊的功能進(jìn)行擴(kuò)展時(shí),不應(yīng)該影響或大規(guī)模地影響已有的程序模塊。

換句話說(shuō),也就是要求開(kāi)發(fā)人員在不修改系統(tǒng)中現(xiàn)有功能代碼(源代碼或二進(jìn)制代碼)的前提下,實(shí)現(xiàn)對(duì)應(yīng)用系統(tǒng)的軟件功能的擴(kuò)展。用一句話概括就是:一個(gè)模塊在擴(kuò)展性方面應(yīng)該是開(kāi)放的而在更改性方面應(yīng)該是封閉的。
開(kāi)放-封閉能夠提高系統(tǒng)的可擴(kuò)展性和可維護(hù)性,但這也是相對(duì)的。
以播放器為例,先定義一個(gè)抽象的接口:

interface Process
{
    public function process();
}

然后對(duì)此接口進(jìn)行擴(kuò)展,實(shí)現(xiàn)解碼和輸出的功能:

class playerEncode implements Proess
{
    public function process(){
        echo "encode
";
    }
}    

class playerOutput implements Process
{
    public function process(){
        echo "output
";
    }
}

對(duì)于播放器的各種功能,這里是開(kāi)放的。只要你遵守約定,實(shí)現(xiàn)了process接口,就能給播放器添加新的功能模塊。
接下來(lái)為定義播放器的線程調(diào)度管理器,播放器一旦接收到通知(可以是外部單擊行為,也可以是內(nèi)部的notify行為),將回調(diào)實(shí)際的線程處理:

class playProcess
{
    private $message = null;
    public function __construct(){
    }
    
    public function callback(Event $event){
        $this->message = $event->click();
        if($this->message instanceof Process){
            $this->message->process();
        }
    }
}

具體的產(chǎn)品出來(lái)了,在這里定義一個(gè)MP4類,這個(gè)類是相對(duì)封閉的,其中定義事件的處理邏輯:

class MP4
{
    public function work(){
        $playProcess = new playProcess();
        $playProcess->callback(new Event("encode"));
        $playProcess->callback(new Event("output"));
    }
}

最后為事件分揀的處理類,此類負(fù)責(zé)對(duì)事件進(jìn)行分揀,判斷用戶或內(nèi)部行為,以產(chǎn)生正確的“線程”,供播放器內(nèi)置的線程管理器調(diào)度:

class Event
{
    private $m;
    
    public function __construct($me){
        $this->m = $me;
    }
    
    public function click(){
        switch($this->m){
            case "encode":
                return new playerEncode();
                break;
            case "output":
                return new playerOutput();
                break;    
        }
    }
}

運(yùn)行:

$mp4 = new MP4;
$mp4->work();
//打印結(jié)果
encode
output

如何遵守開(kāi)放-封閉原則
實(shí)現(xiàn)開(kāi)放-封閉的核心思想就是抽象編程的核心思想就是對(duì)抽象編程,而不是對(duì)具體編程,因?yàn)?b>抽象相對(duì)穩(wěn)定。讓類依賴于固定的抽象,這樣的修改就是封閉的;而通過(guò)面向?qū)ο蟮?b>繼承和多態(tài)機(jī)制,可以實(shí)現(xiàn)對(duì)抽象體的繼承,通過(guò)覆寫其方法來(lái)改變固有的行為,實(shí)現(xiàn)新的擴(kuò)展方法,所以對(duì)于擴(kuò)展就是開(kāi)放的。
1.在設(shè)計(jì)方面充分應(yīng)用“抽象”和封裝的思想。
一方面就是要在軟件系統(tǒng)中找出各種可能的“可變因素”,并將之封裝起來(lái);另一方面,一種可變性因素不應(yīng)當(dāng)散落在多個(gè)不同代碼模塊中,而應(yīng)當(dāng)被封裝到一個(gè)對(duì)象中。
2.在系統(tǒng)功能編程實(shí)現(xiàn)方面應(yīng)用面向接口編程。
當(dāng)需求發(fā)生變化時(shí),可以提供該接口新的實(shí)現(xiàn)類,以求適應(yīng)變化。
面向接口編程要求功能類實(shí)現(xiàn)接口,對(duì)象聲明為接口類型。再設(shè)計(jì)模式中,裝飾模式比較明顯地用到OCP。

替換原則
替換原則也稱里氏替換原則(Liskov Substitution Principle, LSP)的定義和主要思想如下:由于面向?qū)ο缶幊碳夹g(shù)中的繼承在具體的編程中過(guò)于簡(jiǎn)單,在許多系統(tǒng)的設(shè)計(jì)和編程實(shí)現(xiàn)中,我們并沒(méi)有認(rèn)真地、理性地思考應(yīng)用系統(tǒng)中各個(gè)類之間的繼承關(guān)系是否合適,派生類是否能正確地對(duì)其基類中的某些方法進(jìn)行重寫等問(wèn)題。因此經(jīng)常出現(xiàn)濫用繼承或者錯(cuò)誤地進(jìn)行了繼承等現(xiàn)象,給系統(tǒng)的后期維護(hù)帶來(lái)不少麻煩。
LSP指出:子類型必須能夠替換掉它們的父類型,并出現(xiàn)在父類能夠出現(xiàn)的任何地方。
LSP主要是針對(duì)繼承的設(shè)計(jì)原則,繼承與派生(多態(tài))是OOP的主要特性。
如何遵守LSP設(shè)計(jì)原則:

父類的方法都要在子類中實(shí)現(xiàn)或重寫,并且派生類只實(shí)現(xiàn)其抽象類中聲明的方法,而不應(yīng)當(dāng)給出多余的方法定義或?qū)崿F(xiàn)。

在客戶段程序中只應(yīng)該使用父類對(duì)象而不應(yīng)當(dāng)直接使用子類對(duì)象,這樣可以實(shí)現(xiàn)運(yùn)行期綁定(動(dòng)態(tài)綁定)。
如果A、B兩個(gè)類違反了LSP的設(shè)計(jì),通常的做法是創(chuàng)建一個(gè)新的抽象類C,作為兩個(gè)具體類的超類,將A和B的共同行為移到C中,從而解決A和B行為不完全一致的問(wèn)題。

依賴倒置原則 Dependence Inversion Principle, DIP
依賴倒置簡(jiǎn)單地講就是將依賴關(guān)系倒置為依賴接口,具體概念如下:

上層模塊不應(yīng)該依賴于下層模塊,它們共同依賴于一個(gè)抽象(父類不能依賴子類,它們都要依賴抽象類)。

抽象不能依賴于具體,具體應(yīng)該依賴于抽象。

為什么要依賴接口?因?yàn)榻涌隗w現(xiàn)對(duì)問(wèn)題的抽象,同時(shí)由于抽象一般是相對(duì)穩(wěn)定的或者是相對(duì)變化不頻繁的,而具體是易變的。因此,依賴抽象是實(shí)現(xiàn)代碼擴(kuò)展和運(yùn)行期內(nèi)綁定(多態(tài))的基礎(chǔ):只要實(shí)現(xiàn)了該抽象類的子類,都可以被類的使用者使用。

working();
    }
}

class workB
{
    private $e;
    public function set(employee $e){
        $this->e = $e;
    }
    
    public function work(){
        $this->e->working();
    }
}

$worka = new workA;
$worka->work();
$workb = new workB;
$workb->set(new teacher());
$workb->work();

在workA中,work方法依賴于teacher實(shí)現(xiàn);在workB中,work轉(zhuǎn)而依賴于抽象,這樣可以把需要的對(duì)象通過(guò)參數(shù)傳入。
在workB中,teacher實(shí)例通過(guò)setter方法傳入,從而實(shí)現(xiàn)了工廠模式。由于這樣的是實(shí)現(xiàn)是硬編碼的,為了實(shí)現(xiàn)代碼的進(jìn)一步擴(kuò)展,把這個(gè)依賴關(guān)系寫在配置文件里,指明workB需要一個(gè)teacher對(duì)象,專門由一個(gè)程序檢測(cè)配置是否正確(如所依賴的類文件是否存在)以及加載配置中所依賴的實(shí)現(xiàn),這個(gè)檢測(cè)程序,就稱為IOC容器。
IOC(Inversion Of Control)是依賴倒置原則(Dependence Inversion Principle, DIP)的同義詞。依賴注入(DI)和依賴查找(DS)是IOC的兩種實(shí)現(xiàn)。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/28428.html

相關(guān)文章

  • PHP面向對(duì)象設(shè)計(jì)五大原則(SOLID)梳理總結(jié)

    摘要:設(shè)計(jì)原則梳理,參考核心技術(shù)與最佳實(shí)踐敏捷開(kāi)發(fā)原則模式與實(shí)踐,文章面向?qū)ο笤O(shè)計(jì)的五大原則設(shè)計(jì)模式原則單一職責(zé)原則定義特性僅有一個(gè)引起類變化的原因一個(gè)類只承擔(dān)一項(xiàng)職責(zé)職責(zé)變化的原因避免相同的職責(zé)分散到不同的類,功能重復(fù)問(wèn)題一個(gè)類承擔(dān)的職責(zé)過(guò)多, PHP設(shè)計(jì)原則梳理,參考《PHP核心技術(shù)與最佳實(shí)踐》、《敏捷開(kāi)發(fā)原則、模式與實(shí)踐》,文章PHP面向?qū)ο笤O(shè)計(jì)的五大原則、設(shè)計(jì)模式原則SOLID 單一...

    王晗 評(píng)論0 收藏0
  • 編程中那些經(jīng)典套路——設(shè)計(jì)模式匯總

    摘要:如果看不懂的話,可以在評(píng)論區(qū)中提問(wèn),我會(huì)第一時(shí)間回答你無(wú)論何時(shí)我一直都在嗯哼該文章屬于編程中的那些經(jīng)典套路設(shè)計(jì)模式匯總系列 在正式閱讀前,我先談?wù)勎覀冊(cè)撚檬裁醋藙?shì)和心態(tài)學(xué)習(xí)設(shè)計(jì)模式: 如果你還沒(méi)有過(guò)多的編程經(jīng)驗(yàn)(泛指半年以下),我建議你把它當(dāng)做小說(shuō)來(lái)看,能看懂多少是多少,因?yàn)榘肽暌韵陆?jīng)驗(yàn)的程序員用到設(shè)計(jì)模式的情況只會(huì)出現(xiàn)在面試上,至于實(shí)際工作中?相對(duì)來(lái)說(shuō)這部分不會(huì)由你負(fù)責(zé)。 如果你已...

    youkede 評(píng)論0 收藏0
  • 深入理解JavaScript系列8:S.O.L.I.D五大原則之里氏替換原則

    摘要:前言本章我們要講解的是五大原則語(yǔ)言實(shí)現(xiàn)的第篇,里氏替換原則。因此,違反了里氏替換原則。與行為有關(guān),而不是繼承到現(xiàn)在,我們討論了和繼承上下文在內(nèi)的里氏替換原則,指示出的面向?qū)ο蟆? 前言 本章我們要講解的是S.O.L.I.D五大原則JavaScript語(yǔ)言實(shí)現(xiàn)的第3篇,里氏替換原則LSP(The Liskov Substitution Principle )。英文原文:http://fre...

    susheng 評(píng)論0 收藏0
  • 編程中那些套路——關(guān)于簡(jiǎn)單工廠模式

    摘要:簡(jiǎn)單工廠模式就是遵循了這一原則,它讓不同職責(zé)的類各司其職。重點(diǎn)來(lái)了,簡(jiǎn)單工廠模式的不足但是簡(jiǎn)單工廠模式有一個(gè)不足,雖然它遵循了單一職責(zé)原則,但它違反了另一條同樣很重要的原則開(kāi)放封閉原則。 該文章屬于《編程中的那些經(jīng)典套路——設(shè)計(jì)模式匯總》系列,并且以下內(nèi)容基于語(yǔ)言PHP 面向?qū)ο笪宕笤瓌t中有一點(diǎn)非常重要的原則:?jiǎn)我宦氊?zé)原則。 簡(jiǎn)單工廠模式就是遵循了這一原則,它讓不同職責(zé)的類各司其職。 ...

    Rocture 評(píng)論0 收藏0
  • 深入理解JavaScript系列6:S.O.L.I.D五大原則之單一職責(zé)

    摘要:,開(kāi)始我們的第一篇單一職責(zé)。通過(guò)解耦可以讓每個(gè)職責(zé)工更加有彈性地變化。關(guān)于本文本文轉(zhuǎn)自大叔的深入理解系列。深入理解系列文章,包括了原創(chuàng),翻譯,轉(zhuǎn)載,整理等各類型文章,原文是大叔的一個(gè)非常不錯(cuò)的專題,現(xiàn)將其重新整理發(fā)布。 前言 Bob大叔提出并發(fā)揚(yáng)了S.O.L.I.D五大原則,用來(lái)更好地進(jìn)行面向?qū)ο缶幊?,五大原則分別是: The Single Responsibility Princi...

    walterrwu 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<