라면 이야기
라면집에서는 라면을 작은 그릇과 큰 그릇으로 나누어서 팔고 있어요. 게다가 쇠고기를 추가하면 6위안, 계란 1개는 1위안, 라지 스테이크는 5위안, 바삭한 밥 한 조각은 1위안을 추가해야 한다. 전통적인 필기 방식을 사용하여 라면 가격을 다르게 설정하는 경우 8가지 항목(라면 분량 * 반찬 수)을 작성해야 합니다. 이제 국수 가게에서 새로운 부분 크기(중형 그릇)를 도입하는 경우 4개의 새로운 카테고리를 추가해야 합니다. 이로 인해 클래스 폭발이라는 문제가 발생합니다.
제 이전 글https://www.php.cn/php-weizijiaocheng-457250.html을 읽어보신 분이라면 브리지 모드를 이해하신 후 브리지 모드를 사용하면 이 문제를 해결할 수 있다는 느낌을 받으실 것입니다. 크게 면류와 반찬류로 나눕니다.
아래에서는 브리지 모드를 사용하여 위의 문제를 완료합니다. 코드는 다음과 같습니다.
interface INoodle { function cost (); function desc (); } class BigNoodle implements INoodle { private $cost = 9.0; private $dish = null; public function __construct(IDish $dish) { $this->dish = $dish; } public function cost() { return $this->cost + $this->dish->cost(); } public function desc() { return $this->dish->desc() . '大碗拉面'; } } class SmallNoodle implements INoodle { private $cost = 6.0; private $dish = null; public function __construct(IDish $dish) { $this->dish = $dish; } public function cost() { return $this->cost + $this->dish->cost(); } public function desc() { return $this->dish->desc() . '小碗拉面'; } } interface IDish { function cost (); function desc (); } class Beef implements IDish { public function cost () { return 6; } public function desc() { return '牛肉'; } } class Crust implements IDish { public function cost () { return 1; } public function desc() { return '锅巴'; } } class Egg implements IDish { public function cost () { return 1; } public function desc() { return '鸡蛋'; } }
Decorator 모드
브리지 모드를 사용하면 클래스 폭발 문제가 해결되지만, 우리가 갈 때 여러분도 알 수 있습니다. 국수를 먹으려면 반찬이 없을 수도 있고, 국수만 있을 수도 있고, 여러 가지 반찬이 필요할 수도 있습니다. 예를 들어 쇠고기 라면 한 그릇과 바삭한 밥 3개, 계란 2개가 필요합니다. 이 요구 사항에는 브리지 모드를 사용할 수 없습니다. 이 문제를 해결하기 위해 또 다른 구조적 디자인 패턴인 데코레이터 패턴을 사용할 수 있습니다.
데코레이션 패턴은 동작이 포함된 특수 캡슐화 개체에 개체를 배치하여 원래 개체에 새로운 동작을 바인딩할 수 있는 구조적 디자인 패턴입니다.
데코레이터 패턴을 이해하려면 인형인 마트료시카 인형
각 인형 세트는 장식용 물건을 추가하는 것과 같습니다. 런타임 시 가장 바깥쪽 장식 개체(외부 레이어 사용)가 실행된 다음 레이어별로 실행됩니다. 지금은 무슨 뜻인지 이해가 안 되실 수도 있겠지만, 다음 내용을 읽어보신 후 이 문장을 다시 읽어보시면 이해가 되실 것 같습니다.
직접 UML 클래스 다이어그램을 그렸는데 좀 보기 흉하네요. 그냥 해보자
코드 구현
abstract class Noodles { abstract function cost (); abstract function desc (); } class BigNoodle extends Noodles { private $cost = 9.0; public function cost() { return $this->cost; } public function desc() { return '大碗拉面'; } } class SmallNoodle extends Noodles { private $cost = 6.0; public function cost() { return $this->cost; } public function desc() { return '小碗拉面'; } } abstract class NoodlesDecorator extends Noodles { } class Beef extends NoodlesDecorator { private $desc = '牛肉'; private $cost = 6.0; protected $noodles = null; public function __construct(Noodles $noodels) { $this->noodles = $noodels; } public function cost () { return $this->cost + $this->noodles->cost(); } public function desc () { return $this->desc . $this->noodles->desc(); } } // egg、curst类代码省略,除了属性值不一样基本和Beef一致
테스트 코드는 다음과 같습니다
$noodles = new BigNoodle(); $beefBigNoodles = new Beef($noodles); $eggBeffBigNoodles = new Egg($beefBigNoodles); echo $eggBeffBigNoodles->desc(); echo $eggBeffBigNoodles->cost() . '元';
결과 출력: 큰 그릇 달걀 쇠고기 라면 16위안
요약
생각해 보세요. 여기서 라면의 양은 왜 데코레이터 개체로 사용되지 않습니까? 생각해 보세요. 큰 그릇과 작은 그릇의 라면을 주문하시겠습니까?
데코레이터 패턴 특징
데코레이터와 데코레이팅된 객체의 슈퍼 유형이 동일합니다.
객체는 하나 이상의 데코레이터로 래핑될 수 있습니다.
객체는 언제든지 데코레이션될 수 있으므로 런타임에 좋아하는 데코레이터를 사용하여 객체를 동적으로 무제한으로 꾸밀 수 있습니다.
위 내용은 데코레이터 패턴은 무엇이며 브릿지 패턴과 어떻게 다른가요?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!