中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

PHP設計模式之裝飾器模式的示例分析

發布時間:2021-06-11 15:38:47 來源:億速云 閱讀:145 作者:小新 欄目:開發技術

這篇文章將為大家詳細講解有關PHP設計模式之裝飾器模式的示例分析,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。

什么是裝飾器模式

作為一種結構型模式, 裝飾器(Decorator)模式就是對一個已有結構增加"裝飾".

適配器模式, 是為現在有結構增加的是一個適配器類,.將一個類的接口,轉換成客戶期望的另外一個接口.適配器讓原本接口不兼容的類可以很好的合作.

裝飾器模式是將一個對象包裝起來以增強新的行為和責任.裝飾器也稱為包裝器(類似于適配器)

有些設計設計模式包含一個抽象類,而且該抽象類還繼承了另一個抽象類,這種設計模式為數不多,而裝飾器就是其中之一.

什么時候使用裝飾器模式

基本說來, 如果想為現有對象增加新功能而不想影響其他對象, 就可以使用裝飾器模式.如果你好不容易為客戶創建了一個網站格式, 主要組件的工作都很完美, 客戶請求新功能時, 你肯定不希望推翻重來, 再重新創建網站. 例如, 假設你已經構建了客戶原先請求的組件, 之后客戶又有了新的需求, 希望在網站中包含視頻功能. 你不用重寫原先的組件, 只需要"裝飾"現有組件, 為它們增加視頻功能. 這樣即可以保持原來的功能,還可以增加新功能.

有些項目可能有時需要裝飾, 而有時不希望裝飾, 這些項目體現了裝飾器設計模式的另一個重要特性.假設你的基本網站開發模式可以滿足大多數客戶的要求. 不過, 胡些客戶還希望有一些特定的功能來滿足他們的需求. 并不是所有人都希望或需要這些額外的功能. 作為開發人員, 你希望你創建的網站能滿足客戶的業務目標. 所以需要提供"本地化"(customerization)特性, 即針對特定業務提供的特性. 利用裝飾器模式, 不僅能提供核心功能, 還可以用客戶要求的特有功能"裝飾"這些核心功能.

簡單的裝飾器例子

一個web開發企業,計劃建立一個基本網站,并提供一些增強功能. 不過,web開發人員知道, 盡管這個基本計劃適用于大多數客戶, 但客戶以后很可能還希望進一步提升, 利用裝飾器模式, 可以很容易地增加多個具體裝飾器,另外由于你能選擇要增加的裝飾器, 所以企業不僅能控制功能, 還可以控制項目的成本 .

Component接口

Component參與者是一個接口, 在這里, 它是一個抽象類IComponent. 這個抽象類只有一個屬性$site, 另外有兩個抽象方法getSite()getPrice().Component參與者具體為具體組件和Decorator參與者抽象類建立接口:

IComponent.php

<?php
abstract class IComponent
{
  protected $site;
  abstract public function getSite();
  abstract public function getPrice();
}

Decorator接口

這個例子中的裝飾器接口可能會讓你驚訝.這是一個抽象類,而且它還擴展了另一個抽象類! 這個類的作用就是維護組件接口(IComponent)的一個引用, 這是通過擴展IComponent完成的:

Decorator.php

<?php
abstract class Decorator extends IComponent
{
  /*
  任務是維護Component的引用
  繼承getSite()和getPrice()
  因為仍然是抽象類,所以不需要實現父類任何一個抽象方法
  */
}

Decorator類的主要作用就是維護組件接口的一個引用.

在所有的裝飾器模式實現中, 你會發現,具體組件和裝飾順都有相同的接口. 它們的實現可能不同, 另外除了基本接口的屬性和方法外, 組件和裝飾器可能還有額外的屬性和方法.

具體組件

這個例子中只有一個具體組件,它生成一個網站名, 另外生成一個基本網站報價:

BasicSite.php

<?php
class BasicSite extends IComponent
{
  public function __construct()
  {
    $this->site = "Basic Site";
  }
  public function getSite()
  {
    return $this->site;
  }
  public function getPrice()
  {
    return 1200;
  }
}

兩個抽象方法都使用直接賦值來實現, 不過靈活性并不體現在如何改變設置的值.實際上, 要通過增加裝飾器值來改變"Basic Site"值.

具體裝飾器

這個例子中的具體裝飾器與具體組件有相同的接口.實際上, 它們是從Decorator抽象類(而不是IComponent類)繼承了這個接口. 不過,要記住, Decorator所做的就是繼承IComponent接口.

Maintenance.php

<?php
class Maintenance extends Decorator
{
  public function __construct(IComponent $siteNow)
  {
    $this->site = $siteNow;
  }
  public function getSite()
  {
    $format = "<br /> Maintenance";
    return $this->site->getSite() . $format;
  }
  public function getPrice()
  {
    return 950 + $this->site->getPrice();
  }
}

這個裝飾器Maintenance在改變了site的值, 還有包裝的具體組件價格上還會增加它自己 的價格. 另個兩個具體裝飾器與Maintenance裝飾器也類似

Video.php

<?php
class Video extends Decorator
{
  public function __construct(IComponent $siteNow)
  {
    $this->site = $siteNow;
  }
  public function getSite()
  {
    $format = "<br /> Video";
    return $this->site->getSite() . $format;
  }
  public function getPrice()
  {
    return 350 + $this->site->getPrice();
  }
}

DataBase.php

<?php
class DataBase extends Decorator
{
  public function __construct(IComponent $siteNow)
  {
    $this->site = $siteNow;
  }
  public function getSite()
  {
    $format = "<br /> DataBase";
    return $this->site->getSite() . $format;
  }
  public function getPrice()
  {
    return 800 + $this->site->getPrice();
  }
}

測試這個應用時,可以看到,在基本的價格之上還會增加各個裝飾器的價格.另外還能指定裝飾器名的格式, 增加了兩個空格,使之縮進

裝飾器實現中最重要的元素之五就是構造函數, 要為構造函數提供一個組件類型. 由于這里只有一個具體組件, 所有裝飾器的實例化都會使用這個組件. 使用多個組件時, 裝飾器可以包裝應用中的一部分或全部組件, 也可以不包裝任何組件.

客戶

Client類并不是這個設計模式的一部分, 但是正確使用Client類至關重要.每個裝飾器在實例化時"包裝"組件, 不過, 首先必須創建一個要包裝的對象, 這里是BasicSite類實例

Client.php

<?php
function __autoload($class_name)
{
  include $class_name . '.php';
}
class Client
{
  private $basicSite;
  public function __construct()
  {
    $this->basicSite = new BasicSite();
    $this->basicSite = $this->WrapComponent($this->basicSite);
    $siteShow = $this->basicSite->getSite();
    $format = "<br /> <strong>Total= $";
    $price = $this->basicSite->getPrice();
    echo $siteShow . $format . $price . "</strong>";
  }
  private function WrapComponent(IComponent $component)
  {
    $component = new Maintenance($component);
    $component = new Video($component);
    $component = new DataBase($component);
    return $component;
  }
}
$worker = new Client();

wrapComponent()方法檢查傳入的BasicSite實例, 以確保參數有正確的數據類型(IComponent), 然后分別實例化3個裝飾器, 對該實例對象進行裝飾.

Basic Site
  Maintenance
  Video
  DataBase
  Total= $3300

適配器和裝飾器模式都有另外一個名字"包裝器"(wrapper)".

適配器可以"包裝"一個對象, 創建一個與Adaptee兼容的接口, 而無須對它做任何修改.

裝飾器也可以"包裝"一個組件對象, 這樣就能為這個已胡的組件增加職責, 而無須對它做任何修改.

下面的代碼展示了Client如何將組件對象($component)包裝在裝飾器(Maintence)中:

$component = new Maintenance($component);

類似于"接口", 在計算機編程中用到"包裝器"時, 不同的上下文會有不同的用法和含義. 一般來講, 在設計模式中使用"包裝器"是為了處理接口的不兼容, 或者希望為組件增加功能,包裝器就表示用來減少不兼容性的策略.

關于“PHP設計模式之裝飾器模式的示例分析”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

php
AI

洛阳市| 丹凤县| 进贤县| 会昌县| 达州市| 离岛区| 鹿泉市| 萝北县| 房产| 澎湖县| 海口市| 于都县| 时尚| 合川市| 平顺县| 博白县| 张北县| 贵定县| 二连浩特市| 漳浦县| 麻阳| 扎赉特旗| 松滋市| 竹北市| 清流县| 长葛市| 江津市| 武宣县| 思南县| 盐津县| 团风县| 汝城县| 建宁县| 常山县| 乌审旗| 耿马| 乌兰县| 白水县| 安岳县| 寿宁县| 司法|