| 니앙팽이 - 객체지향(OOP) | 4-4 | 구조패턴 - Decorator pattern

2023. 2. 2. 09:47·CS/SW 공학
객체지향

📕 4. 객체지향 디자인 패턴

유니티에서 사용하면 좋을 디자인 패턴만 명시한다.


📄 4. 구조 패턴

클래스나 객체를 조합하여 더 큰구조로 만드는 패턴


2). Decorator Patterns

ⓐ 특징

  1. 객체의 기본 기능에 추가 기능을 덧붙여 결합 & 장착할 수 있다.


1. 다수의 옷이 가진 각각의 효과를 결합 할 수 있다.

  1. 즉 객체를 런타임 동안 동적으로 변화시킬수 있다.

ⓑ 왜 쓰는가?

  • 기능 확장성
    • 기존 코드를 수정하지 않고도 데코레이터 패턴을 통해 행동을 확장할수 있다.
  • 동적 확장성
    • 구성과 위임을 통해서 실행중에 새로운 행동을 추가할 수 있습니다.

ⓒ 구성요소

  1. Component
    • 인터페이스 또는 추상클래스가 된다.
    • 기본 기능을 정의한다.
  2. ConcreteComponent
    • 기본 기능이 되는 인스턴스가 된다. 데코가 붙을 대상
    • Component를 상속한다.
  3. Decorator
    • 데코가 붙을 대상을 포함한다.
    • ConcreteDecorator의 form을 제공함 ConcreteDecorator가 생긴다면 다 Decorator와 비슷하게 생김
    • 추상클래스다
  4. ConcreteDecorator
    • 객체에 ConcreteDecorator기능을 추가하고싶을때
      ConcreteDecorator 생성자에 객체를 넣는다 그럼 행동이 추가된다.

ⓓ 단점

  • 데코레이터를 너무 많이 사용하면 코드가 필요 이상으로 복잡해 질 수 도 있다.

ⓔ 예시

  • 클라이언트가 데코레이터를 붙이는 방법
    /* Client.cs */
    Component component = new ConcreteComponent();
    
    component = new ConcreteDecorator1(...);
    component = new ConcreteDecorator2(...);
    
📂Decorator Pattern (C#)📂
using System;
using System.Collections;
using System.Net.NetworkInformation;
using System.Runtime.CompilerServices;
using System.Text;

namespace DesignPattern
{
    public abstract class Item
    {
        public abstract int GetLineCount();
        public abstract int GetMaxLength();
        public abstract int GetLength(int i);
        public abstract String GetString(int _i);
        public virtual void PrintString()
        {
            int lineNum = GetLineCount();
            for (int i = 0; i < lineNum; i++)
            {
                String str = GetString(i);
                Console.WriteLine(str);
            }
        }
    }
    public class Strings : Item
    {
        private List<String> strings = new List<String>();

        public void add(String _str)
        {
            strings.Add(_str);
        }
        public override int GetLineCount()
        {
            return strings.Count();
        }
        public override int GetMaxLength()
        {
            int maxLen = 0;
            foreach (String E in strings)
            {
                maxLen = maxLen < E.Length ? E.Length : maxLen;
            }
            return maxLen;
        }
        public override int GetLength(int i)
        {
            return strings[i].Length;
        }
        public override String GetString(int i)
        {
            return strings[i];
        }
    }
    public abstract class Decorator : Item
    {
        protected Item item;
        public Decorator(Item item)
        {
            this.item = item;
        }
    }
    public class SideDecorator : Decorator
    {
        private readonly Char decoChar = ' ';
        public SideDecorator(Item item, Char _c) : base(item)
        {
            decoChar = _c;
        }
        public override int GetLineCount()
        {
            return item.GetLineCount();
        }
        public override int GetMaxLength()
        {
            return item.GetMaxLength() + 2;
        }
        public override int GetLength(int i)
        {
            return item.GetLength(i) + 2;
        }
        public override String GetString(int i)
        {
            return decoChar + item.GetString(i) + decoChar;
        }
    }
    public class BoxDecorator : Decorator
    {

        public BoxDecorator(Item item) : base(item) { }
        public override int GetLineCount()
        {
            return item.GetLineCount() + 2;
        }
        public override int GetMaxLength()
        {
            return item.GetMaxLength() + 2;
        }
        public override int GetLength(int i)
        {
            return item.GetLength(i) + 2;
        }
        public override String GetString(int i)
        {
            int maxLen = GetLineCount();
            if (i == 0 || i == maxLen - 1) { return MakeBorder(); }
            return $"|{MakeTailString(item.GetString(i - 1))}|";
        }
        String MakeBorder()
        {
            int maxLen = GetMaxLength();
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < maxLen; i++)
            {
                if (i == 0 || i == maxLen - 1) { sb.Append('+'); continue; }
                sb.Append('-');
            }
            return sb.ToString();
        }
        string MakeTailString(string _target)
        {
            int maxLen = item.GetMaxLength();
            int spaceLen = maxLen - _target.Length;
            for (int i = 0; i < spaceLen; i++) { _target += ' '; }
            return _target;
        }
    }
    public class LineNumberDecorator : Decorator
    {

        public LineNumberDecorator(Item item) : base(item) { }
        public override int GetLineCount()
        {
            return item.GetLineCount();
        }
        public override int GetMaxLength()
        {
            return item.GetMaxLength() + 4;
        }
        public override int GetLength(int i)
        {
            return item.GetLength(i) + 4;
        }
        public override String GetString(int i)
        {
            return $"{String.Format("{0,2:D2}", i)} :{item.GetString(i)}";
        }
    }

    static void Main(string[] argv)
    {
        Strings strings = new Strings();
        strings.add("Hello~");
        strings.add("My name is escatrgot");
        strings.add("I am a Game and Web Developer");
        strings.add("Right now im learning DesignPattern !!");
        strings.PrintString();
        Item decorator = new SideDecorator(strings, '/');
        decorator = new BoxDecorator(decorator);
        decorator = new LineNumberDecorator(decorator);
        decorator = new BoxDecorator(decorator);
        decorator = new LineNumberDecorator(decorator);
        decorator.PrintString();
    }
}
📂Decorator Pattern 2(C#)📂
using System;
using System.Collections;
using System.Collections.Generic;

namespace DesignPattern
{
    internal class Decorator {
        interface Attackable {
            public void Attack();
        } 

        public class Player : Attackable {
            public void Attack(){
                Console.WriteLine("평타");                
            }            
        } 

        public abstract class Decorator : Attackable {
            protected Attackable attackable;
            public Decorator(Attackable attackable){
                this.attackable = attackable;
            }
        }

        public class Laser : Decorator {
            public override void Attack(){
                attackable.Attack();
                Console.WriteLine("찌유유유웅");       
            }
        }

        public class Knife : Decorator {
            public override void Attack(){
                attackable.Attack();
                Console.WriteLine("슉 슈슈슉 ㅅ벌럼아 칼협 칼협");       
            }
        }

        public class Screem : Decorator {
            
            public override void Attack(){
                attackable.Attack();
                Console.WriteLine("喝!!!!!!!!!!!!!!!!!!!!!!!!");
            }
        }
        
        static void Main(string[] argv){
            Player player = new Player();
            player.Attack();

            Attackable decorator = new Laser(player);
            decorator.Attack();
            decorator = new Knife(decorator);
            decorator.Attack();
            decorator = new Laser(decorator);
            decorator = new Screem(decorator);
            decorator.Attack();
        }
    }
}
📂Decorator Pattern 3(C#)📂
namespace DesignPattern
{
    public interface Component
    {
        public String add();
    }

    public class 에스프레소 : Component {
        String name = "에스프레소";
        public String add() {
            return name;
        }
    }

    public abstract class CoffeeDecorator : Component{
        protected readonly Component coffeeComponent;
        public CoffeeDecorator(Component component){
            this.coffeeComponent = component;
        }
        public virtual String add()
        {
            return coffeeComponent.add();
        }
    }
    public class 물데코레이터 : CoffeeDecorator
    {
        public 물데코레이터(Component component) : base(component) { }
        public override String add() { return $"{coffeeComponent.add()} + 물"; }
    }
    public class 우유데코레이터 : CoffeeDecorator {
        public 우유데코레이터(Component component) : base(component){}
        public override String add() { return $"{coffeeComponent.add()} + 우유"; }
    }
    public class 얼음데코레이터 : CoffeeDecorator
    {
        public 얼음데코레이터(Component component) : base(component) { }
        public override String add() { return $"{coffeeComponent.add()} + 얼음"; }
    }
    public class 휘핑크림데코레이터 : CoffeeDecorator
    {
        public 휘핑크림데코레이터(Component component) : base(component) { }
        public override String add() { return $"{coffeeComponent.add()} + 휘핑크림"; }
    }
    public class 자바칩데코레이터 : CoffeeDecorator
    {
        public 자바칩데코레이터(Component component) : base(component) { }
        public override String add() { return $"{coffeeComponent.add()} + 자바칩"; }
    }
    static void Main(string[] argv)
    {
        Component espresso = new 에스프레소();
        Console.WriteLine($"espresso : {espresso.add()}");
        Component americano = new 물데코레이터(espresso);
        Console.WriteLine($"americano : {americano.add()}");
        Console.WriteLine($"espresso : {espresso.add()}");
        Component latte = new 우유데코레이터(new 에스프레소());
        Console.WriteLine($"latte : {latte.add()}");

        Component 자바칩프라푸치노 = new 자바칩데코레이터(new 휘핑크림데코레이터(new 얼음데코레이터(latte)));
        Console.WriteLine($"자바칩프라푸치노 : {자바칩프라푸치노.add()}");
    }
}
저작자표시

'CS > SW 공학' 카테고리의 다른 글

| 니앙팽이 - 객체지향(OOP) | 4-6 | 행동패턴 - Command pattern  (0) 2023.02.02
| 니앙팽이 - 객체지향(OOP) | 4-5 | 구조패턴 - Flyweight pattern  (0) 2023.02.02
| 니앙팽이 - 객체지향(OOP) | 4-3 | 구조패턴 - Composite pattern  (0) 2023.02.02
| 니앙팽이 - 객체지향(OOP) | 4-2 | 생성패턴 - Singleton pattern  (0) 2023.02.02
| 니앙팽이 - 객체지향(OOP) | 4-1 | 디자인패턴 개요  (0) 2023.02.02
'CS/SW 공학' 카테고리의 다른 글
  • | 니앙팽이 - 객체지향(OOP) | 4-6 | 행동패턴 - Command pattern
  • | 니앙팽이 - 객체지향(OOP) | 4-5 | 구조패턴 - Flyweight pattern
  • | 니앙팽이 - 객체지향(OOP) | 4-3 | 구조패턴 - Composite pattern
  • | 니앙팽이 - 객체지향(OOP) | 4-2 | 생성패턴 - Singleton pattern
니앙팽이
니앙팽이
  • 니앙팽이
    니앙팽이 블로그
    니앙팽이
  • 전체
    오늘
    어제
    • 분류 전체보기 (126)
      • 그림그리기 (7)
      • 음악 (4)
        • FL Studio & MIDI (2)
        • 자작곡 (2)
      • 게임 (7)
        • 모바일 (0)
        • 스팀 (0)
        • 닌텐도 (0)
        • 개발 (7)
      • CS (44)
        • SW 공학 (27)
        • DB (7)
        • OS (9)
        • 네트워크 (1)
      • 팁 (9)
      • Language (21)
        • C# (8)
        • C&C++ (3)
        • 파이썬 메모 (3)
        • Javascript (7)
      • PS (0)
        • 알고리즘 (24)
        • 자료구조 (8)
        • 수학 (1)
        • 선형대수 (0)
        • 오토마타 (1)
        • 이산수학 (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    따라그리기
    노마드 코더
    알고리즘
    파이썬
    Stack
    자료구조
    디자인패턴
    유니티
    Javascript
    연결리스트
    그림 연습
    객체지향개발
    프로그래머스
    프로세스
    clip studio paint
    KAKAO
    unity
    가비지 콜렉터
    c#
    클립 스튜디오
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
니앙팽이
| 니앙팽이 - 객체지향(OOP) | 4-4 | 구조패턴 - Decorator pattern
상단으로

티스토리툴바