문제

나는 프록시 패턴을보고 있었고, 나에게는 데코레이터, 어댑터 및 브리지 패턴과 같은 끔찍한 것 같습니다. 내가 뭔가 오해하고 있습니까? 차이점이 뭐야? 프록시 패턴과 다른 패턴을 사용하는 이유는 무엇입니까? 실제 프로젝트에서 과거에 어떻게 사용 했습니까?

도움이 되었습니까?

해결책

프록시, 데코레이터, 어댑터 및 브리지는 클래스를 "포장"하는 데있어 모두 변형입니다. 그러나 그들의 용도는 다릅니다.

  • 대리 객체를 게으르거나 원격 서비스를 호출하거나 물체에 대한 액세스를 제어한다는 사실을 숨기고 싶을 때 사용할 수 있습니다.

  • 데코레이터 "스마트 프록시"라고도합니다. 이것은 객체에 기능을 추가하려는 경우에 사용되지만 해당 객체의 유형을 확장하는 것은 아닙니다. 이를 통해 런타임에 그렇게 할 수 있습니다.

  • 어댑터 초록 인터페이스가있을 때 사용되며 해당 인터페이스를 비슷한 기능적 역할을하는 다른 객체에 맵핑하려고하지만 다른 인터페이스가 있습니다.

  • 다리 어댑터와 매우 유사하지만 추상 인터페이스와 기본 구현을 모두 정의 할 때 브리지라고합니다. 즉, 일부 레거시 또는 타사 코드에 적응하지 않으면 모든 코드의 디자이너이지만 다른 구현을 교체 할 수 있어야합니다.

  • 정면 하나 이상의 클래스의 하위 시스템에 대한 더 높은 수준 (읽기 : 간단한) 인터페이스입니다. 여러 객체를 나타내는 복잡한 개념이 있다고 가정합니다. 해당 객체 세트를 변경하는 것은 혼란 스럽습니다. 왜냐하면 어떤 객체가 호출 해야하는지 항상 알지 못하기 때문입니다. 그때는 물체 모음에 할 수있는 모든 복잡한 작업에 높은 수준의 방법을 제공하는 외관을 작성해야합니다. 예 : 학교 섹션의 도메인 모델, countStudents(), reportAttendance(), assignSubstituteTeacher(), 등등.

다른 팁

Bill의 답변이 말했듯이, 사용 사례는 다릅니다..

그들의 구조도 마찬가지입니다.

  • 대리 그리고 데코레이터 둘 다 랩핑 된 유형과 동일한 인터페이스를 가지지 만 프록시는 후드 아래에 인스턴스를 생성하는 반면, 데코레이터는 생성자에서 인스턴스를 취합니다.

  • 어댑터 그리고 정면 둘 다 랩하는 것과 다른 인터페이스를 가지고 있습니다. 그러나 어댑터는 기존 인터페이스에서 파생되는 반면 외관은 새로운 인터페이스를 만듭니다.

  • 다리 그리고 어댑터 두 가지 모두 기존 유형을 가리 킵니다. 그러나 다리는 추상 유형을 가리키며 어댑터는 콘크리트 유형을 가리킬 수 있습니다. 브리지를 사용하면 런타임에 구현을 페어링 할 수 있지만 어댑터는 일반적으로 그렇지 않습니다.

제 주제에 대한 내.

네 가지 패턴 모두 공통점이 많으며, 4 개는 모두 비공식적으로 포장지 또는 래퍼 패턴이라고 불립니다. 모든 구성, 래핑 주제 및 어느 시점에서 피험자에 대한 실행을 위임하고 하나의 메소드 호출을 다른 방법으로 매핑합니다. 고객에게 다른 객체를 구성하고 모든 관련 데이터를 복사해야 할 필요성을 절약합니다. 현명하게 사용하면 메모리와 프로세서를 저장합니다.

느슨한 커플 링을 홍보함으로써 안정된 코드가 피할 수없는 변화에 덜 노출되고 동료 개발자에게 더 잘 읽을 수 있습니다.

어댑터

어댑터는 주제 (어댑티)를 다른 인터페이스에 적응시킵니다. 이런 식으로 우리는 명목상 다른 유형의 모음에 객체를 추가 할 수 있습니다.

어댑터는 클라이언트에 관련 방법 만 노출하고 다른 모든 방법을 제한 할 수 있으며 외부 라이브러리 적응과 같은 특정 상황에 대한 사용 의도를 드러내면서 덜 일반적인 것처럼 보이고 응용 프로그램 요구에 더 집중합니다. 어댑터는 우리 코드의 가독성과 자체 설명을 증가시킵니다.

어댑터는 다른 팀의 휘발성 코드에서 한 팀을 보호합니다. 해외 팀을 다룰 때 생명 구세주 도구 ;-)

덜 언급 된 목적은 주제 클래스가 과도한 주석을 방지하는 것을 방지합니다. 주석을 기반으로 한 많은 프레임 워크가 있으면 그 어느 때보 다 더 중요한 사용법이됩니다.

어댑터는 단일 상속의 Java 제한을 해결하는 데 도움이됩니다. 하나의 봉투 아래에 여러 적응을 결합하여 여러 상속에 대한 인상을 줄 수 있습니다.

코드 현명한 어댑터는 "얇습니다". 적응기 방법을 호출하는 것 외에도 적응기 클래스에 많은 코드를 추가해서는 안됩니다.

JDK 또는 기본 라이브러리에는 좋은 어댑터 예제가 많지 않습니다. 애플리케이션 개발자는 어댑터를 생성하고 애플리케이션 특정 인터페이스에 라이브러리를 조정합니다.

데코레이터

데코레이터는 위임 할뿐만 아니라 하나의 방법을 다른 방법에지도 할뿐만 아니라 더 많은 방법을, 일부 주제 방법의 동작을 수정하고, 주제 방법을 전혀 호출하지 않고, 다른 객체, 도우미 대상으로 위임 할 수 있습니다.

데코레이터는 일반적으로 로깅, 암호화, 서식 또는 피험자와 같은 포장 된 객체에 (투명하게) 기능을 추가합니다. 이 새로운 기능은 많은 새로운 코드를 가져올 수 있습니다. 따라서 데코레이터는 일반적으로 어댑터보다 훨씬 "더 뚱뚱합니다"입니다.

데코레이터는 피험자 인터페이스의 하위 클래스 여야합니다. 주제 대신 투명하게 사용할 수 있습니다. BufferedOutputStream을 참조하십시오. 여전히 출력 스트림이므로 사용될 수 있습니다. 이는 어댑터와의 주요 기술적 차이입니다.

전체 데코레이터 가족의 교과서 예는 JDK -The Java IO에 쉽게 있습니다. 모든 클래스가 좋아요 BufferedOutputStream, FilterOutputStream 그리고 ObjectOutputStream 데코레이터입니다 출력 스트림. 그들은 하나의 데코레이터가 다시 장식되어 더 많은 기능을 추가하는 양파 층일 수 있습니다.

대리

프록시는 전형적인 래퍼가 아닙니다. 프록시 피험자 인 프록시 피험자 인 포장 된 물체는 아직 프록시 생성시 존재하지 않을 수 있습니다. 프록시는 종종 내부적으로 그것을 만듭니다. 주문시로 생성 된 무거운 오브젝트 일 수도 있고 다른 JVM 또는 다른 네트워크 노드의 원격 개체 및 기본 코드의 구성 요소 인 비자바 객체도 원격 객체입니다. 다른 객체를 전혀 랩하거나 위임 할 필요는 없습니다.

가장 일반적인 예제는 원격 프록시, 무거운 객체 이니셜 라이저 및 액세스 프록시입니다.

  • 원격 프록시 - 주제는 원격 서버, 다른 JVM 또는 비 Java 시스템에 있습니다. 프록시는 메소드 호출을 RMI/REST/SOAP 통화 또는 필요한 모든 것을 번역하여 클라이언트가 기본 기술에 노출되는 것을 보호합니다.

  • 게으른 부하 프록시 - 첫 번째 사용량 또는 첫 번째 집중 사용 만 객체를 완전히 초기화하십시오.

  • 액세스 프록시 - 피험자에 대한 제어 액세스.

정면

외관은 최소 지식의 설계 원칙 (Demeter of Demeter)과 밀접한 관련이 있습니다. 외관은 어댑터와 매우 유사합니다. 둘 다 포장하고 둘 다 한 개체를 다른 물체에 맵핑하지만 의도는 다릅니다. 외관은 피사체, 복잡한 물체 그래프의 복잡한 구조를 평평하게하여 복잡한 구조에 대한 접근을 단순화합니다.

외관은 복잡한 구조를 감싸서 평평한 인터페이스를 제공합니다. 이것은 클라이언트 객체가 피험자 구조에서 내부 관계에 노출되는 것을 방지하여 느슨한 커플 링을 촉진합니다.

다리

구현뿐만 아니라 추상화가 다를 때의 더 복잡한 어댑터 패턴 변형. 대표단에 간접 간의 하나를 더 추가합니다. 추가 대표단은 다리입니다. 인터페이스를 조정하여 어댑터를 분리합니다. 다른 포장 패턴보다 복잡성이 증가하므로주의해서 적용하십시오.

생성자의 차이

생성자를 볼 때 패턴 차이도 분명합니다.

  • 대리 기존 객체를 감싸지 않습니다. 생성자에는 주제가 없습니다.

  • 데코레이터 그리고 어댑터 이미 기존 객체를 랩핑하는 것입니다. 일반적으로
    생성자에 제공됩니다.

  • 정면 생성자는 전체 객체 그래프의 루트 요소를 가져옵니다. 그렇지 않으면 어댑터와 동일하게 보입니다.

실제 예제 - JAXB 마샬링 어댑터. 이 어댑터의 목적은 간단한 플랫 클래스를 외부 적으로 필요한보다 복잡한 구조로 매핑하고 과도한 주석으로 "오염"주제 클래스를 방지하는 것입니다.

많은 GOF 패턴에는 많은 중복이 있습니다. 그것들은 모두 다형성의 힘에 기반을두고 때로는 의도가 실제로 다릅니다. (전략 대 주)

읽기 후 패턴에 대한 나의 이해는 100 배 증가했습니다 첫 번째 디자인 패턴을 헤드하십시오.

나는 그것을 강력히 추천합니다!

전문가의 모든 좋은 답변은 이미 각 패턴이 무엇을 의미하는지 설명했습니다.

그럴게요 장식 키 포인트.

데코레이터 :

  1. 실행 시간에 객체에 동작을 추가하십시오. 상속은이 기능을 달성하는 핵심이며,이 기능은이 패턴의 장점과 단점입니다.
  2. 그것은 수정합니다 행동 인터페이스의.

예 : (체인 링) : java.io 관련 패키지 클래스 InputStream & OutputStream 인터페이스

FileOutputStream fos1 = new FileOutputStream("data1.txt");  
ObjectOutputStream out1 = new ObjectOutputStream(fos1);

대리:

  1. 게으른 초기화, 객체를 캐싱하고 클라이언트/발신자에 대한 액세스를 제어하여 성능 향상에 사용하십시오.. 대체 행동을 제공하거나 실제 대상을 호출 할 수 있습니다. 이 과정에서 새 객체를 만들 수 있습니다.
  2. 같지 않은 데코레이터, 객체의 체인, 프록시를 허용합니다 체인을 허용하지 않습니다.

예 : java.rmi 패키지 수업.

어댑터:

  1. 두 개의 관련없는 인터페이스가 다른 개체를 통해 함께 작동 할 수 있습니다., 아마도 같은 역할을 수행 할 수 있습니다.
  2. 원래 인터페이스를 수정합니다.

예를 들어 java.io.InputStreamReader (InputStream 반환 a Reader)

다리:

  1. 추상화와 구현이 독립적으로 다를 수 있습니다.
  2. 사용합니다 상속에 대한 구성.

예를 들어 수집 수업 java.util. List 구현 ArrayList.

키 노트 :

  1. 어댑터 주제에 대한 다른 인터페이스를 제공합니다. 대리 동일한 인터페이스를 제공합니다. 데코레이터 향상된 인터페이스를 제공합니다.
  2. 어댑터 객체의 인터페이스를 변경하고 데코레이터 물체의 책임을 향상시킵니다.
  3. 데코레이터 그리고 대리 목적이 다르지만 비슷한 구조가 있습니다
  4. 어댑터 그들이 설계된 후에 일을 작동시킵니다. 다리 그들이 있기 전에 일을하게합니다.
  5. 다리 추상화와 구현이 독립적으로 다양하도록 선형으로 설계되었습니다. 어댑터 관련없는 수업이 함께 작동하도록 개조됩니다
  6. 데코레이터 서브 클래싱없이 객체에 책임을 추가 할 수 있도록 설계되었습니다.

다양한 디자인 패턴의 예와 관련하여 Great SE 질문/기사를 살펴보십시오.

데코레이터 패턴을 언제 사용해야합니까?

브리지 패턴은 언제 사용합니까? 어댑터 패턴과 어떻게 다른가요?

프록시와 데코레이터 패턴의 차이점

그것들은 상당히 비슷하며 그들 사이의 선은 상당히 회색입니다. 나는 당신이 읽는 것이 좋습니다 프록시 패턴 그리고 데코레이터 패턴 C2 Wiki의 출품작.

항목과 토론에는 상당히 광범위하며 다른 관련 기사와도 연결됩니다. 그건 그렇고, C2 Wiki는 다른 패턴 사이의 뉘앙스에 대해 궁금해 할 때 우수합니다.

C2 항목을 요약하면, 데코레이터가 동작을 추가/변경한다고 말하지만 프록시는 액세스 제어 (게으른 인스턴스화, 원격 액세스, 보안 등)와 더 관련이 있습니다. 그러나 내가 말했듯이, 그들 사이의 선은 회색이며, 나는 장식 자로 쉽게 볼 수 있고 그 반대의 프록시에 대한 참조를 봅니다.

이것은 인용입니다첫 번째 디자인 패턴을 헤드하십시오

정의는 책에 속합니다. 예는 나에게 속한다.

데코레이터 - 인터페이스를 변경하지는 않지만 책임이 추가됩니다. 자동차 인터페이스가 있다고 가정합니다. 자동차 모델 (S, SV, SL)의 다른 모델에 대해이를 구현할 때 더 많은 책임을 더하십시오 일부 모델의 경우. 선 루프, 에어백 등이 있습니다 ..

어댑터 - 한 인터페이스를 다른 인터페이스로 변환합니다. 당신은 자동차 인터페이스가 있고 지프처럼 행동하기를 원합니다. 그래서 당신은 차를 가져 가서 수정하고 지프로 변합니다. 진짜 지프가 아니기 때문에. 그러나 지프처럼 행동합니다.

정면 - 인터페이스를 더 간단하게 만듭니다. 자동차, 비행기, 선박 인터페이스가 있다고 가정하십시오. 실제로 필요한 것은 한 곳에서 다른 위치로 사람들을 보내는 수업입니다. 당신은 외관이 어떤 차량을 사용할 것인지 결정하기를 원합니다. 그런 다음 모든 것을 수집합니다 인터페이스 참조 1 개의 우산 아래에서 간단하게 유지하기 위해 결정/위임하십시오.

먼저 헤드 : "외관은 인터페이스를 단순화 할뿐만 아니라 구성 요소의 하위 시스템에서 클라이언트를 분리합니다. 외관과 어댑터는 여러 클래스를 감싸 수 있지만, 외관의 의도는 단순화하는 것이지만 어댑터는 인터페이스를 다른 것으로 변환하는 것입니다. "

네 가지 패턴은 모두 외부 객체/클래스를 외부로 포장하는 것이 포함되므로 구조적으로 매우 유사합니다. 나는 목적에 따라 차이를 설명 할 것이다.

  • 대리 외부에서 내부에서 액세스를 캡슐화합니다.
  • 데코레이터 외부로 내부의 행동을 수정하거나 확장합니다.
  • 어댑터 인터페이스를 내부에서 외부로 변환합니다.
  • 다리 변수 또는 플랫폼 의존적 부분 (내부)과 동작 (외부)의 변함없는 부분을 분리합니다.

내부와 외부 물체 사이의 인터페이스 변동에 의해 :

  • 안에 대리 인터페이스는 동일합니다.
  • 안에 데코레이터 인터페이스는 동일합니다.
  • 안에 어댑터 인터페이스는 공식적으로 다르지만 동일한 목적을 충족시킵니다.
  • 안에 다리 인터페이스는 개념적으로 다릅니다.

웹 서비스를 소비 할 때 자주 사용합니다. 프록시 패턴은 아마도 '래퍼 패턴'과 같이 더 실용적으로 이름을 바꿔야 할 것입니다. 또한 MS Excel의 프록시 인 라이브러리가 있습니다. 버전이 설치됩니다 (있는 경우).

말하기 세부 사항 구현, 프록시와 데코레이터, 어댑터, 외관 사이의 차이를 발견합니다. 이러한 패턴의 일반적인 구현에는 둘러싸는 객체가 감싸는 대상 객체가 있습니다. 클라이언트는 대상 객체 대신 객체를 둘러싸고 있습니다. 대상 객체는 실제로 객체를 둘러싸는 몇 가지 방법 내부에서 중요한 부분을 재생합니다.

그러나 프록시의 경우 객체를 동봉 할 수있는 경우 일부 메소드 자체를 재생할 수 있습니다. 클라이언트가 대상 객체가 필요로하는 일부 메소드를 호출 할 때 대상 객체를 초기화합니다. 이는 게으른 초기화입니다. 다른 패턴의 경우, 객체를 둘러싸는 것은 사실상 대상 객체를 기반으로합니다. 따라서 대상 객체는 생성자/세터의 객체를 둘러싸는 것과 함께 항상 초기화됩니다.

또 다른 것은 프록시는 대상이하는 일을 정확하게 수행하는 반면 다른 패턴은 타겟팅에 더 많은 기능을 추가합니다.

Bill Karwing Answer (훌륭한 BTW)에 예제를 추가하고 싶습니다. 구현의 몇 가지 주요 차이점을 추가하여 누락되었다고 생각합니다.

인용 된 부분은 [https://stackoverflow.com/a/350471/1984346 (Bill Karwing)

프록시, 데코레이터, 어댑터 및 브리지는 클래스를 "포장"하는 데있어 모두 변형입니다. 그러나 그들의 용도는 다릅니다.

  • 대리 객체를 게으르거나 원격 서비스를 호출하거나 물체에 대한 액세스를 제어한다는 사실을 숨기고 싶을 때 사용할 수 있습니다.

프록시 된 프록시 클래스 및 객체 클래스는 동일한 인터페이스를 구현해야하므로 교환 가능합니다.

예 - 프록시 비싼 물체

class ProxyHumanGenome implements GenomeInterface  {
    private $humanGenome = NULL; 

    // humanGenome class is not instantiated at construct time
    function __construct() {
    }

    function getGenomeCount() {
        if (NULL == $this->humanGenome) {
            $this->instantiateGenomeClass(); 
        }
        return $this->humanGenome->getGenomeCount();
    }
} 
class HumanGenome implement GenomeInterface { ... }
  • 데코레이터 "스마트 프록시"라고도합니다. 이것은 객체에 기능을 추가하려는 경우에 사용되지만 해당 객체의 유형을 확장하는 것은 아닙니다. 이를 통해 런타임에 그렇게 할 수 있습니다.

DecoratorClass는 ObjectClass의 확장 된 인터페이스를 구현해야합니다. 따라서 ObjectClass는 DecoratorClass로 대체 될 수 있지만 그 반대는 아닙니다.

예 - 추가 기능 추가

class DecoratorHumanGenome implements CheckGenomeInterface  {

    // ... same code as previous example

    // added functionality
    public function isComplete() {
        $this->humanGenome->getCount >= 21000
    }
}

interface CheckGenomeInterface extends GenomeInterface {

    public function isComplete();

}

class HumanGenome implement GenomeInterface { ... }
  • 어댑터 초록 인터페이스가있을 때 사용되며 해당 인터페이스를 비슷한 기능적 역할을하는 다른 객체에 맵핑하려고하지만 다른 인터페이스가 있습니다.

이판 차이 프록시, 데코레이터, 어댑터

어댑터는 주제에 대한 다른 인터페이스를 제공합니다. 프록시는 동일한 인터페이스를 제공합니다. 데코레이터는 향상된 인터페이스를 제공합니다.

  • 다리 어댑터와 매우 유사하지만 추상 인터페이스와 기본 구현을 모두 정의 할 때 브리지라고합니다. 즉, 일부 레거시 또는 타사 코드에 적응하지 않으면 모든 코드의 디자이너이지만 다른 구현을 교체 할 수 있어야합니다.

  • 정면 하나 이상의 클래스의 하위 시스템에 대한 더 높은 수준 (읽기 : 간단한) 인터페이스입니다. 여러 객체를 나타내는 복잡한 개념이 있다고 가정합니다. 해당 객체 세트를 변경하는 것은 혼란 스럽습니다. 왜냐하면 어떤 객체가 호출 해야하는지 항상 알지 못하기 때문입니다. 그때는 물체 모음에 할 수있는 모든 복잡한 작업에 높은 수준의 방법을 제공하는 외관을 작성해야합니다. 예 : 학교 섹션의 도메인 모델, countStudents(), reportAttendance(), assignSubstituteTeacher(), 등등.

이 답변의 대부분의 정보는 https://sourcemaking.com/design_patterns, 나는 내가 추천한다 우수한 자원 디자인 패턴의 경우.

나는 코드가 명확한 아이디어를 줄 것이라고 믿는다 (다른 사람들의 대답을 보완하기 위해). 아래를 참조하십시오 (클래스가 구현하고 랩하는 유형에 초점을 맞추십시오)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace TestConsole
{
    class Program
    {
        static void Main(string[] args)
        {
            /* Proxy */

            Console.WriteLine(Environment.NewLine);
            Console.WriteLine("PROXY");
            Console.WriteLine(Environment.NewLine);

            //instead of creating here create using a factory method, the facory method will return the proxy
            IReal realProxy = new RealProxy();
            Console.WriteLine("calling do work with the proxy object ");
            realProxy.DoWork();

            Console.WriteLine(Environment.NewLine);
            Console.WriteLine("ADAPTER");
            Console.WriteLine(Environment.NewLine);

            /*Adapter*/
            IInHand objectIHave = new InHand();
            Api myApi = new Api();
            //myApi.SomeApi(objectIHave); /*I cant do this, use a adapter then */
            IActual myAdaptedObject = new ActualAdapterForInHand(objectIHave);
            Console.WriteLine("calling api with  my adapted obj");
            myApi.SomeApi(myAdaptedObject);


            Console.WriteLine(Environment.NewLine);
            Console.WriteLine("DECORATOR");
            Console.WriteLine(Environment.NewLine);

            /*Decorator*/
            IReady maleReady = new Male();
            Console.WriteLine("now male is going to get ready himself");
            maleReady.GetReady();

            Console.WriteLine(Environment.NewLine);

            IReady femaleReady = new Female();
            Console.WriteLine("now female is going to get ready her self");
            femaleReady.GetReady();

            Console.WriteLine(Environment.NewLine);

            IReady maleReadyByBeautician = new Beautician(maleReady);
            Console.WriteLine("now male is going to get ready by beautician");
            maleReadyByBeautician.GetReady();

            Console.WriteLine(Environment.NewLine);

            IReady femaleReadyByBeautician = new Beautician(femaleReady);
            Console.WriteLine("now female is going to get ready by beautician");
            femaleReadyByBeautician.GetReady();

            Console.WriteLine(Environment.NewLine);

            Console.ReadLine();


        }
    }

    /*Proxy*/

    public interface IReal
    {
        void DoWork();
    }

    public class Real : IReal
    {
        public void DoWork()
        {
            Console.WriteLine("real is doing work ");
        }
    }


    public class RealProxy : IReal
    {
        IReal real = new Real();

        public void DoWork()
        {
            real.DoWork();
        }
    }

    /*Adapter*/

    public interface IActual
    {
        void DoWork();
    }

    public class Api
    {
        public void SomeApi(IActual actual)
        {
            actual.DoWork();
        }
    }

    public interface IInHand
    {
        void DoWorkDifferently();
    }

    public class InHand : IInHand
    {
        public void DoWorkDifferently()
        {
            Console.WriteLine("doing work slightly different ");
        }
    }

    public class ActualAdapterForInHand : IActual
    {
        IInHand hand = null;

        public ActualAdapterForInHand()
        {
            hand = new InHand();
        }

        public ActualAdapterForInHand(IInHand hnd)
        {
            hand = hnd;
        }

        public void DoWork()
        {
            hand.DoWorkDifferently();
        }
    }

    /*Decorator*/

    public interface IReady
    {
        void GetReady();
    }

    public class Male : IReady
    {
        public void GetReady()
        {
            Console.WriteLine("Taking bath.. ");
            Console.WriteLine("Dress up....");
        }
    }

    public class Female : IReady
    {
        public void GetReady()
        {
            Console.WriteLine("Taking bath.. ");
            Console.WriteLine("Dress up....");
            Console.WriteLine("Make up....");
        }
    }

    //this is a decorator
    public class Beautician : IReady
    {
        IReady ready = null;

        public Beautician(IReady rdy)
        {
            ready = rdy;
        }

        public void GetReady()
        {
            ready.GetReady();
            Console.WriteLine("Style hair ");

            if (ready is Female)
            {
                for (int i = 1; i <= 10; i++)
                {
                    Console.WriteLine("doing ready process " + i);
                }

            }
        }
    }

}

디자인 패턴은 수학이 아니며 예술과 소프트웨어 엔지니어링의 조합입니다. 이 요구 사항에는 프록시, 브리지 등을 사용해야하는 것과 같은 것은 없습니다. 설계 패턴은 문제를 해결하기 위해 만들어집니다. 디자인 문제를 예상하면 사용하십시오. 경험을 바탕으로, 당신은 어떤 패턴을 사용하는 특정 문제에 대해 알게 될 것입니다. 견고한 디자인 원칙에 능숙하다면 패턴이라는 것을 알지 못하고 디자인 패턴을 구현했을 것입니다. 일반적인 예는 statergy 및 공장 패턴입니다

따라서 견고한 desighn 원칙, 청정 코딩 원칙 및 TTD에 더 집중합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top