【面向對象的PHP】之模式:原型

原型模式

平行的繼承層次使用工廠模式在:大型設計中,必須去維護大量的產品類。(上文中,稱之爲「特殊的耦合」)數據庫

在這裏咱們介紹一種其抽象工廠模式的變體:原型模式。它使用clone關鍵詞,來複制具體產品類,使得具體產品類能完成自我複製。segmentfault

(通俗介紹:工場只負責生產產品,選擇生產何等產品,再也不由工場本身決定,而是經過傳參,來確認——對比抽象工廠,你能夠發現,咱們再也找不到一大羣具體產品的建立者,而只有一個高度靈活的建立者)設計模式

問題

假設咱們在作一款相似文明(Cicilization)的網頁遊戲——這麼經典的遊戲都沒玩過?成何體統[滑稽]。(屠龍寶刀,點擊就送!)this

裏面有個 戰鬥用途的地理系統——三種地形:海洋 Sea/平原 Forest/森林 Plains,按照抽象工廠 + 工廠模式,咱們確定能夠獲得這樣的結果:編碼

UML - StartUML

(爲什麼個人眼裏常含淚水,由於StartUML2.5難用的深沉)spa

但咱們要避免「大型的繼承體系」——開頭說了,這會形成另類耦合,因而,來看看原型模式的解決方法吧!設計

實現

class Sea {}
class EarthSea extends Sea {}
class MarsSea extends Sea {}

class Plains {}
class EarthPlains extends Plains {}
class MarsPlains extends Plains {}

class Forest {}
class EarthForest extends Forest {}
class MarsForest extends Forest {}

class TerrainFactory {
    private $sea;
    private $plains;
    private $forest;

    function __construct( Sea $sea, Plains $plains, Forest $forest )
    {
        $this->sea = $sea;
        $this->plains = $plains;
        $this->forest = $forest;
    }

    function getSea() {
        return clone $this->sea;
    }

    function getPlains() {
        return clone $this->plains;
    }

    function getForest() {
        return clone  $this->forest;
    }
}

$factory = new TerrainFactory(
    new EarthSea(),
    new EarthPlains(),
    new EarthForest()
);

print_r( $factory->getSea() );
print_r( $factory->getPlains() );
print_r( $factory->getForest() );

讀完代碼,你就能看懂原型模式,創造者能夠無腦的生產出一片「具有三種地形的戰鬥區域」,你在地球風格的海洋和森林。火星風格的平原上戰鬥?那麼只須要傳遞三個對應參數便可,換而言之——創造者再也不負責:我要造什麼。rest

咱們還能夠增長一些靈活性,譬如:海洋地形中的航行難度——營造出一種「索馬里海域 / 渤海海域」的差別(在古代,索馬里海域的航船條件至關兇惡)。code

class Sea {
    private $navigability = 0;

    function __construct( $navigability )
    {
        $this->navigability = $navigability;
    }
}

...省略部分代碼...

$factory = new TerrainFactory(
    new EarthSea( -1 ),
    new EarthPlains(),
    new EarthForest()
);

能夠預見,這是多麼具有靈活性的模式。額外說起:若是產品類包含了其餘外部類,記得采用__clone()方法,這樣能夠保證你獲得的是深度複製(deep copy)面向對象設計模式

模式的誘導性

本節沒有結論(或者,這個模式很好理解),這裏說起一個模式的誘導和騙術:它們並無幫你決定Create Who?

不管是工廠模式、抽象工廠模式,亦或是原型模式,它們都只是在技術層面簡化了類的數量、維護複雜度。

你仍是須要本身決定:生產特定的產品——你會將這些決定留在整個代碼系統,在你須要修改一處時,形成癱瘓。

解決方案:操控單例類 / 存儲於數據庫 / 甚至直接寫到配置文件(.htaccess等)——包含大量的標記/硬編碼;

我的推薦:單例類 + 配置文件,優勢:方便修改、全局訪問

面向對象設計模式 - 目錄

相關文章
相關標籤/搜索