ホームページ >バックエンド開発 >PHPチュートリアル >PHP のデコレータ パターンに関する簡単な説明

PHP のデコレータ パターンに関する簡単な説明

青灯夜游
青灯夜游転載
2021-06-23 18:40:392983ブラウズ

デコレータ パターンを使用すると、構造を変更せずに既存のオブジェクトに新しい機能を追加できます。この記事では、PHP のデコレータ パターンについて説明し、デコレータの利点とデコレータが最適なシナリオを紹介します。

PHP のデコレータ パターンに関する簡単な説明

ファクトリー パターンは終わりです。他のパターンをいくつか検討してみましょう。みなさんの中には女装をしたことがある方はいるでしょうか?女性プログラマーも多いと言われています。実際、今日のデコレーターのパターンはメイクアップに非常に似ています。 Program Yuan MM が来てくれれば、このデザインパターンをすぐに説明できると思います。

Gof クラス図と説明

装飾、ここではメイクアップに変えてみましょう。まずは顔を整えてからファンデーションを塗り、その後メイクをするという流れで、朝は薄メイクをして仕事に行くこともできますし、仕事が終わって厚化粧をして遊びに行くこともできます。 。もちろん、プログラマーが仕事を終える時間はたまたま夜のショーの後半に間に合っていました。とはいえ、どんなにメイクをしても顔は顔ですし、他人には分からない別人に変身することはできても、それは顔です。これは、オブジェクト(顔)にさまざまな装飾(化粧)を施し、顔を良くする(責任を増やす)デコレータです。

#GoF 定義: オブジェクトにいくつかの追加の責任を動的に追加します。機能の追加という点では、Decorator パターンはサブクラスを生成するよりも柔軟です

GoF クラス図:

PHP のデコレータ パターンに関する簡単な説明

コード実装:

interface Component{
    public function operation();
}

class ConcreteComponent implements Component{
    public function operation(){
        echo "I'm face!" . PHP_EOL;
    }
}

非常に単純なインターフェイスと実装。ここに特定の実装クラスを置きます。次のように考えてください。顔!

abstract class Decorator implements Component{
    protected $component;
    public function __construct(Component $component){
        $this->component = $component;
    }
}

抽象デコレータ クラスは Component インターフェイスを実装しますが、operation() メソッドを実装しないため、サブクラスがそれを実装できます。ここでは主にコンポーネントへの参照を保存します。これは後で装飾されます。上記の特定のカテゴリに対応して、顔にメイクを施す準備をしていきます。

class ConcreteDecoratorA extends Decorator{
    public $addedState = 1; // 没什么实际意义的属性,只是区别于ConcreteDecoratorB

    public function operation(){
        echo $this->component->operation() . "Push " . $this->addedState . " cream!" . PHP_EOL;
    }
}
class ConcreteDecoratorB extends Decorator{
    public function operation(){
        $this->component->operation();
        $this->addedBehavior();
    }

    // 没什么实际意义的方法,只是区别于ConcreteDecoratorA
    public function addedBehavior(){
        echo "Push 2 cream!" . PHP_EOL;
    }
}

コンクリートデコレーター2名。ここでクリームを2回塗りましたが、私は純粋な男で、メイクについてはあまり詳しくありません。最初のステップはファンデーションを塗ることだと思いますよね?しかし今回、2 人のデコレーターが達成したのは、顔にフロストを 2 層塗ることです。

    コードから、特定の ConcreteComponent オブジェクトをパッケージ化していることがわかります。
  • さらに進むと、実際にはそのoperation() メソッドを 2 回パッケージ化しており、毎回少しずつ追加しています。前のものに基づいたもの
  • A デコレータと B デコレータに追加された属性とメソッドにこだわる必要はありません、これらは GoF クラス図内でこれらを区別するためにのみ使用されます。同じことです。それぞれのデコレータは他にも多くのことを行うことができます。Component オブジェクトには、必ずしも Operation() メソッドだけがあるとは限りません。オブジェクト内のメソッドのすべてまたは一部を選択的に装飾できます
  • すべて継承されたコンポーネントです。それをサブクラス化して完全に書き直すことはできないでしょうか? なぜ、このような苦労をするのでしょうか?親愛なる皆さん、組み合わせの概念を理解してください。デコレータの親クラスには実際のオブジェクトへの参照が含まれており、それ自体が分離されます。実際のオブジェクトをラップするだけです。デコレータを直接使用するために直接インスタンス化しないでください。
  • まだわかりませんか?メリットは何ですか?古いシステムのクラスやメソッドをランダムに変更する勇気はありますか?元恋人が書いたすばらしいコードに新しい関数を追加したいときは、デコレータを試してみると、驚くほどうまくいくかもしれません。

この携帯電話の物は、某Mi、某O、某Weiには使えません。プレイすることは不可能です。まあ、相棒、携帯電話の作成に集中してください電話ケース!さて、最初に透明なシェル(コンポーネント)を用意しましたが、見た目は少々見苦しいですが、これは仕方がありません。あるメーターに様々な単色(DecoratorA1)を追加し、裏面に様々な色の植物(DecoratorB1)を印刷します;某Oさんの携帯電話が最近トラフィックに支持されるのが好きなので、彼の携帯電話ケースに様々な色を使用しますまばゆいばかりの色 (DecoratorA2) と有名人の漫画のアバター (DecoratorB2)、最後に、携帯電話が業界のトレンドをリードし始めているようです。この折りたたみスクリーンのせいで、携帯電話ケースを販売する私のビジネスが台無しになるのではありませんか? !分かった、私はあなたのためにはしません、だから私の誰々のミーと誰々のオーと付き合ってください! !

完全なコード: デコレータ パターン

https://github.com/zhangyue0503/designpatterns-php/blob/master/04.decorator/source/decorator.php

テキスト メッセージの送信を続ける 以前は、複数の SMS オペレーターの問題を解決するためにファクトリー モードを使用していました。今回は、テキスト メッセージのコンテンツ テンプレートの問題を解決する必要があります。宣伝文には最新の広告法により「国内No.1」「世界No.1」などの文言は使用できませんし、もちろん一部の野蛮な用語も使用できません。

现在的情况是这样的,我们有一个很早之前的短信模板类,里面的内容是固定的,老系统依然还是使用这个模板,老系统是面对的内部员工,对语言内容的要求不高。而新系统则需要向全网发送,也就是内外部的用户都要发送。这时,我们可以用装饰器模式来对老系统的短信模板进行包装。其实说简单点,我们就是用装饰器来做文本替换的功能。好处呢?当然是可以不去改动原来的模板类中的方法就实现了对老模板内容的修改扩展等。

短信发送类图:

PHP のデコレータ パターンに関する簡単な説明

完整源码:短信发送装饰器方法

https://github.com/zhangyue0503/designpatterns-php/blob/master/04.decorator/source/message-decorator.php

<?php
// 短信模板接口
interface MessageTemplate
{
    public function message();
}

// 假设有很多模板实现了上面的短信模板接口
// 下面这个是其中一个优惠券发送的模板实现
class CouponMessageTemplate implements MessageTemplate
{
    public function message()
    {
        return &#39;优惠券信息:我们是全国第一的牛X产品哦,送您十张优惠券!&#39;;
    }
}

// 我们来准备好装饰上面那个过时的短信模板
abstract class DecoratorMessageTemplate implements MessageTemplate
{
    public $template;
    public function __construct($template)
    {
        $this->template = $template;
    }
}

// 过滤新广告法中不允许出现的词汇
class AdFilterDecoratorMessage extends DecoratorMessageTemplate
{
    public function message()
    {
        return str_replace(&#39;全国第一&#39;, &#39;全国第二&#39;, $this->template->message());
    }
}

// 使用我们的大数据部门同事自动生成的新词库来过滤敏感词汇,这块过滤不是强制要过滤的内容,可选择使用
class SensitiveFilterDecoratorMessage extends DecoratorMessageTemplate
{
    public $bigDataFilterWords = [&#39;牛X&#39;];
    public $bigDataReplaceWords = [&#39;好用&#39;];
    public function message()
    {
        return str_replace($this->bigDataFilterWords, $this->bigDataReplaceWords, $this->template->message());
    }
}

// 客户端,发送接口,需要使用模板来进行短信发送
class Message
{
    public $msgType = &#39;old&#39;;
    public function send(MessageTemplate $mt)
    {
        // 发送出去咯
        if ($this->msgType == &#39;old&#39;) {
            echo &#39;面向内网用户发送&#39; . $mt->message() . PHP_EOL;
        } else if ($this->msgType == &#39;new&#39;) {
            echo &#39;面向全网用户发送&#39; . $mt->message() . PHP_EOL;
        }

    }
}

$template = new CouponMessageTemplate();
$message = new Message();

// 老系统,用不着过滤,只有内部用户才看得到
$message->send($template);

// 新系统,面向全网发布的,需要过滤一下内容哦
$message->msgType = &#39;new&#39;;
$template = new AdFilterDecoratorMessage($template);
$template = new SensitiveFilterDecoratorMessage($template);

// 过滤完了,发送吧
$message->send($template);

说明

  • 装饰器的最大好处:一是不改变原有代码的情况下对原有代码中的内容进行扩展,开放封闭原则;二是每个装饰器完成自己的功能,单一职责;三是用组合实现了继承的感觉;
  • 最适用于:给老系统进行扩展
  • 要小心:过多的装饰者会把你搞晕的
  • 不一定都是对同一个方法进行装饰,其实装饰者应该更多的用于对对象的装饰,对对象进行扩展,这里我们都是针对一个方法的输出进行装饰,但仅限此文,装饰器的应用其实更加广泛
  • 装饰器的特点是全部都继承自一个主接口或类,这样的好处就是返回的对象是相同的抽象数据,具有相同的行为属性,否则,就不是装饰之前的对象,而是一个新对象了
  • 有点不好理解没关系,我们这次的例子其实也很勉强,这个设计模式在《Head First设计模式》中有提到Java的I/O系列接口是使用的这种设计模式:FileInputStream、LineNumberInputStream、BufferInputStream等
  • Laravel框架中的中间件管道,这里其实是多种模式的综合应用,其中也应用到了装饰器模式:Laravel HTTP——Pipeline 中间件装饰者模式源码分析
  • 另外在Laravel中,日志处理这里也是对Monolog进行了装饰,有兴趣的同学可以去了解下

推荐学习:《PHP视频教程

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

声明:
この記事はjuejin.imで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。