Decorator Pattern

๊น€์˜์šฐ (AvocadoSmasher)ยท2022๋…„ 10์›” 25์ผ
0

Design Pattern

๋ชฉ๋ก ๋ณด๊ธฐ
3/8
post-thumbnail

๐Ÿ”Žย What is Decorator Pattern??

๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ํŒจํ„ด(Decorator Pattern)์€ ์ƒํ™ฉ์ด๋‚˜ ์šฉ๋„์— ๋”ฐ๋ผ ์–ด๋– ํ•œ ๊ฐ์ฒด์— ๊ธฐ๋Šฅ์„ ๋™์ ์œผ๋กœ ์ถ”๊ฐ€ํ•ด์ฃผ๋Š” ํŒจํ„ด์ž…๋‹ˆ๋‹ค. ์ด๋Š” ์žก๋‹คํ•œ ๊ธฐ๋Šฅ์„ ๋ชจ๋‘ ํ•œ๊ณณ์— ๋•Œ๋ ค๋„ฃ๊ธฐ ๋ณด๋‹ค๋Š” ๊ธฐ๋ณธ ๋ผˆ๋Œ€๊ฐ€ ๋˜๋Š” ๊ธฐ๋Šฅ์„ ๊ฐ€์ง„ ๋ถ€๋ถ„๊ณผ ๊ทธ ์™ธ์˜ ๋ถ€๋ถ„๋“ค์„ ๋‚˜๋ˆ„์–ด ๊ฐ์ฒด๋ฅผ ์กฐํ•ฉํ•ด๊ฐ€๋ฉฐ ์‚ฌ์šฉ์ž๊ฐ€ ์›ํ•˜๋Š” ๊ธฐ๋Šฅ์„ ํ•˜๋Š” ๊ฐ์ฒด๋ฅผ ์™„์„ฑํ•˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.

โš“๏ธ Digging into how it works

์‚ฌ์ „์ ์ธ ์ •์˜๋Š” ์œ„์™€ ๊ฐ™์€ ๋Š๋‚Œ์ž…๋‹ˆ๋‹ค. ์ง๊ด€์ ์ธ ์ดํ•ด๋ฅผ ์œ„ํ•ด์„œ๋Š” Decorate(์žฅ์‹ํ•˜๋‹ค.) ๋ผ๋Š” ์˜๋‹จ์–ด๋ฅผ ๋ณด๋ฉด ์•Œ ์ˆ˜ ์žˆ๋Š”๋ฐ ๋ง ๊ทธ๋Œ€๋กœ ์žฅ์‹์„ ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

ํฌ๋ฆฌ์Šค๋งˆ์Šค ํŠธ๋ฆฌ๋ฅผ ์žฅ์‹ํ•˜๋Š”๊ฒƒ์„ ๋ณด๋ฉด Decorator Pattern๊ณผ ๋งค์šฐ ์œ ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ํฌ๋ฆฌ์Šค๋งˆ์Šค ํŠธ๋ฆฌ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ๋ผˆ๋Œ€๊ฐ€ ๋˜๋Š” ํŠธ๋ฆฌ๊ฐ€ ์žˆ๊ณ  ๊ทธ ์™ธ์— ์žฅ์‹๋“ค์€ ์ถ”๊ฐ€์ ์œผ๋กœ ์ถ”๊ฐ€ํ•˜๋Š” ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿผ ์ผ๋ฐ˜์ ์ธ ๊ตฌ์กฐ๋ฅผ ๋‹ค์ด์–ด๊ทธ๋žจ์„ ํ†ตํ•ด ์‚ดํŽด๋ณด๋„๋ก ํ•˜์ฃ .


(์ถœ์ฒ˜ : Wikipedia Decorator Page)

์œ„์˜ ๊ตฌ์กฐ์™€ ํฌ๋ฆฌ์Šค๋งˆ์Šค ํŠธ๋ฆฌ ์žฅ์‹์„ ๋งค์นญํ•ด๊ฐ€๋ฉฐ ์•Œ์•„๋ณผ๊นŒ์š”?

  • Component : ํฌ๋ฆฌ์Šค๋งˆ์Šค ํŠธ๋ฆฌ ๋ถ€๋ถ„์„ ๋‹ด๋‹นํ•˜๋Š” ๊ธฐ๋ณธ ๋ผˆ๋Œ€์˜ ๋ถ€๋ถ„์ž…๋‹ˆ๋‹ค.
  • ConcreteComponent ์‹ค์งˆ์ ์œผ๋กœ Component์˜ ์ธ์Šคํ„ด์Šค๋กœ์จ ๊ธฐ๋Šฅ์„ ํ•ด์ฃผ๋Š” ๋ถ€๋ถ„์œผ๋กœ ํฌ๋ฆฌ์Šค๋งˆ์Šค ํŠธ๋ฆฌ๋„ Tree์˜ ์ข…๋ฅ˜์— ๋”ฐ๋ผ ๋Š๋‚Œ์ด ๋‹ฌ๋ผ์ง€๊ฒ ์ฃ ? ์˜ˆ๋ฅผ๋“ค์–ด Oak tree, Pine tree, etc ๋‹ค์–‘ํ•˜๊ฒŒ ์กด์žฌํ•  ์ˆ˜ ์žˆ๊ฒ ์ฃ ? ๊ทธ๋Ÿฐ ๋ผˆ๋Œ€๋ผ๋Š” Tree์˜ ์‹ค์งˆ์ ์ธ ์ธ์Šคํ„ด์Šค์ธ ๋‚˜๋ฌด์˜ ์ข…๋ฅ˜๋“ค์ด ๋  ์ˆ˜ ์žˆ๊ฒ ์Šต๋‹ˆ๋‹ค.
  • Decorator ConcreteDecorator๋“ค์„ ํ•œ ๋ฒˆ๋” ๋ชจ๋“ˆํ™” ํ•˜๋Š” ๋Š๋‚Œ์ธ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. Decorator ๊ฐ„์—๋„ ๊ฐœ๋ณ„์ ์œผ๋กœ ์ฒ˜๋ฆฌ๋˜์ง€ ์•Š์•„๋„ ๋˜๋Š” ์†์„ฑ์ด๋‚˜ ๋ฉ”์†Œ๋“œ๋“ค์„ ๋ฌถ์–ด์„œ ์—ฌ๊ธฐ์— ํ‘œํ˜„ํ•ฉ๋‹ˆ๋‹ค. (Component๋ฅผ ์ฐธ์กฐํ•˜๋Š” ์†์„ฑ ๋˜ํ•œ ์—ฌ๊ธฐ์— ๋ฐฐ์น˜ํ•ฉ๋‹ˆ๋‹ค. )
  • ConcreteDecorator Decorator์˜ ์‹ค์งˆ์ ์ธ ์ธ์Šคํ„ด์Šค ๋ถ€๋ถ„. ์ถ”๊ฐ€๋œ ๊ธฐ๋Šฅ๋“ค์— ๋Œ€ํ•œ ์ฑ…์ž„์„ ์ง€๋Š” ๋ถ€๋ถ„์ž…๋‹ˆ๋‹ค.

์ด๋Ÿฐ Decorator Pattern์€ ๋ผˆ๋Œ€์™€ ์žฅ์‹์„ ๋ถ„๋ฆฌํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ฃผ๊ธฐ์— ๊ธฐ๋Šฅ์˜ ๋™์ ์ธ ํ™•์žฅ์— ์œ ๋ฆฌํ•˜๋‹ค๋Š” ์žฅ์ ์ด ์žˆ์ง€๋งŒ ํ•ญ์ƒ ์‚ฌ์šฉํ•ด๋„ ์ข‹๋‹ค! ํ•˜๋Š” ๋ฌด์ ์˜ ๋””์ž์ธ ํŒจํ„ด์€ ์•„๋‹™๋‹ˆ๋‹ค. ์—ฌ๋Š ๋””์ž์ธ ํŒจํ„ด๋“ค์ด ๋Œ€๋ถ€๋ถ„ ๊ทธ๋ ‡๋“ฏ ๋‚จ์šฉํ•˜๋ฉด ์ฝ”๋“œ๊ฐ€ ๋งค์šฐ ๋ณต์žกํ•ด์ง€๊ณ  ๊ธธ์–ด ์งˆ ์ˆ˜ ์žˆ๋Š” ๋‹จ์ ์ด ์กด์žฌํ•œ๋‹ค.

๐Ÿ’ปย Code (feat. Java)

ํฌ๋ฆฌ์Šค๋งˆ์Šค ํŠธ๋ฆฌ๋ฅผ ์žฅ์‹ํ•˜๊ธฐ ์œ„ํ•œ ๋ชจ๋ธ์„ ๋””์ž์ธํ•ด๋ณด์•˜์Šต๋‹ˆ๋‹ค. ์šฐ์„  ํด๋ž˜์Šค ๋‹ค์ด์–ด๊ทธ๋žจ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

ํด๋ž˜์Šค ๋‹ค์ด์–ด๊ทธ๋žจ

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;
    }
}

๐Ÿ“Œย Summary

์ด๋ฒˆ์—๋Š” Decorator Pattern์— ๋Œ€ํ•ด ์•Œ์•„๋ณด์•˜์Šต๋‹ˆ๋‹ค. ์‹ค์ œ๋กœ ์“ฐ์ด๋Š” ๊ฒฝ์šฐ๋Š” ์‚ฌ์‹ค ์ž์ฃผ ๋ณด์ง„ ๋ชปํ–ˆ์ง€๋งŒ StreamReader ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋ถ€๋ถ„๋“ค์ด Decorator ํŒจํ„ด์œผ๋กœ ์ œ์ž‘ ๋˜์—ˆ๋‹ค๋Š” ์†Œ์‹์„ ๋“ฃ๊ธฐ๋Š” ํ•˜์˜€์Šต๋‹ˆ๋‹ค๋งŒ ์—ฌ๊ธฐ์„œ ์ž์„ธํžˆ ์†Œ๊ฐœํ•˜์ง„ ์•Š๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

Decorator Pattern์€ ์šฉ๋„์— ๋”ฐ๋ฅธ ๊ธฐ๋Šฅ์„ ๋™์ ์œผ๋กœ ์ถ”๊ฐ€ํ•˜๋Š”๊ฒƒ์„ OOP์˜ ๋ฃฐ๋“ค์„ ์ง€ํ‚ค๋ฉฐ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ๋””์ž์ธ ํŒจํ„ด ์ค‘ ํ•˜๋‚˜์˜€์Šต๋‹ˆ๋‹ค. ์ด๋•Œ๊นŒ์ง€ ์•Œ์•„๋ณธ Strategy Pattern ์ด๋ž‘ ๋ฌ˜ํ•˜๊ฒŒ ์œ ์‚ฌํ•˜๋‹ค๊ณ  ๋Š๋ผ๊ฒŒ ๋˜๋Š” ๋ถ€๋ถ„(์ „๋žต ํŒจํ„ด์€ ํ–‰์œ„์™€ ํ–‰์œ„๋ฅผ ํ•˜๋Š” ๊ฐ์ฒด๋ฅผ ๋ถ„๋ฆฌํ•˜๋Š” ๊ฒƒ์ด์—ˆ์ฃ ? ๋ญ”๊ฐ€ ์ƒ๊ฒจ๋‚œ ๋™๊ธฐ๋ž‘ ๊ตฌํ˜„์˜ ํ˜•ํƒœ๊ฐ€ ์•ฝ๊ฐ„์”ฉ ๋‹ค๋ฅด๋‹ค ๋ณด๋‹ˆ ๋‹ค๋ฅธ ํŒจํ„ด์œผ๋กœ ๋ถ„๋ฅ˜๋œ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.) ๋‘˜ ๋‹ค ๊ฒฐ๊ตญ ํ•ต์‹ฌ์€ ๋ฉ”์ธ ๋ผˆ๋Œ€์™€ ์žก๋‹ค๊ตฌ๋ฆฌํ•œ ๊ฒƒ๋“ค์„ ๋ถ„๋ฆฌํ•˜์—ฌ ๊ด€๋ฆฌํ•˜๋„๋ก ํ•˜๋Š” ๊ฒƒ์ด๋‹ค ๋ผ๋Š”๊ฒƒ์„ ๋Š๊ปด์ง€๋”๋ผ๊ตฌ์š” ์ €๋งŒ ๊ทธ๋Ÿฐ๊ฐ€์š”? ์•„๋ฌดํŠผ ๋งŽ์€ ๋ ˆ๊ฑฐ์‹œํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋“ค์ด ์ด๋Ÿฌํ•œ ํŒจํ„ด๋“ค์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์œผ๋‹ˆ ์ดํ•ดํ•˜๊ณ  ์žˆ๋‹ค๋ฉด ์•ž์œผ๋กœ ์—ฌ๋Ÿฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋“ค์„ ์ ‘ํ•  ๋•Œ ๊ตฌ์กฐ๊ฐ€ ์–ด๋–ค์‹์ธ์ง€ ์ดํ•ดํ•˜๋ฉด์„œ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€๋Šฅํ•˜๊ฒ ์ฃ ? ๋ง์ด ๋„ˆ๋ฌด ๊ธธ์–ด์กŒ๋„ค์š”. ๊ทธ๋Ÿผ ์ด๋งŒ ๋ฌผ๋Ÿฌ๋‚˜๊ฒ ์Šต๋‹ˆ๋‹ค.

profile
Android Studio ๊ณต๋ถ€ ์ค‘

0๊ฐœ์˜ ๋Œ“๊ธ€