程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> PHP編程 >> PHP綜合 >> php設計模式介紹之裝飾器模式

php設計模式介紹之裝飾器模式

編輯:PHP綜合

若你從事過面向對象的php開發,即使很短的時間或者僅僅通過本書了解了一些,你會知道,你可以 通過繼承改變或者增加一個類的功能,這是所有面向對象語言的一個基本特性。如果已經存在的一個php 類缺少某些方法,或者須要給方法添加更多的功能(魅力),你也許會僅僅繼承這個類來產生一個新類 —這建立在額外的代碼上。

但是產生子類並不總是可能或是合適的。如果 你希望改變一 個已經初始化的對象的行為,你怎麼辦?或者,你希望繼承許多類的行為,改怎麼辦?前一個,只能在於 運行時完成,後者顯然時可能的,但是可能會導致產生大量的不同的類—可怕的事情。

問 題

你如何組織你的代碼使其可以容易的添加基本的或者一些很少用到的 特性,而不是直接不額 外的代碼寫在你的類的內部?

解決方案

裝飾器模式提供了改變子類的靈活方案。裝飾器 模式允許你在不引起子類數量爆炸的情況下動態的修飾對象,添加特性。

當用於一組子類時,裝 飾器模式更加有用。如果你擁有一族子類(從一個父類派生而來),你需要在與子類獨立使用情況下添 加額外的特性,你可以使用裝飾器模式,以避免代碼重復和具體子類數量的增加。看看以下例子,你可 以更好的理解這種觀點。考慮一個建立在組件概念上的“form”表單庫,在那裡你需要為每 一個你想要表現的表單控制類型建立一個類。這種類圖可以如下所示:

Select and TextInput類是組件類的子類。假如你想要增加一個“labeled”帶標簽的組件—一個輸入表單告訴 你要輸入的內容。因為任何一個表單都可能需要被標記,你可能會象這樣繼承每一個具體的組件:

上面的 類圖看起來並不怎麼壞,下面讓我們再增加一些特性。表單驗證階段,你希望能夠指出一個表單控制是 否合法。你為非法控制使用的代碼又一次繼承其它組件,因此又需要產生大量的子類:

這個類看起來並不是 太壞,所以讓我們增加一些新的功能。在結構有效性確認中你需要指出結構是否是有效的。你需要讓你 檢驗有效性的代碼也可以應用到其它部件,這樣不用再更多的子類上進行有效性驗證。

這裡子類溢出並不是 唯一的問題。想一想那些重復的代碼,你需要重新設計你的整個類層次。有沒有更好的方法!確實,裝 飾器模式是避免這種情況的好方法。

裝飾器模式結構上類似與代理模式(參見第2章)。一個裝 飾器對象保留有對對象的引用,而且忠實的重新建立被裝飾對象的公共接口。裝飾器也可以增加方法, 擴展被裝飾對象的接口,任意重載方法,甚至可以在腳本執行期間有條件的重載方法。

為了探究 裝飾器模式,讓我們以前面討論過的表單組件庫為例,並且用裝飾器模式而不是繼承,實現 “lable”和“invalidation”兩個特性。

樣本代碼:

組件庫包含 哪些特性?

容易創建表單元素

將表單元素以html方式輸出

在每個元素上實現簡單 的驗證

本例中,我們創建一個包含姓,名,郵件地址,輸入項的表單。所有的區域都是必須的, 而且E-mail必須看起來是有效的E—mail地址。用HTML語言表示,表單的代碼象下面所示:

<form action=”formpage.PHP” method=”post”>
<b>First Name:</b> <input type=”text” name=”fname” value=””><br>
<b>Last Name:</b> <input type=”text” name=”lname” value=””><br>
<b>Email:</b> <input type=”text” name=”email” value=””><br>
<input type=”submit” value=”Submit”>
</form>

增加一些css樣式後,表單渲染 出來如下圖所示:

為建立統一的API,我們創建一個基本的組件類(如果這是php5的例子,這或許會使用接口) 。既然所有的組件(表單元素)都必須渲染一些輸出,組建類可以僅僅只有一個paint()方法。

class Widget {
function paint() {
return $this->_asHtml();
}
}

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved