组合模式扩展,有选择的递归

1.先定义个选择接口规则

 public interface IMatchRule

    {

        bool IsMatch(Component target);

    }
 public abstract class Component

    {

        /// <summary>

        /// 保存子节点

        /// </summary>

        protected IList<Component> children;



        /// <summary>

        /// Leaf和Composite的共同特征. setter方式注入名称

        /// </summary>

        public virtual string Name

        {

            get;

            set;

        }



        /// <summary>

        /// 其实只有Composite类型才需要真正实现的功能

        /// </summary>

        /// <param name="child"></param>

        public virtual void Add(Component child) { children.Add(child); }

        public virtual void Remove(Component child) { children.Remove(child); }

        public virtual Component this[int index] { get { return children[index]; } }



        /// <summary>

        /// 演示用的补充方法:实现迭代器,并且对容器对象实现隐性递归

        /// </summary>

        /// <returns></returns>

        public virtual IEnumerable<Component> Enumerate(IMatchRule rule)

        {

            if ((rule == null) || (rule.IsMatch(this)))

                yield return this;

            if ((children != null) && (children.Count > 0))

                foreach (Component child in children)

                    foreach (Component item in child.Enumerate(rule))

                        if ((rule == null) || (rule.IsMatch(item)))

                            yield return item;

        }

        public virtual IEnumerable<Component> Enumerate() { return Enumerate(null); }

    }
    public class Leaf : Component

    {

        /// <summary>

        /// 明确声明不支持此类操作

        /// </summary>

        /// <param name="child"></param>

        public override void Add(Component child) { throw new NotSupportedException(); }

        public override void Remove(Component child) { throw new NotSupportedException(); }

        public override Component this[int index] { get { throw new NotSupportedException(); } }

    }
  public class Composite : Component

    {

        public Composite() { base.children = new List<Component>(); }

    }

在工厂类中

 public class ComponentFactory

    {

        public Component Create<T>(string name) where T : Component, new()

        {

            return new T() { Name = name };

        }



        /// <summary>

        /// 连贯性方法(Fluent Method): 直接向某个节点下增加新的节点

        /// </summary>

        /// <typeparam name="T"></typeparam>

        /// <param name="parent"></param>

        /// <param name="name"></param>

        /// <returns></returns>

        public Component Create<T>(Component parent, string name)

            where T : Component, new()

        {

            if (parent == null) throw new ArgumentNullException("parent");

            if (!(parent is Composite)) throw new Exception("non-somposite type");

            Component instance = Create<T>(name);

            parent.Add(instance);

            return instance;

        }

    }

那么在实现中调用则

using System;

using System.Collections.Generic;

using System.Diagnostics;

using System.Linq;

using C = MarvellousWorks.PracticalPattern.Composite.Iterating;

using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace MarvellousWorks.PracticalPattern.Composite.Tests.Iterating

{

    [TestClass]

    public class CompositeFixture

    {

        #region non-linq version



        class LeafMatchRule : C.IMatchRule

        {

            public bool IsMatch(C.Component target)

            {

                if (target == null) return false;

                return target.GetType().IsAssignableFrom(typeof(C.Leaf));

            }

        }



        C.Component corporate;



        /// <summary>

        /// 建立测试公司的组织结构

        /// </summary>

        [TestInitialize]

        public void Initialize()

        {

            var factory = new C.ComponentFactory();

            corporate = factory.Create<C.Composite>("corporate");           // 1

            factory.Create<C.Leaf>(corporate, "president");                 // 2

            factory.Create<C.Leaf>(corporate, "vice president");            // 3

            var sales = factory.Create<C.Composite>(corporate, "sales");    // 4

            var market = factory.Create<C.Composite>(corporate, "market");  // 5

            factory.Create<C.Leaf>(sales, "joe");                           // 6

            factory.Create<C.Leaf>(sales, "bob");                           // 7

            factory.Create<C.Leaf>(market, "judi");                         // 8

            var branch = factory.Create<C.Composite>(corporate, "branch");  // 9

            factory.Create<C.Leaf>(branch, "manager");                      // 10

            factory.Create<C.Leaf>(branch, "peter");                        // 11

        }



        [TestMethod]

        public void Test()

        {

            Assert.AreEqual<int>(7, corporate.Enumerate(new LeafMatchRule()).Count());

            Assert.AreEqual<int>(11, corporate.Enumerate().Count());



            //  验证通过增加遍历规则可以只显示所有leaf节点

            Trace.WriteLine("List all leaves:\n------------------------\n");

            foreach (var item in corporate.Enumerate(new LeafMatchRule()))

                Trace.WriteLine(item.Name );

        }



        #endregion



    }

}

 

你可能感兴趣的:(组合模式)