데코레이터 패턴을 사용하면 구조를 변경하지 않고도 기존 객체에 새로운 기능을 추가할 수 있습니다. 이 기사에서는 PHP의 데코레이터 패턴을 안내하고 데코레이터의 이점과 가장 적합한 시나리오를 소개합니다.
팩토리 패턴이 끝났으니 다른 패턴을 공부해 볼까요? 혹시 여성복을 입어보신 분 있으신가요? 여성 프로그래머가 많다고 합니다. 사실 오늘날의 데코레이터 패턴은 메이크업과 매우 유사합니다. 나는 Program Yuan MM이 여기 있다면 이 디자인 패턴을 즉시 설명할 수 있다고 믿습니다.
장식이라는 두 단어는 일단 메이크업으로 바꿔보겠습니다. 먼저 얼굴을 정돈한 다음 파운데이션을 바르고 화장을 하세요. 아침에 출근할 때는 옅은 화장을 해도 되고, 퇴근하고 놀러 갈 때는 짙은 화장을 해도 됩니다. . 물론 프로그래머들이 퇴근하는 시간은 공교롭게도 하반기 심야쇼 시간과 맞먹는다. 그런데 아무리 화장을 해도 얼굴은 자기 얼굴이고, 남들이 알아보지 못하는 다른 사람으로 변신할 수도 있지만, 그래도 얼굴은 자기 얼굴이다. 객체(얼굴)에 다양한 장식(화장)을 하여 얼굴을 더 돋보이게 만드는(책임감 증가) 데코레이터입니다.
GoF 정의: 기능 추가 측면에서 일부 추가 책임을 동적으로 추가하는 측면에서 데코레이터 패턴은 하위 클래스를 생성하는 것보다 더 유연합니다.
GoF 클래스 다이어그램:
코드 구현:
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() 메서드는 구현하지 않으므로 하위 클래스에서 구현할 수 있습니다. 여기서는 주로 나중에 장식할 Component에 대한 참조를 저장합니다. 위의 특정 카테고리에 맞춰 얼굴 메이크업을 준비할 예정이에요!
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; } }
콘크리트 장식가 두 명. 저는 여기 크림을 두 번 발랐어요. 역시 저는 순수한 남자이고 메이크업에 대해 잘 모르는 편이에요. 첫 번째 단계는 파운데이션을 바르는 것 같죠? 하지만 이번에는 두 명의 데코레이터가 달성한 것이 얼굴에 두 겹의 서리를 바르는 것입니다.
전체 코드: 데코레이터 패턴
https://github.com/zhangyue0503/designpatterns-php/blob/master/04.designator/source/ decorator.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 '优惠券信息:我们是全国第一的牛X产品哦,送您十张优惠券!'; } } // 我们来准备好装饰上面那个过时的短信模板 abstract class DecoratorMessageTemplate implements MessageTemplate { public $template; public function __construct($template) { $this->template = $template; } } // 过滤新广告法中不允许出现的词汇 class AdFilterDecoratorMessage extends DecoratorMessageTemplate { public function message() { return str_replace('全国第一', '全国第二', $this->template->message()); } } // 使用我们的大数据部门同事自动生成的新词库来过滤敏感词汇,这块过滤不是强制要过滤的内容,可选择使用 class SensitiveFilterDecoratorMessage extends DecoratorMessageTemplate { public $bigDataFilterWords = ['牛X']; public $bigDataReplaceWords = ['好用']; public function message() { return str_replace($this->bigDataFilterWords, $this->bigDataReplaceWords, $this->template->message()); } } // 客户端,发送接口,需要使用模板来进行短信发送 class Message { public $msgType = 'old'; public function send(MessageTemplate $mt) { // 发送出去咯 if ($this->msgType == 'old') { echo '面向内网用户发送' . $mt->message() . PHP_EOL; } else if ($this->msgType == 'new') { echo '面向全网用户发送' . $mt->message() . PHP_EOL; } } } $template = new CouponMessageTemplate(); $message = new Message(); // 老系统,用不着过滤,只有内部用户才看得到 $message->send($template); // 新系统,面向全网发布的,需要过滤一下内容哦 $message->msgType = 'new'; $template = new AdFilterDecoratorMessage($template); $template = new SensitiveFilterDecoratorMessage($template); // 过滤完了,发送吧 $message->send($template);
说明
推荐学习:《PHP视频教程》
위 내용은 PHP의 데코레이터 패턴에 대한 간략한 토론의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!