Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
Tags
- 처음 만나는 AI수학 with Python
- 서버설정
- 처음 만나는 AI 수학 with Python
- 자바편
- 선형대수
- network configuration
- 티스토리 쿠키 삭제
- 이터레이터
- Kernighan의 C언어 프로그래밍
- 구멍가게코딩단
- 목록처리
- d
- 리눅스
- baeldung
- 코드로배우는스프링웹프로젝트
- 네트워크 설정
- 스프링 시큐리티
- ㅒ
- 친절한SQL튜닝
- 데비안
- 페이징
- 코드로배우는스프링부트웹프로젝트
- 자료구조와함께배우는알고리즘입문
- /etc/network/interfaces
- GIT
- 알파회계
- 스프링부트핵심가이드
- iterator
- 자료구조와 함께 배우는 알고리즘 입문
- resttemplate
Archives
- Today
- Total
bright jazz music
Compound Pattern: 2. Decorator 패턴 추가 본문
Design Pattern/Compound Pattern
Compound Pattern: 2. Decorator 패턴 추가
bright jazz music 2022. 10. 14. 22:32갑자기 오리가 소리낸 횟수를 세는 기능을 오리 클래스 수정 없이 추가하고 싶어졌다.
이 때 데코레이터 패턴을 사용할 수 있다.
데코레이터 패턴은 기존 기능의 수정 없이 새로운 기능을 추가하고 싶을 때 사용할 수 있다. 사실상 어댑터 패턴과 유사하다. 어댑터 패턴은 호환에 좀 더 중점을 준다는 점이 다른 것 같다.
데코레이터 패턴은 데코레이터 클래스를 만들어서 기존 객체들을 데코레이터로 감싸면 된다. 이렇게 하면 Duck코드는 건드리지 않아도 된다.
1. 데코레이터 생성
//QuackCountingDecorator.java
package com.example.designpatternstudy.compoundPattern;
//데코레이터. 어댑터와 마찬가지로 타겟 인터페이스 구현 필요
public class QuackCountingDecorator implements QuackableInterfaceForCompoundPattern {
//감싸고자 하는 객체의 레퍼런스를 저장하는 인스턴스 변수 필요
QuackableInterfaceForCompoundPattern duck;
static int numberOfQuacks;
//생성자: 생성자에서 감싸고 있는 타겟 인터페이스의 레퍼런스를 가져온다.
public QuackCountingDecorator(QuackableInterfaceForCompoundPattern duck){
this.duck = duck;
}
@Override
public void quack() {//호출 시 내부의 객체에게 동작을 위임.
duck.quack();
numberOfQuacks++;
}
public static int getQuacks(){
return numberOfQuacks;
}
}
2. 시뮬레이터에 데코레이터 패턴 사용
//DuckSimulator.java
package com.example.designpatternstudy.compoundPattern;
public class DuckSimulator {
public static void initDuckSimul(){
DuckSimulator simulator = new DuckSimulator();
simulator.simulate();
}
void simulateAll(){
//인터페이스를 새로 생성할 때마다 새로운 데코레이터로 감싼다.
QuackableInterfaceForCompoundPattern mallardDuck
= new QuackCountingDecorator(new MallardDuck());
QuackableInterfaceForCompoundPattern redheadDuck
= new QuackCountingDecorator(new RedheadDuck());
QuackableInterfaceForCompoundPattern duckCall
= new QuackCountingDecorator(new DuckCall());
QuackableInterfaceForCompoundPattern rubberDuck
= new QuackCountingDecorator(new RubberDuck());
//GooseAdapter를 사용해서 오리가 됨
QuackableInterfaceForCompoundPattern gooseDuck = new GooseAdapter(new Goose());
//GooseAdapter오리도 데코레이터 사용
QuackableInterfaceForCompoundPattern gooseDuckDeco
= new QuackCountingDecorator(new GooseAdapter(new Goose()));
System.out.println("\n오리 시뮬레이션 게임 (+ 데코레이터)");
simulate(mallardDuck); //1
simulate(redheadDuck); //2
simulate(duckCall); //3
simulate(rubberDuck); //4
//거위 시뮬레이트트
simulate(gooseDuck);
simulate(gooseDuckDeco);//5
System.out.println("오리가 소리 낸 횟수:" +
QuackCountingDecorator.getQuacks() + " 번");
}
//데코레이터도 QuackableInterfaceForCompoundPattern 인터페이스이다.
void simulate(QuackableInterfaceForCompoundPattern duck){
duck.quack();
}
}
3. 테스트
package com.example.designpatternstudy;
import com.example.designpatternstudy.compoundPattern.DuckSimulator;
import org.junit.jupiter.api.Test;
public class CompoundPatternTests {
@Test
public void duckSimulTest(){
// DuckSimulator duckSimulator = new DuckSimulator();
// duckSimulator.initDuckSimul();
// 이렇게 했더니 아래와 같은 경고 발생
// Static member 'com.example.designpatternstudy.compoundPattern.DuckSimulator.initDuckSimul()' accessed via instance reference
// Inspection info: Reports references to static methods and fields via a class instance rather than the class itself.
// Even though referring to static members via instance variables is allowed by The Java Language Specification, this makes the code confusing as the reader may think that the result of the method depends on the instance.
// The quick-fix replaces the instance variable with the class name.
// Example:
// String s1 = s.valueOf(0);
// After the quick-fix is applied:
// String s = String.valueOf(0);
// 클래스의 인스턴스를 통해 static 멤버(여기서는 initDuciSimul())에 접근하는 것도 가능하다. 그러나 이는 코드를 헷갈리게 만든다.
// 독자는 해당 메소드의 결과가 객체에 의존적이라고 생각할 수도 있다.
// ==> 해당 멤버가 static이라면 객체 생성하여 접근할 필요 없이 그냥 클래스로 접근하라는 뜻.
DuckSimulator.initDuckSimul();
//오리 시뮬레이션 게임 (+ 데코레이터)
//꽥꽥
//꽥꽥
//꽉꽉
//삑삑
//끽끽
//끽끽
//오리가 소리 낸 횟수:5 번
}
}
// 6번 출력되었지만 집계는 5번이 된다. 왜냐하면 gooseDuck는 데코레이터로 감싸지 않은 객체이기 때문이다.
// 반면 gooseDuckDeco는 어댑터로 감싼 Goose클래스를 다시 한 번 데코레이터로 감쌌기 때문에 집계되었다.
'Design Pattern > Compound Pattern' 카테고리의 다른 글
Compound Pattern: 6. 지금까지의 내용 리뷰 (0) | 2022.11.05 |
---|---|
Compound Pattern: 5. Observer 패턴 (0) | 2022.11.03 |
Compound Pattern: 4. Composite 패턴 + Iterator패턴 (0) | 2022.10.31 |
Compound Pattern: 3. Factory 패턴 (0) | 2022.10.15 |
Compound Pattern: 1. Adapter패턴 (0) | 2022.10.14 |
Comments