제 홈페이지의 모든 글은 anti-nhn license에 따릅니다.



자바 디자인 패턴 8 - Decorator

1. Decorator 패턴은..

기존에 구현되어 있는 클래스에 기능을 추가하기 위한 패턴입니다. 기존에 있던 클래스를 상속하여 만들기 때문에 기존 클래스와 사용법이 크게 다르지는 않습니다.

2. 예제

-------------- 데코레이터 -------------
package ch08_Decorator;
public class Decorator {
    public String getMerong(){
        return "merong";
    }
}

-------------- 데코레이터를 상속 받은 넘 ----
package ch08_Decorator;
public class ChildDecorator extends Decorator{
    private Decorator decorator;
    public ChildDecorator(Decorator decorator){
        this.decorator = decorator;
    }
    @Override
    public String getMerong(){
        return "@" + decorator.getMerong() + "@";
    }
}

-------------- 테스트 클래스 --------------
package ch08_Decorator;
public class Test {
    public static void main(String[] args) {
        Decorator decorator = new Decorator();
        System.out.println(decorator.getMerong());
        Decorator child = new ChildDecorator(decorator);
        System.out.println(child.getMerong());
        Decorator child2 = new ChildDecorator(child);
        System.out.println(child2.getMerong());
    }
}
-------------- 결과 -----------------
merong
@merong@
@@merong@@

데코레이터 패턴에서 상위클래스(Decorator라 합니다.) 와 하위 클래스(ConcreteDecorator라 합니다.) 와의 관계를 알아봅시다.
첫째, 하위 클래스는 상위클래스의 형식을 멤버변수로 가집니다. ChildDecorator 는 Decorator를 멤버변수로 받습니다. 일반적으로 생성자의 인자로 받아서 멤버변수로 쎄팅을 합니다. 별도의 setter를 가지는 경우는 거의 없습니다.
둘째, 하위 클래스는 상위클래스를 상속 받아 상위클래스의 메쏘드를 이용합니다. 하위 클래스의 getMerong() 이라는 메쏘드는 상위 클래스의 getMerong()을 오버라이드하지만, 내부적으로 상위클래스의 getMerong()을 사용하고 있습니다.

3. Decorator가 일반적인 상속과 다른 점

Decorator는 메쏘드의 확장 개념입니다. 멤버 변수로 받은 객체의 메쏘드를 이용하여 그 메쏘드를 확장하는 것입니다.

4. JAVA API에 있는 Decorator

java.io에 있는 InputStream, Reader, OutputStream, Writer 등은 모두 Decorator 패턴으로 구성되어 있습니다.
파일을 Reader로 읽는 경우를 살펴보겠습니다.

Reader reader = new FileReader("파일명");

Reader reader = new BufferedReader(new FileReader("파일명");

파일은 위의 두가지 방법으로 모두 읽을 수 있습니다. 둘다 Reader의 형식으로 받습니다. BufferedReader의 생성자는 Reader를 받아 멤버 변수로 가지고 있으며, Reader를 상속 받습니다. 멤버 변수로 받은 Reader를 이용하여, 버퍼를 이용해서 읽습니다.

by 삼실청년 | 2007/10/13 16:44 | 컴터질~ | 트랙백(2) | 핑백(2) | 덧글(8)

트랙백 주소 : http://iilii.egloos.com/tb/3850836
☞ 내 이글루에 이 글과 관련된 글 쓰기 (트랙백 보내기) [도움말]
Tracked from Confluence: .. at 2013/07/05 09:53

제목 : 5주차- 대규모트래픽 분산처리를 위한 자바 서버개발
부제: NIO부터 Netty까지 Introduction 인터넷 사용 인구의 폭발적인 증가와...more

Tracked from Confluence: .. at 2013/11/26 23:18

제목 : 5주차- 대규모트래픽 분산처리를 위한 자바 서버개발
부제: NIO부터 Netty까지 Introduction 인터넷 사용 인구의 폭발적인 증가와...more

Linked at java design patt.. at 2017/05/31 09:26

... 턴 7 – Composite 8. 자바 디자인 패턴 8 – Decorator</A> 9. 자바 디자인 패턴 9 <a href="http://blog.sina.com.cn/s/blog_8e40db350102wt27.html">港股开户 &#8211; Chain of Responsibility 10. 자바 디자인 ... more

Linked at 자바 디자인 패턴 종류 &#8.. at 2017/09/26 09:15

... 바 디자인 패턴 5 – Singleton 6. 자바 디자인 패턴 6 – Strategy 7. 자바 디자인 패턴 7 – Composite 8. 자바 디자인 패턴 8 – Decorator 9. 자바 디자인 패턴 9 &#8211; Chain of Responsibility 10. 자바 디자인 패턴 10 – Facad ... more

Commented by 용식 at 2009/01/14 13:51
오랜만에 글 올려주셨네요 ^^
요즘 헤드퍼스트 디자인 패턴으로 공부하면서 삼실청년님의 포스트를 같이 보고 있습니다.
지금 데코레이터 패턴에 대해 보는 중이라.. 새로 올리신 글에 댓글을 안 올리고..
여기다가 댓글을 올리네요 ㅎㅎ

잘보고 갈게요 ^^
Commented by 삼실청년 at 2009/01/22 10:33
책이 용식님이랑 궁합이 좀 맞나보네요.^^ 궁합 안 맞는 사람들은 욕을 바가지로 퍼부어대는 책인데ㅋㅋ
Commented by 김경모 at 2009/02/06 11:20
데코레이터 패턴에 팩토리 패턴을 적용시켜 소스를 바꿀려고 하니 쉽게 되질 않네요 ^^
삽질끝에 겨우겨우 적용을 했습니다.. ^^ 책보고 소스보고 공부도 도움 많이 되지만 배운걸 직접
적용 해보니 또 새로운걸 배우게 되네요 .. 감사합니당 ^^
오늘도 많이 배우고 갑니다...^^
Commented by 삼실청년 at 2009/02/08 00:59
^^ 공부 열심히 하시나보네요. 제가 휴가 내고 스키장가는 중에 글 남겨주셨군요. 스키장 한번 갔다왔더니 온몸이 뻐근하네요. 즐거운 주말되세요.
Commented by fg at 2013/05/20 12:51
궁금한게 있습니다. 왜 굳이 상위 클래스를 맴버 변수로 갖는 이유가 뭔가요?

상위 클래스를 상속한이상, super.~~ 이렇게 해도 되는건 아닌가요?
Commented by 삼실청년 at 2013/05/21 20:44
그 상위 클래스의 하위 클래스들까지 커버하기 위함 입니다.

public class HeroTest {
interface Hero{
String getName();
}
static class BatMan implements Hero{
public String getName(){ return "batman";}
}
static class SpiderMan implements Hero{
public String getName(){ return "spiderman";}
}
static class SuperHero implements Hero{
private final Hero org;
SuperHero(Hero org){this.org = org;}
public String getName(){ return "super" + org.getName();}
}
public static void main(String[] args) {
Hero batman = new BatMan();
Hero spiderman = new SpiderMan();
Hero superBatman = new SuperHero(batman);
Hero superSpiderman = new SuperHero(spiderman);
System.out.println(superBatman.getName());
System.out.println(superSpiderman.getName());
}
}

위의 코드를 보시면 SuperHero 라는 걸 만들어서, SuperBatman이나 SuperSpiderman 같은 클래스를 만들지 않겠다는 것입니다. Hero 종류가 늘어나도 SuperHero 클래스 하나면 다 커버 가능합니다.
Commented by fg at 2013/05/23 15:40
감사합니다! 중요한걸 놓쳐버렸었군요!

코드까지.... 정말 감사합니다.
Commented by 삼실청년 at 2013/05/28 02:47
^^ 도움이 되셨길 바래요.

:         :

:

비공개 덧글

◀ 이전 페이지          다음 페이지 ▶