>  기사  >  백엔드 개발  >  데코레이터 패턴은 무엇이며 브릿지 패턴과 어떻게 다른가요?

데코레이터 패턴은 무엇이며 브릿지 패턴과 어떻게 다른가요?

齐天大圣
齐天大圣원래의
2020-08-05 08:57:482824검색

라면 이야기

라면집에서는 라면을 작은 그릇과 큰 그릇으로 나누어서 팔고 있어요. 게다가 쇠고기를 추가하면 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 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.