구조 디자인 패턴: 데코레이터 패턴

디자인 패턴 칼럼 디렉토리

창조적인 디자인 패턴 - 싱글톤 패턴/팩토리 패턴/추상적인 팩토리
행동 디자인 패턴: 템플릿 디자인 패턴/옵저버 디자인 패턴/전략 디자인 패턴
구조 디자인 패턴: 데코레이터
모드

디자인 패턴의 분류

디자인 패턴은 생성적 디자인 패턴, 구조적 디자인 패턴 및 행동적 디자인 패턴의 세 가지 유형으로 나눌 수 있습니다.

생성 디자인 패턴: 이러한 패턴에는 단순 팩토리 패턴, 팩토리 메소드 패턴, 추상 팩토리 패턴, 싱글톤 패턴, 빌더 패턴 및 프로토타입 패턴을 포함하는 객체 생성 메커니즘이 포함됩니다.

구조 디자인 패턴: 이러한 패턴에는 어댑터 패턴, 브리지 패턴, 컴포지션 패턴, 데코레이터 패턴, 모양 패턴, 플라이웨이트 패턴 및 프록시 패턴을 포함하여 클래스와 개체의 조합이 포함 됩니다.

동작 디자인 패턴: 이러한 패턴은 책임 패턴, 명령 패턴, 인터프리터 패턴, 반복자 패턴, 중간 패턴, 메모 패턴, 관찰자 ​​패턴 , 상태 패턴, 전략 패턴 , 템플릿 메서드 패턴 및 방문자 패턴을 포함하여 개체 간의 통신 및 상호 작용을 포함합니다.

이 기사는 구조 디자인 패턴에서 데코레이터와 조합 디자인 패턴에 대한 요약입니다. 각 디자인 패턴의 정의는 상대적으로 모호하므로 코드를 직접 보고 이해할 수 있습니다.

디자인 패턴의 디자인 원칙

종속성 역전 : 고수준 모듈은 저수준 모듈에 의존해서는 안 되며 둘 다 추상화에 의존해야 합니다. 추상화는 구체적인 구현에 의존해서는 안 되며 구체적인 구현은 추상화에 의존해야 합니다 .
개방 및 폐쇄 : 클래스는 확장(조합 및 상속)에 개방되고 수정에 폐쇄적이어야 함
인터페이스 지향 : 변수 유형이 특정 구체적인 클래스로 선언되지 않고 인터페이스로 선언됨,
클라이언트 프로그램에서 필요 없음 개체 유형의 세부 사항을 알고 개체의 인터페이스만 알면 됩니다. 시스템 각 부분의 종속성을 줄여 "높은 응집력과 느슨한 결합"의 유형 설계 체계를 실현
합니다. 인터페이스를 노출하고 인터페이스만 호출) .
변경 지점 캡슐화 : 변경 지점에서 안정 지점을 분리, 변경 지점을 확장 및 수정, 안정 지점과 변경 지점의 구현 수준을 분리, 단일 책임: 클래스 는 변경에 대한 이유가 하나만 있어야 합니다 . 즉, 변경점이 너무 많지 않아야 합니다.) . 리스코프 치환 : 서브타입은 부모타입을 대체할 수 있어야 하며, 주로 서브클래스가 부모클래스의 구현을 재정의할 때 발생하며, 원래 부모타입을 사용했던 프로그램에 오류가 있을 수 있음, 부모클래스의 메서드는 커버되지만 부모 클래스의 메서드에 대한 책임이 구현되지 않음 (즉, 하위 클래스는 부모 클래스의 메서드를 재정의할 수 있지만 부모 클래스의 필수 기능은 보장되어야 함 ) 인터페이스 격리 : 클라이언트가 사용하지 않는 메서드에 의존하도록 강요해서는 안 됩니다.일반적으로 더 많은 인터페이스가 있는 클래스를 처리하는 데 사용되며 이러한 인터페이스에는 많은 책임이 수반됩니다.클라이언트는 필요하지 않은 인터페이스에 의존해서는 안 됩니다. 다른 클래스에 대한 클래스의 종속성은 가장 작은 인터페이스를 기반으로 해야 합니다. 상속에 대한 구성






: 상속 결합도가 높음, 구성 결합도가 낮음;

데코레이터 패턴

객체에 일부 추가 책임을 동적으로 추가합니다. 데코레이션은 기능 추가 측면에서 서브클래싱보다 더 유연합니다.

이 디자인 패턴을 설명하기 위해 접시(음식 및 다양한 조미료 포함)의 비용을 계산하는 예를 사용하십시오.

음식점에서는 국수, 각종 조미료 등 음식의 원가를 계산해야 합니다.

#include <iostream>
#include <string>

using namespace std;

// 食品类
class Food {
    
    
protected:
	string des;
	double price;

public:
	virtual double cost() = 0;
	string getDes() {
    
    
		return des;
	}
	void setDes(string des) {
    
    
		this->des = des;
	}
	double getPrice() {
    
    
		return price;
	}
	void setPrice(double price) {
    
    
		this->price = price;
	}
};

// 面条类
class Noodles : public Food {
    
    
public:
	double cost() override {
    
    
		return getPrice();
	}
};

// 中式面条类
class ChineseNoodles : public Noodles {
    
    
public:
	ChineseNoodles() {
    
    
		setDes("中式面条");
		setPrice(25.00);
	}
};

// 装饰器类
class Decorator : public Food {
    
    
protected:
	Food* desFood;

public:
	Decorator(Food* desFood) {
    
    
		this->desFood = desFood;
	}
	double cost() override {
    
    
		cout << desFood->getDes() << "价格:" << desFood->getPrice() << "  配料如下:"
			<< getDes() << "  价格:" << getPrice() << "  总价" << (getPrice() + desFood->cost()) << endl;
		return getPrice() + desFood->cost();
	}
};

// 孜然类
class Cumin : public Decorator {
    
    
public:
	Cumin(Food* desFood) : Decorator(desFood) {
    
    
		setDes("孜然");
		setPrice(2.00);
	}
};
// 胡椒类
class Peper : public Decorator {
    
    
public:
	Peper(Food* desFood) : Decorator(desFood) {
    
    
		setDes("胡椒");
		setPrice(3.00);
	}
};

int main() {
    
    
	// 先定义一个被装饰者,返回对象要为最顶层的对象,这样被装饰者才能接受
	Food* noodles = new ChineseNoodles();
	// 定义一个装饰者对象
	Food* cumin = new Cumin(noodles);
	// 输出为:中式面条价格:25配料如下:孜然价格:2总价27
	cout << "-----------面条+孜然------------------------" << endl;
	cumin->cost();
	cout << "-----------面条+胡椒------------------------" << endl;
	Food* peper = new Peper(noodles);
	peper->cost();
	cout << "-----------面条+胡椒+孜然------------------------" << endl;
	peper = new Peper(cumin);
	cout << "面条+胡椒+孜然价格:" <<peper->cost();

	delete cumin;
	delete noodles;
	delete peper;

	return 0;
}

여기에 이미지 설명 삽입

"noodles + pepper + cumin"의 예에서 데코레이터 클래스의 비용 인쇄가 중첩되어 있으므로 로그 인쇄가 지저분합니다.

여기에 이미지 설명 삽입

구조:

  • Decorated abstract interface (Food): 기본 함수 메서드와 데코레이션 메서드 인터페이스를 제공합니다.
  • 특정 데코레이터(Noodles): 추상 클래스를 상속하고 메서드 인터페이스를 구현합니다.
  • 데코레이터 공개 클래스(Decorator): 통합 데코레이션 방법을 구현합니다.
  • 콘크리트 데코레이터 클래스: 커스텀 데코레이터 속성.

사용 시나리오: 소프트웨어 개발 프로세스에서 일부 기존 구성 요소(정의된 개체)를 사용하려는 경우가 있습니다 . 이러한 구성 요소는 일부 핵심 기능만 수행할 수 있습니다. 그러나 기능은 아키텍처를 변경하지 않고도 동적으로 확장할 수 있습니다 . 그래서 이들은 데코레이터 패턴을 사용하여 모두 구현할 수 있습니다.

특징:

데코레이터 디자인 패턴은 구성 + 상속의 형태로 구현됩니다.

장식계급과 장식계급은 서로 결합되지 않고 독립적으로 발전할 수 있다.

데코레이터 패턴은 상속의 대안으로, 데코레이터 패턴은 구현 클래스의 기능을 동적으로 확장할 수 있습니다.

추천

출처blog.csdn.net/weixin_44477424/article/details/131905486