C \ # 디자인 모드 (10) - 조합 모드 (Composite Pattern)

머리말
소프트웨어 개발 과정 에서 우 리 는 간단 한 대상 과 복합 대상 을 처리 하 는 상황 을 자주 만 날 수 있다. 예 를 들 어 운영 체제 에서 디 렉 터 리 에 대한 처 리 는 바로 이런 예 이다. 디 렉 터 리 는 단독 파일 도 포함 할 수 있 고 폴 더 도 포함 할 수 있 으 며 폴 더 는 파일 로 구성 되 기 때문이다. 간단 한 대상 과 복합 대상 은 기능 적 으로 차이 가 있 기 때문이다.이 로 인해 조작 과정 에서 간단 한 대상 과 복합 대상 을 구분 해 야 한다. 그러면 고객 호출 에 불필요 한 번 거 로 움 을 가 져 올 수 있 지만 고객 으로서 그들 은 간단 한 대상 과 복합 대상 을 시종일관 일치 하 게 대 할 수 있 기 를 바란다.그러나 조합 모델 은 이런 문 제 를 해결 하 는 것 이다.다음은 조합 모델 이 이 문 제 를 어떻게 해결 하 는 지 살 펴 보 자.
2. 조합 모델 에 대한 상세 한 소개
2.1 조합 모드 의 정의
조합 모드 는 대상 을 트 리 구조 로 조합 하여 '부분 - 전체' 의 차원 구 조 를 표현 하여 고객 이 하나의 대상 과 대상 의 조합 을 일치 하 는 방식 으로 처리 하도록 합 니 다. 다음은 우리 가 그린 예 로 조합 모델 을 상세 하 게 소개 합 니 다. 도형 은 일부 기본 도형 요소 로 구성 할 수도 있 고 복잡 한 도형 으로 구성 할 수도 있 습 니 다.(기본 도형 요 소 를 조합 하여 만 든 것) 고객 이 기본 도형 과 복잡 한 도형 에 대한 호출 을 일치 시 키 기 위해 우 리 는 조합 모델 을 사용 하여 전체 목적 을 달성 합 니 다.
조합 모델 이 실현 되 는 가장 관건 적 인 부분 은 간단 한 대상 과 복합 대상 이 똑 같은 인 터 페 이 스 를 실현 해 야 한 다 는 것 이다. 이것 이 바로 조합 모델 이 조합 대상 과 간단 한 대상 을 일치 하 게 처리 할 수 있 는 이유 이다.
2.2 조합 모델 의 실현
조합 모델 의 정 의 를 소개 한 후에 우 리 는 도형 의 예 로 조합 모델 을 실현 합 니 다. 구체 적 인 코드 는 다음 과 같 습 니 다.
//                             
    //      
    class Client
    {
        static void Main(string[] args)
        {
            ComplexGraphics complexGraphics = new ComplexGraphics("                  ");
            complexGraphics.Add(new Line("  A"));
            ComplexGraphics CompositeCG = new ComplexGraphics("              ");
            CompositeCG.Add(new Circle(" "));
            CompositeCG.Add(new Circle("  B"));
            complexGraphics.Add(CompositeCG);
            Line l = new Line("  C");
            complexGraphics.Add(l);
            //          
            Console.WriteLine("         :");
            Console.WriteLine("---------------------");
            complexGraphics.Draw();
            Console.WriteLine("        ");
            Console.WriteLine("---------------------");
            Console.WriteLine();
            //                 
            complexGraphics.Remove(l);
            Console.WriteLine("    C ,         :");
            Console.WriteLine("---------------------");
            complexGraphics.Draw();
            Console.WriteLine("        ");
            Console.WriteLine("---------------------");
            Console.Read();
        }
    }
    /// 
    ///      ,
    /// 
    public abstract class Graphics
    {
        public string Name { get; set; }
        public Graphics(string name)
        {
            this.Name = name;
        }
        public abstract void Draw();
        public abstract void Add(Graphics g);
        public abstract void Remove(Graphics g);
    }
    /// 
    ///      —— 
    /// 
    public class Line : Graphics
    {
        public Line(string name)
            : base(name)
        { }
        //         
        public override void Draw()
        {
            Console.WriteLine("   " + Name);
        }
        //                 ,      Add Remove        
        //              Add Remove            
        //                  
        public override void Add(Graphics g)
        {
            throw new Exception("       Line      ");
        }
        public override void Remove(Graphics g)
        {
            throw new Exception("       Line      ");
        }
    }
    /// 
    ///      —— 
    /// 
    public class Circle : Graphics
    {
        public Circle(string name)
            : base(name)
        { }
        //         
        public override void Draw()
        {
            Console.WriteLine("   " + Name);
        }
        public override void Add(Graphics g)
        {
            throw new Exception("       Circle      ");
        }
        public override void Remove(Graphics g)
        {
            throw new Exception("       Circle      ");
        }
    }
    /// 
    ///     ,         ,                       
    /// 
    public class ComplexGraphics : Graphics
    {
        private List complexGraphicsList = new List();
        public ComplexGraphics(string name)
            : base(name)
        { }
        /// 
        ///        
        /// 
        public override void Draw()
        {         
            foreach (Graphics g in complexGraphicsList)
            {
                g.Draw();
            }
        }
        public override void Add(Graphics g)
        {
            complexGraphicsList.Add(g);
        }
        public override void Remove(Graphics g)
        {
            complexGraphicsList.Remove(g);
        }
    }

기본 적 인 도형 대상 에 Add 와 Remove 방법 이 존재 하지 않 기 때문에 위 에서 실현 하 는 과정 에서 이상 한 방식 으로 이런 문 제 를 해결 할 수 있 습 니 다. 그러나 우 리 는 더욱 안전 한 방식 으로 해결 하고 싶 습 니 다. 기본 적 인 도형 에는 이런 방법 이 존재 하지 않 기 때문에 우 리 는 이런 방법 을 제거 할 수 있 습 니까? 이런 방법 을 제거 하기 위해 우 리 는 Graphic 을 수정 해 야 합 니 다.s 인터페이스, 우 리 는 하위 대상 을 관리 하 는 방법 을 복합 도형 대상 에 설명 합 니 다. 이렇게 간단 한 대상 Line, Circle 이 이런 방법 을 사용 할 때 컴 파일 할 때 오류 가 발생 합 니 다. 이런 실현 방식 을 우 리 는 안전 식 조합 모델 이 라 고 부 릅 니 다. 그러나 위의 실현 방식 을 투명 식 조합 모델 이 라 고 부 릅 니 다. 다음은 안전 식 조합 모델 이 어떻게 실제 적 인지 보 여 줍 니 다.현재 구체 적 인 실현 코드 는 다음 과 같다.
///         
    ///                           ComplexGraphics  
    ///         Line、Circle   Add Remove   ,           
    ///                     ,                      。
    ///                    ,      ,             
    class Client
    {
        static void Main(string[] args)
        {
            ComplexGraphics complexGraphics = new ComplexGraphics("                  ");
            complexGraphics.Add(new Line("  A"));
            ComplexGraphics CompositeCG = new ComplexGraphics("              ");
            CompositeCG.Add(new Circle(" "));
            CompositeCG.Add(new Circle("  B"));
            complexGraphics.Add(CompositeCG);
            Line l = new Line("  C");
            complexGraphics.Add(l);
            //          
            Console.WriteLine("         :");
            Console.WriteLine("---------------------");
            complexGraphics.Draw();
            Console.WriteLine("        ");
            Console.WriteLine("---------------------");
            Console.WriteLine();
            //                 
            complexGraphics.Remove(l);
            Console.WriteLine("    C ,         :");
            Console.WriteLine("---------------------");
            complexGraphics.Draw();
            Console.WriteLine("        ");
            Console.WriteLine("---------------------");
            Console.Read();
        }
    }
    /// 
    ///      ,
    /// 
    public abstract class Graphics
    {
        public string Name { get; set; }
        public Graphics(string name)
        {
            this.Name = name;
        }
        public abstract void Draw();
        //    Add Remove  
        //             ComplexGraphics      
        //                  
    }
    /// 
    ///      —— 
    /// 
    public class Line : Graphics
    {
        public Line(string name)
            : base(name)
        { }
        //         
        public override void Draw()
        {
            Console.WriteLine("   " + Name);
        }
    }
    /// 
    ///      —— 
    /// 
    public class Circle : Graphics
    {
        public Circle(string name)
            : base(name)
        { }
        //         
        public override void Draw()
        {
            Console.WriteLine("   " + Name);
        }
    }
    /// 
    ///     ,         ,                       
    /// 
    public class ComplexGraphics : Graphics
    {
        private List complexGraphicsList = new List();
        public ComplexGraphics(string name)
            : base(name)
        { }
        /// 
        ///        
        /// 
        public override void Draw()
        {
            foreach (Graphics g in complexGraphicsList)
            {
                g.Draw();
            }
        }
        public void Add(Graphics g)
        {
            complexGraphicsList.Add(g);
        }
        public void Remove(Graphics g)
        {
            complexGraphicsList.Remove(g);
        }
    }

2.3 조합 모드 의 유형 도
위의 두 가지 방식 의 실현 을 본 후에 우 리 는 조합 모델 의 유형 도 를 구체 적 으로 보고 조합 모델 중의 유형 간 의 관 계 를 정리 하 자.
투명 한 조합 모드 도표:
보안 조합 모드 의 분류:
조합 모드 에서 세 가지 캐릭터 와 관련된다.
  • 추상 적 인 구조 재 (Component) 역할: 이것 은 추상 적 인 역할 이다. 위 에서 실 현 된 Graphics 는 이 역할 을 충당 하고 조합 에 참가 하 는 대상 에 게 공공 인터페이스 와 기본 행 위 를 정의 하여 모든 하위 대상 을 관리 할 수 있다 (투명 한 조합 모델 은 이렇다).. 안전 한 조합 모드 에서 구조 재 역할 은 하위 대상 을 관리 하 는 방법 을 정의 하지 않 습 니 다. 이 정 의 는 나뭇가지 구조 대상 에 의 해 제 시 됩 니 다.
  • 나뭇잎 구조물 (Leaf) 역할: 나뭇잎 대상 이 있 을 때 하위 대상 의 대상 이 없고 그 위 에 중 Line 과 Circle 이 이 역할 을 수행 하여 조합 에 참가 하 는 원시 대상 의 행 위 를 정의 한다
  • .
  • 나뭇가지 구조 재 (Composite) 역할: 조합 에 참가 하 는 하급 자 대상 을 대표 하 는 대상 이다. 위 에서 중 ComplexGraphics 가 이 역할 을 하고 나뭇가지 대상 은 모든 관리 대상 의 방법 을 제시한다. 예 를 들 어 Add, Remove 등 이다.
  • 3. 조합 모델 의 장단 점
    장점:
  • 조합 모드 로 인해 클 라 이언 트 코드 는 대상 과 대상 용 기 를 일치 하 게 처리 할 수 있 고 관계 처리 가 필요 없 는 단일 대상 이 며 조합의 대상 용기 입 니 다.
  • '고객 코드 와 복잡 한 대상 용기 구조' 를 결합 시킨다.
  • 조합 대상 에 새로운 구조물 을 쉽게 넣 을 수 있다.
  • 단점: 디자인 을 더욱 복잡 하 게 한다. 클 라 이언 트 는 클래스 간 의 차원 관 계 를 정리 하 는 데 더 많은 시간 을 들 여야 한다. (이것 은 거의 모든 디자인 모델 이 직면 하 는 문제 이다.)
    질문
  • 가끔 은 시스템 이 나뭇가지 구조의 하위 구 조 를 여러 번 옮 겨 다 녀 야 할 때 가 있 습 니 다. 이 럴 때 하위 구 조 를 부모 구조 에 저장 하 는 것 을 캐 시 로 고려 할 수 있 습 니 다.
  • 클 라 이언 트 는 나뭇잎 류 의 방법 을 직접 호출 하지 않 으 려 고 합 니 다. (제 위 에서 이 루어 진 것 은 바로 이 렇 습 니 다. 나뭇가지 의 구체 적 인 대상 을 만 들 었 습 니 다. GraphicscoplexGraphics = new ComplexGraphics ('복잡 한 도형 과 두 라인 으로 구 성 된 복잡 한 도형') 를 사용 하고 아버지 류 (Graphics) 를 빌려 야 합 니 다.코드 의 재 활용 성 을 증가 시 킬 수 있 습 니 다.
  • 4. 조합 모드 의 사용 장면
    다음 과 같은 상황 에서 조합 모드 를 사용 하 는 것 을 고려 해 야 한다.
  • 한 대상 의 전체 또는 부분의 차원 구 조 를 나타 내야 한다.
  • 사용자 가 조합 대상 과 단일 대상 의 차 이 를 무시 하고 사용 자 는 조합 구조의 모든 대상 을 통일 적 으로 사용 하 기 를 바란다.
  • 5. 조합 모델 이. NET 에서 의 응용
    조합 모델 은. NET 에서 가장 전형 적 인 응용 은 바로 WinForms 와 Web 의 개발 이다.. NET 라 이브 러 리 에서 모두 이 두 플랫폼 에 기 존의 컨트롤 을 많이 제 공 했 지만 System. Windows. Forms. dll 에서 System. Windows. Forms. Control 류 는 조합 모델 을 응용 했다. 컨트롤 은 Label, TextBox 등 간단 한 컨트롤 을 포함 하 는 동시에 Group Box, DataGrid 등 도 포함 하기 때문이다.복합 적 인 컨트롤 은 모든 컨트롤 이 OnPaint 방법 으로 컨트롤 을 표시 해 야 합 니 다. 이러한 대상 간 의 전체 와 부분의 차원 구 조 를 나타 내기 위해 마이크로소프트 는 Control 류 의 실현 을 조합 모델 (정확히 말 하면 투명 한 조합 모델 을 응용 했다) 을 응용 합 니 다.
    총화
    여기 서 조합 모델 에 대한 소 개 는 끝 났 습 니 다. 조합 모델 은 클 라 이언 트 프로그램 과 복잡 한 요소 내부 구 조 를 결합 시 켜 클 라 이언 트 프로그램 이 간단 한 요 소 를 처리 하 는 것 처럼 복잡 한 요 소 를 처리 할 수 있 도록 합 니 다.

    좋은 웹페이지 즐겨찾기