프로그래밍 기술/Escort GoF의 디자인 패턴 C#

[C#] 복합체 패턴(Composite Pattern) - 구현

언제나휴일 2016. 4. 26. 10:34
반응형

8. 복합체 패턴(Composite Pattern)



복합체 패턴(Composite Pattern) 클래스 다이어그램

[그림] 복합체 패턴(Composite Pattern) 클래스 다이어그램

Composite.zip


8. 4 구현

 

 복합체 패턴의 예제 프로그램을 구현하는 순서는 Tree, Category, Path, 데모 코드 순으로 하겠습니다.

 

8.4.1 Tree

 

 Tree 클래스는 Path Category를 같은 방법으로 사용할 수 있게 하려고 Path에서 수행할 수 있는 기능과 Category에서 할 수 있는 모든 기능에 대해 약속 또는 구현해 주어야 합니다.

 

 Path에서는 자신의 정보를 보여주는 기능이 필요합니다. Category에서는 자신의 정보 및 자식 요소들에 대한 정보를 보여주는 기능이 필요합니다. 이에 대한 구체적 구현이 추상 메서드로 약속만 하겠습니다.

 

 또한, Category에서는 자식 요소를 추가하거나 제거할 수 있는 기능을 제공해 주어야 할 것입니다. 하지만 단일 개체인 Path에서는 이에 대해 재정의할 것이 없으므로 Tree 클래스에는 메서드 내부를 비어있게 구현할게요. 물론, Category에서는 재정의해야 합니다. 이처럼 Path에서는 불필요한 기능까지 기반 클래스에서 제공하는 것은 복합체 패턴의 단점입니다.

 

Tree.cs

namespace Composite

{

    abstract class Tree

    {

        public string Name{    get;    private set;    }

        public Tree Parent{     get;    set;  }

 

        public abstract void View();

        public virtual void AddChild(Tree child) {   } //복합 개체에서만 필요한 기능

        public virtual void RemoveChild(Tree child){  }//복합 개체에서만 필요한 기능

 

        public int Size

        {

            get

            {

                return Name.Length + Level*2;

            }

        }

 

        public int Level

        {

            get

            {

                int level = 0;

                Tree ancestor = Parent;

                while(ancestor!=null)

                {

                    level++;

                    ancestor = ancestor.Parent;

                }

                return level;

            }

        }

       

        public Tree(string name)

        {

            Name = name;

            Parent = null;

        }

    }

}

 

 

8.4.2 Category

 

 Category 클래스에서는 자신의 정보 및 자식 요소들의 정보도 보여주도록 View 메서드를 재정의해야 할 것입니다. 그리고 자식 요소를 추가하거나 자식 요소를 제거하는 메서드도 재정의해 주어야 합니다.

 

Category.cs

using System;

using System.Collections.Generic;

 

namespace Composite

{

    class Category:Tree

    {

        List<Tree> children = new List<Tree>();

        public Category(string name):base(name)

        { 

        }

        public override void View()

        {

            Console.WriteLine("{0," + Size.ToString() + "}-C", Name);

            foreach(Tree child in children)

            {

                child.View();

            }

        }

        public override void AddChild(Tree child) //Category에만 필요한 기능

        {

            child.Parent = this;

            children.Add(child);

        }

        public override void RemoveChild(Tree child) //Category에만 필요한 기능

        {

            child.Parent = null;

            children.Remove(child);

        }

    }

}

 

8.4.3 Path

 

 Path 클래스에서는 단순히 자신의 정보를 보여주는 View 메서드를 재정의하면 되겠죠.

 

Path.cs

using System;

namespace Composite

{

    class Path:Tree

    {

        public Path(string path):base(path)

        {

        }

        public override void View()

        {

            Console.WriteLine("{0," + Size.ToString() + "}", Name);

        }

    }

}

  

8.4.4 데모 코드

 

 데모 코드에서는 지역별로 관리되는 서브 트리와 날짜별로 관리되는 서브 트리를 구성된 트리를 만들고 이들에 대한 전체 정보를 보여주는 정도로 보여주려고 합니다.

 

Program.cs

namespace Composite

{

    class Program

    {

        static void Main(string[] args)

        {

            Tree tree = new Category("사진트리");

            Tree date_tree = MakeDemoDateTree();

            Tree location_tree = MakeDemoLocationTree();

 

            tree.AddChild(date_tree);

            tree.AddChild(location_tree);

            tree.View();

        }

 

        static Tree MakeDemoLocationTree()

        {

            Tree tree = new Category("지역");

            Tree sub1 = new Category("제주");

            Tree sub2 = new Category("천안");

            Tree sub3 = new Category("서울");

            Tree sub4 = new Path("C:\\사진\\외도");

            Tree sub2_1 = new Path("C:\\사진\\현충사의봄");

           

 

            sub2.AddChild(sub2_1);

            tree.AddChild(sub1);

            tree.AddChild(sub2);

            tree.AddChild(sub3);

            tree.AddChild(sub4);

            return tree;

        }

 

        static Tree MakeDemoDateTree()

        {

            Tree tree = new Category("날짜");

            Tree sub1 = new Category("20120429");

            Tree sub2 = new Category("20120407");

            Tree sub3 = new Category("20120507");

 

            Tree sub1_1 = new Path("C:\\사진\\외도");

            sub1.AddChild(sub1_1);

            Tree sub2_1 = new Path("C:\\사진\\현충사의봄");

            sub2.AddChild(sub2_1);

            Tree sub3_1 = new Path("C:\\사진\\일산고구마모종");

            sub3.AddChild(sub3_1);

 

            tree.AddChild(sub1);

            tree.AddChild(sub2);

            tree.AddChild(sub3);

 

            return tree;

        }

    }

}

  

▶ 실행 결과

사진트리-C

  날짜-C

    20120429-C

      C:\사진\외도

    20120407-C

      C:\사진\현충사의봄

    20120507-C

      C:\사진\일산고구마모종

  지역-C

    제주-C

    천안-C

      C:\사진\현충사의봄

    서울-C

    C:\사진\외도

 

 

2016/04/26 - [프로그래밍 기술/Escort GoF의 디자인 패턴 C#] - [C#] 복합체 패턴(Composite Pattern) - 개요, 시나리오


2016/04/26 - [프로그래밍 기술/Escort GoF의 디자인 패턴 C#] - [C#] 복합체 패턴(Composite Pattern) - 설계(Design)


반응형