复合模式 泛型检查


例子:对应

    enum Color { Yellow, Red, Green }
    enum Size
    {
        Small, Medium, Large, Yuge
    }

    class Product
    {
        public string Name;
        public Color Color;
        public Size Size;

        public Product(string name, Color color, Size size)
        {
            Name = name;
            Color = color;
            Size = size;
        }
        public override string ToString()
        {
            return $"   -I'm Has a {Size} {Name} ,I't {Color}";
        }
    }
    class ProductFilter
    {
        public static IEnumerable FilterBySize(IEnumerable products, Size size)
        {
            foreach (var item in products)
                if (item.Size == size)
                    yield return item;
        }
    }
    interface ISpecification
    {
        bool IsSatified(T t);
    }
    interface IFilter
    {
        IEnumerable Filter(IEnumerable items, ISpecification spec);
        //IEnumerable FilterMore(IEnumerable items, ISpecification spec1, ISpecification spec2);
    }

    class ColorSpecification : ISpecification
    {
        private Color Color;

        public ColorSpecification(Color color)
        {
            Color = color;
        }

        public bool IsSatified(Product t)
        {
            return t.Color == Color;
        }
    }
    class SizeSpecification : ISpecification
    {
        private Size size;

        public SizeSpecification(Size size)
        {
            this.size = size;
        }

        public bool IsSatified(Product t)
        {
            return t.Size == size;
        }
    }
    class CompSiteSpecification : ISpecification
    {
        private IEnumerable> specifications;
        public CompSiteSpecification(params ISpecification[] _specifications)
        {
            specifications = _specifications;
        }
        public bool IsSatified(T t)
        {
           return specifications.All(sp => sp.IsSatified(t));
        }
    }

    class AndSpecification : ISpecification
    {
        ISpecification specification1, specification2;

        public AndSpecification(ISpecification specification1, ISpecification specification2)
        {
            this.specification1 = specification1;
            this.specification2 = specification2;
        }

        public bool IsSatified(T t)
        {
            return specification1.IsSatified(t) && specification2.IsSatified(t);
        }
    }
    class BetterFilter : IFilter
    {
        public IEnumerable Filter(IEnumerable items, ISpecification spec)
        {
            foreach (var item in items)
            {
                if (spec.IsSatified(item))
                {
                    yield return item;
                }
            }
        }

        //public IEnumerable FilterMore(IEnumerable items, ISpecification spec1, ISpecification spec2)
        //{
        //    foreach (var item in items)
        //    {
        //        if (spec1.IsSatified(item)&& spec2.IsSatified(item))
        //        {
        //            yield return item;
        //        }
        //    }
        //}
    }

    internal class Program
    {
        static void Main(string[] args)
        {
            Product apple = new Product("Apple", Color.Red, Size.Small);
            Product banana = new Product("Banana", Color.Yellow, Size.Medium);
            Product home = new Product("Home", Color.Green, Size.Large);
            Product tree = new Product("Tree", Color.Green, Size.Large);
            Product greenApple = new Product("GreenApple", Color.Green, Size.Small);

            Product[] products = { apple, banana, home, tree, greenApple };
            Console.WriteLine("Get Large (new):");
            foreach (var item in ProductFilter.FilterBySize(products, Size.Large))
            {
                Console.WriteLine(item);
            }
            BetterFilter better = new BetterFilter();
            Console.WriteLine("Get Large (new):");
            foreach (var item in better.Filter(products, new ColorSpecification(Color.Green)))
            {
                Console.WriteLine(item);
            }
            Console.WriteLine("Get Green & Small (new):");
            foreach (var item in better.Filter(products,
                new CompSiteSpecification(
                new ColorSpecification(Color.Green),
                new SizeSpecification(Size.Small)))
                )
            {
                Console.WriteLine($"    -{item.Name} is big & Green");
            }
        }
    }