zoukankan      html  css  js  c++  java
  • Specification模式的一个不错的示例代码

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

    namespace SpecificationPattern.ProgramT
    {
        public class Mobile
        {
            public BrandName BrandName { get; set; }
            public Type Type { get; set; }
            public int Cost;
            public string GetDescription()
            {
                return "The mobile is of brand : " + this.BrandName + " and of type : " + this.Type;
            }

            public Mobile(BrandName brandName, Type type, int cost = 0)
            {
                this.BrandName = brandName;
                this.Type = type;
                this.Cost = cost;
            }
        }

        public enum BrandName
        {
            Samsung,
            Apple,
            Htc
        }

        public enum Type
        {
            Basic,
            Smart
        }

        public interface ISpecification<T>
        {
            bool IsSatisfiedBy(T o);
            ISpecification<T> And(ISpecification<T> specification);
            ISpecification<T> Or(ISpecification<T> specification);
            ISpecification<T> Not(ISpecification<T> specification);
        }

        public abstract class CompositeSpecification<T> : ISpecification<T>
        {
            public abstract bool IsSatisfiedBy(T o);

            public ISpecification<T> And(ISpecification<T> specification)
            {
                return new AndSpecification<T>(this, specification);
            }
            public ISpecification<T> Or(ISpecification<T> specification)
            {
                return new OrSpecification<T>(this, specification);
            }
            public ISpecification<T> Not(ISpecification<T> specification)
            {
                return new NotSpecification<T>(specification);
            }
        }

        public class AndSpecification<T> : CompositeSpecification<T>
        {
            ISpecification<T> leftSpecification;
            ISpecification<T> rightSpecification;

            public AndSpecification(ISpecification<T> left, ISpecification<T> right)
            {
                this.leftSpecification = left;
                this.rightSpecification = right;
            }

            public override bool IsSatisfiedBy(T o)
            {
                return this.leftSpecification.IsSatisfiedBy(o)
                    && this.rightSpecification.IsSatisfiedBy(o);
            }
        }

        public class OrSpecification<T> : CompositeSpecification<T>
        {
            ISpecification<T> leftSpecification;
            ISpecification<T> rightSpecification;

            public OrSpecification(ISpecification<T> left, ISpecification<T> right)
            {
                this.leftSpecification = left;
                this.rightSpecification = right;
            }

            public override bool IsSatisfiedBy(T o)
            {
                return this.leftSpecification.IsSatisfiedBy(o)
                    || this.rightSpecification.IsSatisfiedBy(o);
            }
        }

        public class NotSpecification<T> : CompositeSpecification<T>
        {
            ISpecification<T> specification;

            public NotSpecification(ISpecification<T> spec)
            {
                this.specification = spec;
            }

            public override bool IsSatisfiedBy(T o)
            {
                return !this.specification.IsSatisfiedBy(o);
            }
        }

        public class ExpressionSpecification<T> : CompositeSpecification<T>
        {
            private Func<T, bool> expression;
            public ExpressionSpecification(Func<T, bool> expression)
            {
                if (expression == null)
                    throw new ArgumentNullException();
                else
                    this.expression = expression;
            }

            public override bool IsSatisfiedBy(T o)
            {
                return this.expression(o);
            }
        }

        public class PremiumSpecification<T> : CompositeSpecification<T>
        {
            private int cost;
            public PremiumSpecification(int cost)
            {
                this.cost = cost;
            }

            public override bool IsSatisfiedBy(T o)
            {
                return (o as Mobile).Cost >= this.cost;
            }
        }

        class ProgramT
        {
            static void Main(string[] args)
            {
                List<Mobile> mobiles = new List<Mobile> {
                    new Mobile(BrandName.Samsung, Type.Smart, 700),
                    new Mobile(BrandName.Apple, Type.Smart, 800),
                    new Mobile(BrandName.Htc, Type.Basic),
                    new Mobile(BrandName.Samsung, Type.Basic) };

                ISpecification<Mobile> samsungExpSpec =
                   new ExpressionSpecification<Mobile>(o => o.BrandName == BrandName.Samsung);
                ISpecification<Mobile> htcExpSpec =
                   new ExpressionSpecification<Mobile>(o => o.BrandName == BrandName.Htc);
                ISpecification<Mobile> SamsungAndHtcSpec = samsungExpSpec.And(htcExpSpec);


                ISpecification<Mobile> SamsungHtcExpSpec =
                   samsungExpSpec.Or(htcExpSpec);
                ISpecification<Mobile> NoSamsungExpSpec = new ExpressionSpecification<Mobile>(o => o.BrandName != BrandName.Samsung);

                ISpecification<Mobile> brandExpSpec = new ExpressionSpecification<Mobile>(o => o.Type == Type.Smart);
                ISpecification<Mobile> premiumSpecification = new PremiumSpecification<Mobile>(600);
                ISpecification<Mobile> complexSpec = (samsungExpSpec.Or(htcExpSpec)).And(brandExpSpec);
                ISpecification<Mobile> linqNonLinqExpSpec = NoSamsungExpSpec.And(premiumSpecification);

                //Some fun
                Console.WriteLine(" ***Samsung mobiles***** ");
                var result = mobiles.FindAll(o => samsungExpSpec.IsSatisfiedBy(o));
                result.ForEach(o => Console.WriteLine(o.GetDescription()));

                Console.WriteLine(" *****Htc mobiles******** ");
                result = mobiles.FindAll(o => htcExpSpec.IsSatisfiedBy(o));
                result.ForEach(o => Console.WriteLine(o.GetDescription()));

                Console.WriteLine(" ****Htc and samsung mobiles******* ");
                result = mobiles.FindAll(o => SamsungHtcExpSpec.IsSatisfiedBy(o));
                result.ForEach(o => Console.WriteLine(o.GetDescription()));

                Console.WriteLine(" ****Not samsung******* ");
                result = mobiles.FindAll(o => NoSamsungExpSpec.IsSatisfiedBy(o));
                result.ForEach(o => Console.WriteLine(o.GetDescription()));

                Console.WriteLine(" ****Htc and samsung mobiles (only smart)******* ");
                result = mobiles.FindAll(o => complexSpec.IsSatisfiedBy(o));
                result.ForEach(o => Console.WriteLine(o.GetDescription()));

                //More fun
                Console.WriteLine(" ****All premium mobile phones******* ");

                result = mobiles.FindAll(o => premiumSpecification.IsSatisfiedBy(o));
                result.ForEach(o => Console.WriteLine(o.GetDescription()));


                Console.WriteLine(" ****All premium mobile phones except samsung******* ");
                result = mobiles.FindAll(o => linqNonLinqExpSpec.IsSatisfiedBy(o));
                result.ForEach(o => Console.WriteLine(o.GetDescription()));
                Console.ReadLine();
            }

        }

    }

  • 相关阅读:
    C++对象模型
    C/C++内存结构
    第一篇
    Goodbye Steve(19552011)
    DirectX学习笔记_关于Sprite.Draw2D的说明
    Goodbye World!
    js把一个数组的数据平均到几个数组里面
    Django model字段类型清单
    Golang中间件——goredis操作Redis
    Python开发一个短网址生成器
  • 原文地址:https://www.cnblogs.com/dearbeans/p/8744636.html
Copyright © 2011-2022 走看看