데코레이터 패턴: 두 판 사이의 차이
보이기
내용 삭제됨 내용 추가됨
잔글 {{토막글|전산학}} |
잔글 봇: 같이 보기 문단 추가 |
||
(사용자 17명의 중간 판 24개는 보이지 않습니다) | |||
1번째 줄: | 1번째 줄: | ||
{{위키데이터 속성 추적}} |
|||
'''데코레이터 패턴'''(Decorator pattern)이란 주어진 상황 및 용도에 따라 어떤 객체에 책임을 덧붙이는 패턴으로, 기능 확장이 필요할 때 서브클래싱 대신 쓸 수 있는 유연한 대안이 될 수 있다. |
'''데코레이터 패턴'''(Decorator pattern)이란 주어진 상황 및 용도에 따라 어떤 객체에 책임을 덧붙이는 패턴으로, 기능 확장이 필요할 때 서브클래싱 대신 쓸 수 있는 유연한 대안이 될 수 있다. |
||
== 예 == |
== 예 == |
||
=== 자바 === |
=== 자바 === |
||
<syntaxhighlight lang="java"> |
|||
{{-}} |
|||
<source lang="java"> |
|||
// the Window interface |
// the Window interface |
||
interface Window { |
interface Window { |
||
10번째 줄: | 10번째 줄: | ||
public String getDescription(); // returns a description of the Window |
public String getDescription(); // returns a description of the Window |
||
} |
} |
||
// implementation of a simple Window without any scrollbars |
// implementation of a simple Window without any scrollbars |
||
22번째 줄: | 21번째 줄: | ||
} |
} |
||
} |
} |
||
</syntaxhighlight> |
|||
</source> |
|||
아래의 클래스들은 모든 < |
아래의 클래스들은 모든 <code>Window</code> 클래스들의 데코레이터를 포함하고 있다. |
||
< |
<syntaxhighlight lang="java"> |
||
// abstract decorator class - note that it implements Window |
// abstract decorator class - note that it implements Window |
||
abstract class WindowDecorator implements Window { |
abstract class WindowDecorator implements Window { |
||
35번째 줄: | 34번째 줄: | ||
} |
} |
||
} |
} |
||
// the first concrete decorator which adds vertical scrollbar functionality |
// the first concrete decorator which adds vertical scrollbar functionality |
||
42번째 줄: | 40번째 줄: | ||
super(decoratedWindow); |
super(decoratedWindow); |
||
} |
} |
||
public void draw() { |
public void draw() { |
||
drawVerticalScrollBar(); |
drawVerticalScrollBar(); |
||
56번째 줄: | 54번째 줄: | ||
} |
} |
||
} |
} |
||
// the second concrete decorator which adds horizontal scrollbar functionality |
// the second concrete decorator which adds horizontal scrollbar functionality |
||
77번째 줄: | 74번째 줄: | ||
} |
} |
||
} |
} |
||
</syntaxhighlight> |
|||
</source> |
|||
< |
<code>Window</code> 인스턴스를 만드는 테스트 프로그램은 아래와 같다. |
||
< |
<syntaxhighlight lang="java"> |
||
public class DecoratedWindowTest { |
public class DecoratedWindowTest { |
||
public static void main(String[] args) { |
public static void main(String[] args) { |
||
91번째 줄: | 88번째 줄: | ||
} |
} |
||
} |
} |
||
</syntaxhighlight> |
|||
</source> |
|||
=== C++ === |
=== C++ === |
||
< |
<syntaxhighlight lang="cpp"> |
||
#include <iostream> |
#include <iostream> |
||
103번째 줄: | 100번째 줄: | ||
class Widget { |
class Widget { |
||
public: |
public: |
||
virtual void draw() = 0; |
virtual void draw() = 0; |
||
virtual ~Widget() {} |
virtual ~Widget() {} |
||
}; |
}; |
||
/* ConcreteComponent */ |
/* ConcreteComponent */ |
||
class TextField : public Widget { |
class TextField : public Widget { |
||
private: |
private: |
||
int width, height; |
int width, height; |
||
public: |
public: |
||
TextField( int w, int h ){ |
TextField( int w, int h ){ |
||
width = w; |
width = w; |
||
height = h; |
height = h; |
||
} |
} |
||
void draw() { |
void draw() { |
||
cout << "TextField: " << width << ", " << height << '\n'; |
cout << "TextField: " << width << ", " << height << '\n'; |
||
} |
} |
||
}; |
}; |
||
/* Decorator (interface) */ |
/* Decorator (interface) */ |
||
class Decorator : public Widget { |
class Decorator : public Widget { |
||
private: |
private: |
||
Widget* wid; // reference to Widget |
Widget* wid; // reference to Widget |
||
public: |
public: |
||
Decorator( Widget* w ) { |
Decorator( Widget* w ) { |
||
wid = w; |
wid = w; |
||
} |
} |
||
void draw() { |
void draw() { |
||
wid->draw(); |
wid->draw(); |
||
} |
} |
||
146번째 줄: | 143번째 줄: | ||
/* ConcreteDecoratorA */ |
/* ConcreteDecoratorA */ |
||
class BorderDecorator : public Decorator { |
class BorderDecorator : public Decorator { |
||
public: |
public: |
||
BorderDecorator( Widget* w ) : Decorator( w ) { } |
BorderDecorator( Widget* w ) : Decorator( w ) { } |
||
void draw() { |
void draw() { |
||
Decorator::draw(); |
Decorator::draw(); |
||
cout << " BorderDecorator" << '\n'; |
cout << " BorderDecorator" << '\n'; |
||
} |
} |
||
}; |
}; |
||
/* ConcreteDecoratorB */ |
/* ConcreteDecoratorB */ |
||
class ScrollDecorator : public Decorator { |
class ScrollDecorator : public Decorator { |
||
public: |
public: |
||
ScrollDecorator( Widget* w ) : Decorator( w ) { } |
ScrollDecorator( Widget* w ) : Decorator( w ) { } |
||
void draw() { |
void draw() { |
||
Decorator::draw(); |
Decorator::draw(); |
||
cout << " ScrollDecorator" << '\n'; |
cout << " ScrollDecorator" << '\n'; |
||
} |
} |
||
}; |
}; |
||
int main( void ) { |
int main( void ) { |
||
Widget* aWidget = new BorderDecorator( |
Widget* aWidget = new BorderDecorator( |
||
new ScrollDecorator( |
new ScrollDecorator( |
||
175번째 줄: | 172번째 줄: | ||
} |
} |
||
</syntaxhighlight> |
|||
</source> |
|||
=== C# === |
|||
<source lang="csharp"> |
|||
namespace GSL_Decorator_pattern |
|||
{ |
|||
interface IWindowObject |
|||
{ |
|||
void draw(); // draws the object |
|||
String getDescription(); // returns a description of the object |
|||
} |
|||
class ControlComponent : IWindowObject |
|||
{ |
|||
public ControlComponent() |
|||
{ |
|||
} |
|||
public void draw() // draws the object |
|||
{ |
|||
Console.WriteLine( "ControlComponent::draw()" ); |
|||
} |
|||
public String getDescription() // returns a description of the object |
|||
{ |
|||
return "ControlComponent::getDescription()"; |
|||
} |
|||
} |
|||
abstract class Decorator : IWindowObject |
|||
{ |
|||
protected IWindowObject _decoratedWindow = null; // the object being decorated |
|||
public Decorator( IWindowObject decoratedWindow ) |
|||
{ |
|||
_decoratedWindow = decoratedWindow; |
|||
} |
|||
public virtual void draw() |
|||
{ |
|||
_decoratedWindow.draw(); |
|||
Console.WriteLine("\tDecorator::draw() "); |
|||
} |
|||
public virtual String getDescription() // returns a description of the object |
|||
{ |
|||
return _decoratedWindow.getDescription() + "\n\t" + "Decorator::getDescription() "; |
|||
} |
|||
} |
|||
// the first decorator |
|||
class DecorationA : Decorator |
|||
{ |
|||
public DecorationA(IWindowObject decoratedWindow) : base(decoratedWindow) |
|||
{ |
|||
} |
|||
public override void draw() |
|||
{ |
|||
base.draw(); |
|||
DecorationAStuff(); |
|||
} |
|||
private void DecorationAStuff() |
|||
{ |
|||
Console.WriteLine("\t\tdoing DecorationA things"); |
|||
} |
|||
public override String getDescription() |
|||
{ |
|||
return base.getDescription() + "\n\t\tincluding " + this.ToString(); |
|||
} |
|||
}// end class ConcreteDecoratorA : Decorator |
|||
class DecorationB : Decorator |
|||
{ |
|||
public DecorationB(IWindowObject decoratedWindow) : base(decoratedWindow) |
|||
{ |
|||
} |
|||
public override void draw() |
|||
{ |
|||
base.draw(); |
|||
DecorationBStuff(); |
|||
} |
|||
private void DecorationBStuff() |
|||
{ |
|||
Console.WriteLine("\t\tdoing DecorationB things"); |
|||
} |
|||
public override String getDescription() |
|||
{ |
|||
return base.getDescription() + "\n\t\tincluding " + this.ToString(); |
|||
} |
|||
}// end class DecorationB : Decorator |
|||
class DecorationC : Decorator |
|||
{ |
|||
public DecorationC(IWindowObject decoratedWindow) : base(decoratedWindow) |
|||
{ |
|||
} |
|||
public override void draw() |
|||
{ |
|||
base.draw(); |
|||
DecorationCStuff(); |
|||
} |
|||
private void DecorationCStuff() |
|||
{ |
|||
Console.WriteLine("\t\tdoing DecorationC things"); |
|||
} |
|||
public override String getDescription() |
|||
{ |
|||
return base.getDescription() + "\n\t\tincluding " + this.ToString(); |
|||
} |
|||
}// end class DecorationC : Decorator |
|||
}// end of namespace GSL_Decorator_pattern |
|||
</source> |
|||
=== 파이썬 === |
|||
<source lang="python"> |
|||
class Coffee: |
|||
def cost(self): |
|||
return 1 |
|||
class Milk: |
|||
def __init__(self, coffee): |
|||
self.coffee = coffee |
|||
def cost(self): |
|||
return self.coffee.cost() + .5 |
|||
class Whip: |
|||
def __init__(self, coffee): |
|||
self.coffee = coffee |
|||
def cost(self): |
|||
return self.coffee.cost() + .7 |
|||
class Sprinkles: |
|||
def __init__(self, coffee): |
|||
self.coffee = coffee |
|||
def cost(self): |
|||
return self.coffee.cost() + .2 |
|||
# Example 1 |
|||
coffee = Milk(Coffee()) |
|||
print "Coffee with milk : "+str(coffee.cost()) |
|||
# Example 2 |
|||
coffee = Whip(Milk(Sprinkles(Coffee()))) |
|||
print "Coffee with milk, whip and sprinkles : "+str(coffee.cost()) |
|||
</source> |
|||
=== 자바스크립트 === |
|||
<source lang="JavaScript"> |
|||
//Class to be decorated |
|||
function Coffee(){ |
|||
this.cost = function(){ |
|||
return 1; |
|||
}; |
|||
} |
|||
//Decorator A |
|||
function Milk(coffee){ |
|||
this.cost = function(){ |
|||
return coffee.cost() + 0.5; |
|||
}; |
|||
} |
|||
//Decorator B |
|||
function Whip(coffee){ |
|||
this.cost = function(){ |
|||
return coffee.cost() + 0.7; |
|||
}; |
|||
} |
|||
//Decorator C |
|||
function Sprinkles(coffee){ |
|||
this.cost = function(){ |
|||
return coffee.cost() + 0.2; |
|||
}; |
|||
} |
|||
//Here's one way of using it |
|||
var coffee = new Milk(new Whip(new Sprinkles(new Coffee()))); |
|||
alert( coffee.cost() ); |
|||
//Here's another |
|||
var coffee = new Coffee(); |
|||
coffee = new Sprinkles(coffee); |
|||
coffee = new Whip(coffee); |
|||
coffee = new Milk(coffee); |
|||
alert(coffee.cost()); |
|||
== 같이 보기 == |
|||
</source> |
|||
* [[컴포지트 패턴]] |
|||
* [[어댑터 패턴]] |
|||
* [[관점 지향 프로그래밍]] |
|||
* [[불변객체]] |
|||
== 외부 링크 == |
|||
{{위키책|en:Computer Science Design Patterns/Decorator|Decorator implementations in various languages|언어=en}} |
|||
* [http://c2.com/cgi/wiki?DecoratorPattern Decorator pattern description from the Portland Pattern Repository] |
|||
{{디자인 패턴(소프트웨어)}} |
|||
{{토막글|전산학}} |
|||
[[분류:디자인 패턴]] |
|||
[[분류:소프트웨어 디자인 패턴]] |
|||
[[de:Decorator]] |
|||
[[en:Decorator pattern]] |
|||
[[es:Decorator (patrón de diseño)]] |
|||
[[fr:Décorateur (patron de conception)]] |
|||
[[it:Decorator]] |
|||
[[ja:Decorator パターン]] |
|||
[[nl:Decorator]] |
|||
[[pl:Wzorzec dekoratora]] |
|||
[[ru:Декоратор (шаблон проектирования)]] |
|||
[[uk:Декоратор (шаблон проектування)]] |
|||
[[vi:Decorator pattern]] |
|||
[[zh:修饰模式]] |
2024년 6월 2일 (일) 23:40 기준 최신판
데코레이터 패턴(Decorator pattern)이란 주어진 상황 및 용도에 따라 어떤 객체에 책임을 덧붙이는 패턴으로, 기능 확장이 필요할 때 서브클래싱 대신 쓸 수 있는 유연한 대안이 될 수 있다.
예
[편집]자바
[편집]// the Window interface
interface Window {
public void draw(); // draws the Window
public String getDescription(); // returns a description of the Window
}
// implementation of a simple Window without any scrollbars
class SimpleWindow implements Window {
public void draw() {
// draw window
}
public String getDescription() {
return "simple window";
}
}
아래의 클래스들은 모든 Window
클래스들의 데코레이터를 포함하고 있다.
// abstract decorator class - note that it implements Window
abstract class WindowDecorator implements Window {
protected Window decoratedWindow; // the Window being decorated
public WindowDecorator (Window decoratedWindow) {
this.decoratedWindow = decoratedWindow;
}
}
// the first concrete decorator which adds vertical scrollbar functionality
class VerticalScrollBarDecorator extends WindowDecorator {
public VerticalScrollBarDecorator (Window decoratedWindow) {
super(decoratedWindow);
}
public void draw() {
drawVerticalScrollBar();
decoratedWindow.draw();
}
private void drawVerticalScrollBar() {
// draw the vertical scrollbar
}
public String getDescription() {
return decoratedWindow.getDescription() + ", including vertical scrollbars";
}
}
// the second concrete decorator which adds horizontal scrollbar functionality
class HorizontalScrollBarDecorator extends WindowDecorator {
public HorizontalScrollBarDecorator (Window decoratedWindow) {
super(decoratedWindow);
}
public void draw() {
drawHorizontalScrollBar();
decoratedWindow.draw();
}
private void drawHorizontalScrollBar() {
// draw the horizontal scrollbar
}
public String getDescription() {
return decoratedWindow.getDescription() + ", including horizontal scrollbars";
}
}
Window
인스턴스를 만드는 테스트 프로그램은 아래와 같다.
public class DecoratedWindowTest {
public static void main(String[] args) {
// create a decorated Window with horizontal and vertical scrollbars
Window decoratedWindow = new HorizontalScrollBarDecorator (
new VerticalScrollBarDecorator(new SimpleWindow()));
// print the Window's description
System.out.println(decoratedWindow.getDescription());
}
}
C++
[편집]#include <iostream>
using namespace std;
/* Component (interface) */
class Widget {
public:
virtual void draw() = 0;
virtual ~Widget() {}
};
/* ConcreteComponent */
class TextField : public Widget {
private:
int width, height;
public:
TextField( int w, int h ){
width = w;
height = h;
}
void draw() {
cout << "TextField: " << width << ", " << height << '\n';
}
};
/* Decorator (interface) */
class Decorator : public Widget {
private:
Widget* wid; // reference to Widget
public:
Decorator( Widget* w ) {
wid = w;
}
void draw() {
wid->draw();
}
~Decorator() {
delete wid;
}
};
/* ConcreteDecoratorA */
class BorderDecorator : public Decorator {
public:
BorderDecorator( Widget* w ) : Decorator( w ) { }
void draw() {
Decorator::draw();
cout << " BorderDecorator" << '\n';
}
};
/* ConcreteDecoratorB */
class ScrollDecorator : public Decorator {
public:
ScrollDecorator( Widget* w ) : Decorator( w ) { }
void draw() {
Decorator::draw();
cout << " ScrollDecorator" << '\n';
}
};
int main( void ) {
Widget* aWidget = new BorderDecorator(
new ScrollDecorator(
new TextField( 80, 24 )));
aWidget->draw();
delete aWidget;
}