๋ฐ์ฝ๋ ์ดํฐ ํจํด(Decorator Pattern)์ ์ํฉ์ด๋ ์ฉ๋์ ๋ฐ๋ผ ์ด๋ ํ ๊ฐ์ฒด์ ๊ธฐ๋ฅ์ ๋์ ์ผ๋ก ์ถ๊ฐํด์ฃผ๋ ํจํด์ ๋๋ค. ์ด๋ ์ก๋คํ ๊ธฐ๋ฅ์ ๋ชจ๋ ํ๊ณณ์ ๋๋ ค๋ฃ๊ธฐ ๋ณด๋ค๋ ๊ธฐ๋ณธ ๋ผ๋๊ฐ ๋๋ ๊ธฐ๋ฅ์ ๊ฐ์ง ๋ถ๋ถ๊ณผ ๊ทธ ์ธ์ ๋ถ๋ถ๋ค์ ๋๋์ด ๊ฐ์ฒด๋ฅผ ์กฐํฉํด๊ฐ๋ฉฐ ์ฌ์ฉ์๊ฐ ์ํ๋ ๊ธฐ๋ฅ์ ํ๋ ๊ฐ์ฒด๋ฅผ ์์ฑํ๋๋ก ํฉ๋๋ค.
์ฌ์ ์ ์ธ ์ ์๋ ์์ ๊ฐ์ ๋๋์ ๋๋ค. ์ง๊ด์ ์ธ ์ดํด๋ฅผ ์ํด์๋ Decorate(์ฅ์ํ๋ค.) ๋ผ๋ ์๋จ์ด๋ฅผ ๋ณด๋ฉด ์ ์ ์๋๋ฐ ๋ง ๊ทธ๋๋ก ์ฅ์์ ํ๋ ๊ฒ์ ๋๋ค.
ํฌ๋ฆฌ์ค๋ง์ค ํธ๋ฆฌ๋ฅผ ์ฅ์ํ๋๊ฒ์ ๋ณด๋ฉด Decorator Pattern๊ณผ ๋งค์ฐ ์ ์ฌํฉ๋๋ค. ํฌ๋ฆฌ์ค๋ง์ค ํธ๋ฆฌ๋ ๊ธฐ๋ณธ์ ์ผ๋ก ๋ผ๋๊ฐ ๋๋ ํธ๋ฆฌ๊ฐ ์๊ณ ๊ทธ ์ธ์ ์ฅ์๋ค์ ์ถ๊ฐ์ ์ผ๋ก ์ถ๊ฐํ๋ ๋ฐฉ์์ ๋๋ค. ๊ทธ๋ผ ์ผ๋ฐ์ ์ธ ๊ตฌ์กฐ๋ฅผ ๋ค์ด์ด๊ทธ๋จ์ ํตํด ์ดํด๋ณด๋๋ก ํ์ฃ .
(์ถ์ฒ : Wikipedia Decorator Page)
์์ ๊ตฌ์กฐ์ ํฌ๋ฆฌ์ค๋ง์ค ํธ๋ฆฌ ์ฅ์์ ๋งค์นญํด๊ฐ๋ฉฐ ์์๋ณผ๊น์?
์ด๋ฐ Decorator Pattern์ ๋ผ๋์ ์ฅ์์ ๋ถ๋ฆฌํ ์ ์๋๋ก ํด์ฃผ๊ธฐ์ ๊ธฐ๋ฅ์ ๋์ ์ธ ํ์ฅ์ ์ ๋ฆฌํ๋ค๋ ์ฅ์ ์ด ์์ง๋ง ํญ์ ์ฌ์ฉํด๋ ์ข๋ค! ํ๋ ๋ฌด์ ์ ๋์์ธ ํจํด์ ์๋๋๋ค. ์ฌ๋ ๋์์ธ ํจํด๋ค์ด ๋๋ถ๋ถ ๊ทธ๋ ๋ฏ ๋จ์ฉํ๋ฉด ์ฝ๋๊ฐ ๋งค์ฐ ๋ณต์กํด์ง๊ณ ๊ธธ์ด ์ง ์ ์๋ ๋จ์ ์ด ์กด์ฌํ๋ค.
ํฌ๋ฆฌ์ค๋ง์ค ํธ๋ฆฌ๋ฅผ ์ฅ์ํ๊ธฐ ์ํ ๋ชจ๋ธ์ ๋์์ธํด๋ณด์์ต๋๋ค. ์ฐ์ ํด๋์ค ๋ค์ด์ด๊ทธ๋จ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
ํด๋์ค ๋ค์ด์ด๊ทธ๋จ
ChristmasTree interface (Component)
public interface ChristmasTree {
public String howItLooks();
public double totalCost();
}
OakTree & PineTree (ConcreteComponent)
public class PineTree implements ChristmasTree{
@Override
public String howItLooks() {
return "PineTree";
}
@Override
public double totalCost() {
return 3.5d;
}
}
public class OakTree implements ChristmasTree{
@Override
public String howItLooks() {
return "OakTree";
}
@Override
public double totalCost() {
return 5.5d;
}
}
ChristmasDecorator abstract class (Decorator)
abstract public class ChristmasDecorator implements ChristmasTree{
protected ChristmasTree christmasTree;
public ChristmasDecorator(ChristmasTree christmasTree){
this.christmasTree = christmasTree;
}
public String howItLooks(){
return christmasTree.howItLooks();
}
public double totalCost(){
return christmasTree.totalCost();
}
}
Bell & DecoySnow & NeonLight class (concreteDecorator)
public class Bell extends ChristmasDecorator{
public Bell(ChristmasTree christmasTree){
super(christmasTree);
}
@Override
public String howItLooks() {
return super.howItLooks() + " + Bell";
}
@Override
public double totalCost() {
return super.totalCost() + 0.6d;
}
}
public class DecoySnow extends ChristmasDecorator{
public DecoySnow(ChristmasTree christmasTree){
super(christmasTree);
}
@Override
public String howItLooks() {
return super.howItLooks() + " + Decoy Snow";
}
@Override
public double totalCost() {
return super.totalCost() + 0.5d;
}
}
public class NeonLight extends ChristmasDecorator{
public NeonLight(ChristmasTree christmasTree){
super(christmasTree);
}
@Override
public String howItLooks() {
return super.howItLooks() + " + Neon Light";
}
@Override
public double totalCost() {
return super.totalCost() + 1.5d;
}
}
์ด๋ฒ์๋ Decorator Pattern์ ๋ํด ์์๋ณด์์ต๋๋ค. ์ค์ ๋ก ์ฐ์ด๋ ๊ฒฝ์ฐ๋ ์ฌ์ค ์์ฃผ ๋ณด์ง ๋ชปํ์ง๋ง StreamReader ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋ถ๋ถ๋ค์ด Decorator ํจํด์ผ๋ก ์ ์ ๋์๋ค๋ ์์์ ๋ฃ๊ธฐ๋ ํ์์ต๋๋ค๋ง ์ฌ๊ธฐ์ ์์ธํ ์๊ฐํ์ง ์๋๋ก ํ๊ฒ ์ต๋๋ค.
Decorator Pattern์ ์ฉ๋์ ๋ฐ๋ฅธ ๊ธฐ๋ฅ์ ๋์ ์ผ๋ก ์ถ๊ฐํ๋๊ฒ์ OOP์ ๋ฃฐ๋ค์ ์งํค๋ฉฐ ๊ตฌํํ ์ ์๋๋ก ํ๋ ๋์์ธ ํจํด ์ค ํ๋์์ต๋๋ค. ์ด๋๊น์ง ์์๋ณธ Strategy Pattern ์ด๋ ๋ฌํ๊ฒ ์ ์ฌํ๋ค๊ณ ๋๋ผ๊ฒ ๋๋ ๋ถ๋ถ(์ ๋ต ํจํด์ ํ์์ ํ์๋ฅผ ํ๋ ๊ฐ์ฒด๋ฅผ ๋ถ๋ฆฌํ๋ ๊ฒ์ด์์ฃ ? ๋ญ๊ฐ ์๊ฒจ๋ ๋๊ธฐ๋ ๊ตฌํ์ ํํ๊ฐ ์ฝ๊ฐ์ฉ ๋ค๋ฅด๋ค ๋ณด๋ ๋ค๋ฅธ ํจํด์ผ๋ก ๋ถ๋ฅ๋๊ฒ ๊ฐ์ต๋๋ค.) ๋ ๋ค ๊ฒฐ๊ตญ ํต์ฌ์ ๋ฉ์ธ ๋ผ๋์ ์ก๋ค๊ตฌ๋ฆฌํ ๊ฒ๋ค์ ๋ถ๋ฆฌํ์ฌ ๊ด๋ฆฌํ๋๋ก ํ๋ ๊ฒ์ด๋ค ๋ผ๋๊ฒ์ ๋๊ปด์ง๋๋ผ๊ตฌ์ ์ ๋ง ๊ทธ๋ฐ๊ฐ์? ์๋ฌดํผ ๋ง์ ๋ ๊ฑฐ์ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ค์ด ์ด๋ฌํ ํจํด๋ค์ ์ฌ์ฉํ๊ณ ์์ผ๋ ์ดํดํ๊ณ ์๋ค๋ฉด ์์ผ๋ก ์ฌ๋ฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ค์ ์ ํ ๋ ๊ตฌ์กฐ๊ฐ ์ด๋ค์์ธ์ง ์ดํดํ๋ฉด์ ์ฌ์ฉํ๋ ๊ฒ์ด ๊ฐ๋ฅํ๊ฒ ์ฃ ? ๋ง์ด ๋๋ฌด ๊ธธ์ด์ก๋ค์. ๊ทธ๋ผ ์ด๋ง ๋ฌผ๋ฌ๋๊ฒ ์ต๋๋ค.