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


    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
    
        }
    }
  • 相关阅读:
    【Linux&amp;Unix--open/close/write/read系统调用】
    瑞丽的SQL-SQL Server的表旋转(行列转换)
    oracle查询和编写数据字典
    [Python]How to handle the exception in Python?
    【Android 应用开发】 FastJson 使用具体解释
    OpenStack Dashboard
    Java Drp项目实战——Drp知多少
    腾讯下一个重点:硬件;硬件自身的未来也正进入多元化发展
    一个简单的带缓存http代理
    Swift语言教程中文文档
  • 原文地址:https://www.cnblogs.com/wangchuang/p/2995861.html
Copyright © 2020-2023  润新知