📕 4. 객체지향 디자인 패턴
유니티에서 사용하면 좋을 디자인 패턴만 명시한다.
📄 4. 구조 패턴
클래스나 객체를 조합하여 더 큰구조로 만드는 패턴
2). Decorator Patterns
ⓐ 특징
- 객체의 기본 기능에 추가 기능을 덧붙여 결합 & 장착할 수 있다.
1. 다수의 옷이 가진 각각의 효과를 결합 할 수 있다.
- 즉 객체를 런타임 동안 동적으로 변화시킬수 있다.
ⓑ 왜 쓰는가?
- 기능 확장성
- 기존 코드를 수정하지 않고도 데코레이터 패턴을 통해 행동을 확장할수 있다.
- 동적 확장성
- 구성과 위임을 통해서 실행중에 새로운 행동을 추가할 수 있습니다.
ⓒ 구성요소
- Component
- 인터페이스 또는 추상클래스가 된다.
- 기본 기능을 정의한다.
- ConcreteComponent
- 기본 기능이 되는 인스턴스가 된다. 데코가 붙을 대상
- Component를 상속한다.
- Decorator
- 데코가 붙을 대상을 포함한다.
- ConcreteDecorator의 form을 제공함 ConcreteDecorator가 생긴다면 다 Decorator와 비슷하게 생김
- 추상클래스다
- ConcreteDecorator
- 객체에 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 |