컴포지트(Composite) 패턴
여러 인터페이스의 인스턴스를 마치 하나의 인스턴스인 것처럼 취급하는 것.
그래서 클라이언트는 단 하나의 인스턴스만을 받아들인 후 별도의 수정 없이도 해당 인스턴스를 여러 개의 인스턴스처럼 활용할 수 있는 방법
아래 기본적인 컴포지트 패턴 사용 방법을 알아보자.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 | //... namespace Composite.basic { public interface IComponent { void Something(); } } //... namespace Composite.basic { public class Leaf : IComponent { public void Something() { Console.WriteLine("Leaf Class - Something()"); } } } //... namespace Composite.basic { public class CompositeComponent : IComponent { private ICollection<IComponent> children; public CompositeComponent() { children = new List<IComponent>(); } public void AddComponent(IComponent component) { children.Add(component); } public void RemoveComponent(IComponent component) { children.Remove(component); } public void Something() { foreach(var child in children) { child.Something(); } } } } namespace Composite.basic { class CompositeProgram { static IComponent component; static void Main(string[] args) { var composite = new CompositeComponent(); composite.AddComponent(new Leaf()); composite.AddComponent(new Leaf()); composite.AddComponent(new Leaf()); component = composite; composite.Something(); Console.WriteLine("Composite Design Pattern Program.cs - End"); } } } /* 결과 DecoratorComponent Class - SomethingElse() ConcreteComponent Class - Something() DecoratorProgram.cs - End */ | cs |
CompositeComponent 클래스에는 IComponent 인터페이스의 인스턴스를 추가하거나 제거하기 위한 메서드가 정의되어 있다. 이 메서드는 인터페이스의 일부가 아니라 CompositeComponent 클래스의 클라이언트 코드가 직접 접근할 수 있도록 정의한 것이다. 그래서 CompositeComponent 클래스의 인스턴스의 생성을 팩토리 메서드 또는 클래스에 위임하려면 데코레이트된 클래스의 인스턴스를 생성해서 AddComponent 메서드에 전달하는 역할도 함께 수행하도록 해야 한다. 그렇지 않으면 IComponent 인터페이스의 클라이언트가 이 역할을 모두 수행해야 한다.
IComponent 인터페이스의 클라이언트가 Something 메서드를 호출할 때마다 컬렉션 내에 저장된 인스턴스를 모두 탐색하면서 각 인스턴스의 Something 메서드를 호출하게 된다. 이런 방법으로 하나의 IComponent 인스턴스(CompositeComponent타입)를 통해 다른 여러 타입이 가진 메서드를 호출할 수 있게 된다.
컴포지트 객체에는 서로 다른 타입의 객체를 제공할 수 있다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | //... namespace Composite.basic { public class Leaf : IComponent { public void Something() { Console.WriteLine("Leaf Class - Something()"); } } public class AThirdLeafType : IComponent { public void Something() { Console.WriteLine("AThirdLeafType Class - Something()"); } } public class BThirdLeafType : IComponent { public void Something() { Console.WriteLine("BThirdLeafType Class - Something()"); } } } //... /* Leaf Class - Something() AThirdLeafType Class - Something() BThirdLeafType Class - Something() Composite Design Pattern Program.cs - End */ | cs |
논리적으로는 이 패턴을 이용하면 하나 혹은 그 이상의 CompositeComponent 객체를 AddComponent 메서드에 전달하여 상속 구조를 표현하는 트리(tree) 형태의 인스턴스를 조합하여 연결할 수 있다.
'프로그래밍 > DesignPattern-C#' 카테고리의 다른 글
데코레이터(Decorator) 패턴 (0) | 2019.01.31 |
---|