본문으로 이동

데코레이터 패턴: 두 판 사이의 차이

위키백과, 우리 모두의 백과사전.
내용 삭제됨 내용 추가됨
잔글 {{토막글|전산학}}
잔글 봇: 같이 보기 문단 추가
 
(사용자 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>


아래의 클래스들은 모든 <tt>Window</tt> 클래스들의 데코레이터를 포함하고 있다.
아래의 클래스들은 모든 <code>Window</code> 클래스들의 데코레이터를 포함하고 있다.


<source lang="java">
<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>
<tt>Window</tt> 인스터스를 만드는 테스트 프로그램은 아래와 같다.
<code>Window</code> 인스턴스를 만드는 테스트 프로그램은 아래와 같다.


<source lang="java">
<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++ ===

<source lang="cpp">
<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;
}

같이 보기

[편집]

외부 링크

[편집]