ホームページ  >  記事  >  バックエンド開発  >  PHPデコレータパターンの使い方を詳しく解説

PHPデコレータパターンの使い方を詳しく解説

php中世界最好的语言
php中世界最好的语言オリジナル
2018-05-17 11:48:162201ブラウズ

今回は、PHPデコレーターモードの使用方法について詳しく説明します。PHPデコレーターモードを使用する際の注意点は何ですか。以下は実際のケースです。見てみましょう。

Decoratorパターンとは

Decoratorパターンは、構造パターンとして、既存の構造に「装飾」を追加するものです。

アダプターパターンは、今のところ、構造に追加されるものは、クラスのインターフェイスを顧客が期待する別のインターフェイスに変換するアダプター クラスです。アダプターを使用すると、互換性のないインターフェイスを持つクラスが適切に連携できるようになります。

デコレーター パターン は、新しい動作を強化し、デコレーターはラッパーとも呼ばれます (アダプターと同様)

一部のデザイン パターンには、別の抽象クラスも継承します。そのようなデザイン パターンは多数あり、デコレーターはその 1 つです。デコレータ パターンを使用する場合

基本的に、他のオブジェクトに影響を与えずに既存のオブジェクトに新しい機能を追加したい場合は、Web サイトのフォーマットを作成するのに苦労した場合は、デコレータ パターンを使用できます。クライアントと主要コンポーネントが完全に機能する場合、クライアントが新しい機能を要求したときに、車輪を再発明してサイトを再作成する必要はありません。たとえば、クライアントが最初に要求した Web サイトを構築したとします。そして、顧客が新たなニーズを持ち、Web サイトにビデオ機能を組み込みたいと考えている場合、元のコンポーネントを書き直す必要はなく、既存のコンポーネントを「装飾」してそこにビデオ機能を追加するだけで済みます。元の機能を維持することもできます。新しい機能を追加することもできます。 一部のプロジェクトは装飾が必要な場合もあれば、装飾したくない場合もあります。開発パターンはほとんどの顧客の要件を満たすことができますが、一部のクライアントは、これらの追加機能を誰もが望んでいるわけではありません。 「顧客化」機能、つまり特定のビジネス向けに提供される機能を提供する デコレーター パターンを使用すると、コア機能を提供するだけでなく、これらのコア機能を顧客が必要とする独自の機能で「装飾」することもできます。単純な装飾の例

ある Web 開発企業は、いくつかの機能強化を加えた基本的な Web サイトを構築することを計画しています。ただし、Web 開発者は、この基本的なプランはほとんどのクライアントで機能しますが、クライアントがそれをさらに強化したい可能性があることを知っています。将来的には、デコレーター モードを使用すると、複数の特定のデコレーターを簡単に追加できるようになり、追加するデコレーターを選択できるため、機能だけでなく、

コンポーネント インターフェイス

のコストも管理できるようになります。コンポーネントの参加はインターフェイスであり、ここでは抽象クラス IComponent です。この抽象クラスには $site 属性が 1 つだけあり、

参加者は特定のコンポーネントと Decorator 参加者抽象クラスのインターフェイスを明確に確立します:

IComponent .php

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

getSite()getPrice().Componentデコレータ インターフェイス

この例のデコレータ インターフェイスは驚くかもしれませんが、これは抽象クラスであり、別の抽象クラスも拡張しています。このクラスの役割は、コンポーネント インターフェイス (IComponent) を維持することです。これは、IComponent を拡張することで行われます:

Decorator.php

<?php
abstract class Decorator extends IComponent
{
  /*
  任务是维护Component的引用
  继承getSite()和getPrice()
  因为仍然是抽象类,所以不需要实现父类任何一个抽象方法
  */
}

Decorator クラスの主な役割は、コンポーネント インターフェイスへの参照を維持することです。

すべてのデコレータ パターンの実装では、両方の具象コンポーネントがさらに、基本インターフェイスの

プロパティとメソッド に加えて、コンポーネントとデコレータには追加のプロパティとメソッドがある場合があります。

具体的なコンポーネント

があります。この例では、Web サイト名と基本的な Web サイトの引用を生成する特定のコンポーネントが 1 つだけです:

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;
  }
}
どちらの抽象メソッドも直接代入を使用して実装されていますが、柔軟性は反映されていません の値を変更する方法実際には、デコレータの値を追加して「基本サイト」の値を変更する必要があります。

特定のデコレータ

这个例子中的具体装饰器与具体组件有相同的接口.实际上, 它们是从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 . &#39;.php&#39;;
}
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中文网其它相关文章!

推荐阅读:

PHP基于面向对象实现留言本步骤详解

PHP里氏替换原则实战分析

以上がPHPデコレータパターンの使い方を詳しく解説の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。