2010-01-17

Introduction to Composite Pattern

-->
Design patterns, CAB & SCSF

Hai phần trước đã nói sơ qua về CAB. Nhưng thật sự thì chưa có gì đọng lại ngoài những cái tên. Tiếp theo chúng ta sẽ điểm qua các Design patterns sử dụng trong CAB và SCSF. Các design patterns không thể liệt kê hết trong phần này mà cần tham khảo trong suốt những phần tiếp theo. Nếu một pattern được sử dụng trong CAB và SCSF cần tham khảo để tiếp tục thì mình sẽ bổ sung. Có thể tham khảo các design patterns tại http://www.dofactory.com/Patterns/Patterns.aspx
Giới thiệu Composite Pattern
 Đầu tiên sẽ đề cập đến design pattern cơ bản là Composite. Có thể tham khảo bài viết tại http://sourcemaking.com/design_patterns/composite.

Composite UML class diagram (sử dụng abstract class)

Composite UML class diagram (sử dụng interface)

Trong UML class diagram có thể thấy 3 phần chính
- Leaf là các đối tượng thành phần (hay còn gọi là Primitive).

- Component là giao diện cho các đối tượng thành phần, khai báo các method căn bản, là giao diện dùng khi access các thành phần.

- Composite định nghĩa các thao tác trên đối tượng thành phần, thực hiện lưu trữ và quản lý các đối tương thành phần.

Composite Pattern cho phép nhóm các object thành một single instance của một object. Các objects được nhóm có tính năng khá tương tự nhau. Object kết quả gọi là composite object. Việc thêm một component vào composite được hình dung tương tự việc thêm vào tree. Về kỹ thuật tất cả các Design patterns đều xoay quanh những tính năng của OOP encapsulation, inheritance, polymorphism...

Trong Composite kỹ thuật chính là polymorphism với 2 cách implement là polymorphism thông qua interface (recommended) và polymorphism qua abstract class.

Lab dành cho Composite Pattern

Ví dụ đơn giản khi có các region:
(England: (London: Chelsea)) và (France: Paris) nhóm thành Europe, một region lớn hơn như sau:

(Europe: (England: (London: Chelsea)) (France: Paris))

-->
Source code với C# (thực hiện qua interface)
Component.cs
-->

using System;
using System.Collections.Generic;
using System.Text;

namespace DesignPatterns
{

    /// <summary>
    ///     Component interface
    /// </summary>
    interface Component
    {

        /// <summary>
        ///     Get the string of component (demo for component operation)
        /// </summary>
        ///
        ///     String of component
        /// </returns>
        string operation();

        /// <summary>
        ///     Get all children
        /// </summary>
        /// <returns>
        ///     List of <see cref="Component"/> children
        /// </returns>
        List<Component> getChildren();

        /// <summary>
        ///     Add to children collection
        /// </summary>
        /// <param name="c" type="Component">
        ///     Child <see cref="Component"/> to add
        /// </param>
        void add(Component c);

        /// <summary>
        ///     Remove from children collection
        /// </summary>
        /// <param name="c" type="Component">
        ///     Child <see cref="Component"/> to remove
        /// </param>
        /// <returns>
        ///     A bool value...
        /// </returns>
        bool remove(Component c);
    }
}

Composite.cs
using System;
using System.Collections.Generic;
using System.Text;

namespace DesignPatterns
{

    /// <summary>
    ///     Composite
    /// </summary>
    class Composite : Component
    {

        /// <summary>
        ///     ID
        /// </summary>
        private string _id;

        /// <summary>
        ///     Children collection
        /// </summary>
        private List<Component> _components = new List<Component>();

        /// <summary>
        ///     Constructor
        /// </summary>
        /// <param name="id" type="string">
        ///    
        /// </param>
        public Composite(string id)
        {
            _id = id;
        }

        #region [ INTERFACE IMPLEMENTATION ]

        /// <summary>
        ///     Operation
        /// </summary>
        /// <returns>
        ///     A string value present name and list of children recursive
        /// </returns>
        public string operation()
        {
            string s = " (" + _id + ":";
            this.getChildren().ForEach
            (
                delegate(Component child)
                {
                    s += " " + child.operation();
                }
            );

            return s + ") ";
        }

        /// <summary>
        ///     Implement interface get all children
        /// </summary>
        /// <returns>
        ///     List of <see cref="Component"/> children
        /// </returns>
        public List<Component> getChildren()
        {
            return _components;
        }

        /// <summary>
        ///     Add to children collection
        /// </summary>
        /// <param name="c" type="Component">
        ///     Child <see cref="Component"/> to add
        /// </param>
        public void add(Component c)
        {
            _components.Add(c);
        }

        /// <summary>
        ///     Remove from children collection
        /// </summary>
        /// <param name="c" type="Component">
        ///     Child <see cref="Component"/> to remove
        /// </param>
        /// <returns>
        ///     A bool value...
        /// </returns>
        public bool remove(Component c)
        {
            return _components.Remove(c);
        }

        #endregion

    }
}

Leaf.cs
-->

using System;
using System.Collections.Generic;
using System.Text;

namespace DesignPatterns
{

    /// <summary>
    ///     Leaf
    /// </summary>
    class Leaf : Component
    {

        /// <summary>
        ///    
        /// </summary>
        private string _id;

        /// <summary>
        ///     Constructor
        /// </summary>
        /// <param name="id" type="string">
        ///     ID
        /// </param>
        public Leaf(string id)
        {
            _id = id;
        }

        #region [ INTERFACE IMPLEMENTATION ]

        /// <summary>
        ///    
        /// </summary>
        /// <returns>
        ///     A string value...
        /// </returns>
        public string operation()
        {
            return _id;
        }

        /// <summary>
        ///     Get all children
        /// </summary>
        /// <returns>
        ///     Just return null
        /// </returns>
        public List<Component> getChildren()
        {
            return null;
        }

        /// <summary>
        ///     Add to children collection, do nothing
        /// </summary>
        /// <param name="c" type="Component">
        ///     Child <see cref="Component"/> to add
        /// </param>
        public void add(Component c) { }

        /// <summary>
        ///     Remove from children collection
        /// </summary>
        /// <param name="c" type="Component">
        ///     Child <see cref="Component"/> to remove
        /// </param>
        /// <returns>
        ///     Just return false
        /// </returns>
        public bool remove(Component c) { return false; }

        #endregion

    }
}



Program.cs
-->
using System;
using System.Collections.Generic;
using System.Text;

namespace DesignPatterns
{

    /// <summary>
    ///     Program
    /// </summary>
    class Program
    {

        /// <summary>
        ///     Main entry point
        /// </summary>
        /// <param name="args" type="string[]">
        ///    
        /// </param>
        static void Main(string[] args)
        {

            // England
            Composite england = new Composite("England");

            // London
            Composite london = new Composite("London");
            london.add(new Leaf("Chelsea"));
            england.add(london);

            // Manchester
            Leaf manchester = new Leaf("Manchester");
            england.add(manchester);
            england.remove(manchester);

            // France
            Composite france = new Composite("France");
            france.add(new Leaf("Paris"));

            // Europe
            Composite europe = new Composite("Europe");
            europe.add(england);
            europe.add(france);

            // Get Europe
            Console.WriteLine(europe.operation());
            Console.ReadKey();
        }
    }
}

Source code với C# (thực hiện qua abstract class)
Component.cs
-->

using System;
using System.Collections.Generic;
using System.Text;

namespace DesignPatterns
{

    /// <summary>
    ///     Component interface
    /// </summary>
    public abstract class Component
    {

        /// <summary>
        ///     ID
        /// </summary>
        protected string _id;

        /// <summary>
        ///     Constructor
        /// </summary>
        /// <param name="id" type="string">
        ///    
        /// </param>
        public Component(string id)
        {
            _id = id;
        }

        /// <summary>
        ///     Get all children
        /// </summary>
        /// <returns>
        ///     List of <see cref="Component"/> children
        /// </returns>
        public abstract List<Component> getChildren();

        /// <summary>
        ///     Get the string of component (demo for component operation)
        /// </summary>
        /// <returns>
        ///     String of component
        /// </returns>
        public abstract string operation();

        /// <summary>
        ///     Add to children collection
        /// </summary>
        /// <param name="c" type="Component">
        ///     Child <see cref="Component"/> to add
        /// </param>
        public abstract void add(Component c);

        /// <summary>
        ///     Remove from children collection
        /// </summary>
        /// <param name="c" type="Component">
        ///     Child <see cref="Component"/> to remove
        /// </param>
        /// <returns>
        ///     A bool value...
        /// </returns>
        public abstract bool remove(Component c);
    }
}


Composite.cs
-->
using System;
using System.Collections.Generic;
using System.Text;

namespace DesignPatterns
{

    /// <summary>
    ///     Composite
    /// </summary>
    class Composite : Component
    {

        /// <summary>
        ///     Children collection
        /// </summary>
        private List<Component> _components = new List<Component>();

        /// <summary>
        ///     Constructor
        /// </summary>
        /// <param name="id" type="string">
        ///    
        /// </param>
        public Composite(string id)
            : base(id)
        { }

        #region [ OVERRIDE METHODS ]

        /// <summary>
        ///     Operation
        /// </summary>
        /// <returns>
        ///     A string value present name and list of children recursive
        /// </returns>
        public override string operation()
        {
            string s = " (" + _id + ":";
            this.getChildren().ForEach(delegate(Component child) { s += " " + child.operation(); });
            return s + ") ";
        }

        /// <summary>
        ///     Implement interface get all children
        /// </summary>
        /// <returns>
        ///     List of <see cref="Component"/> children
        /// </returns>
        public override List<Component> getChildren()
        {
            return _components;
        }

        /// <summary>
        ///     Add to children collection
        /// </summary>
        /// <param name="c" type="Component">
        ///     Child <see cref="Component"/> to add
        /// </param>
        public override void add(Component c)
        {
            _components.Add(c);
        }

        /// <summary>
        ///     Remove from children collection
        /// </summary>
        /// <param name="c" type="Component">
        ///     Child <see cref="Component"/> to remove
        /// </param>
        /// <returns>
        ///     A bool value...
        /// </returns>
        public override bool remove(Component c)
        {
            return _components.Remove(c);
        }

        #endregion

    }
}

Leaf.cs
-->
using System;
using System.Collections.Generic;
using System.Text;


namespace DesignPatterns
{

    /// <summary>
    ///     Leaf
    /// </summary>
    class Leaf : Component
    {

        /// <summary>
        ///     Constructor
        /// </summary>
        /// <param name="id" type="string">
        ///     ID
        /// </param>
        public Leaf(string id) : base(id) { }

        #region [ OVERRIDE METHODS ]

        /// <summary>
        ///    
        /// </summary>
        /// <returns>
        ///     A string value...
        /// </returns>
        public override string operation()
        {
            return _id;
        }

        /// <summary>
        ///     Get all children
        /// </summary>
        /// <returns>
        ///     Just return null
        /// </returns>
        public override List<Component> getChildren()
        {
            return null;
        }

        /// <summary>
        ///     Add to children collection, do nothing
        /// </summary>
        /// <param name="c" type="Component">
        ///     Child <see cref="Component"/> to add
        /// </param>
        public override void add(Component c) { }

        /// <summary>
        ///     Remove from children collection
        /// </summary>
        /// <param name="c" type="Component">
        ///     Child <see cref="Component"/> to remove
        /// </param>
        /// <returns>
        ///     Just return false
        /// </returns>
        public override bool remove(Component c) { return false; }

        #endregion

    }
}

Qua bài này chúng ta sẽ chính thức tìm hiểu CAB. Part tiếp theo sẽ là part đầu tiên và mình sẽ đánh số cho dễ theo dõi bắt đầu là Part 1.

No comments:

Post a Comment