본문 바로가기

프로그래밍/DesignPattern-C#

컴포지트(Composite) 패턴

컴포지트(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