首页 > 代码库 > 规约模式学习总结

规约模式学习总结

目前想到的可以使用规约模式的情况(以后想到了再补充):

1. 当有一组条件,被多处使用,且这些条件可以任意组合时,这个时候考虑使用规约模式来解耦;

 

下面看一下规约模式的简单实现:

    public interface ISpecification<T> where T : class    {        bool IsSatisfiedBy( T item );    }    public abstract class Specification<T> : ISpecification<T> where T : class    {        #region ISpecification<T> 成员        public abstract bool IsSatisfiedBy( T item );        #endregion        public ISpecification<T> And( ISpecification<T> other )        {            return new AndSpecification<T>( this, other );        }        public ISpecification<T> Or( ISpecification<T> other )        {            return new OrSpecification<T>( this, other );        }        public ISpecification<T> Not()        {            return new NotSpecification<T>( this );        }    }    public class AndSpecification<T> : Specification<T> where T : class    {        private readonly ISpecification<T> _left;        private readonly ISpecification<T> _right;        public AndSpecification( ISpecification<T> left, ISpecification<T> right )        {            if ( left == null ) throw new ArgumentNullException( "left" );            if ( right == null ) throw new ArgumentNullException( "right" );            this._left = left;            this._right = right;        }        public override bool IsSatisfiedBy( T item )        {            return this._left.IsSatisfiedBy( item ) && this._right.IsSatisfiedBy( item );        }    }    public class OrSpecification<T> : Specification<T> where T : class    {        private readonly ISpecification<T> _left;        private readonly ISpecification<T> _right;        public OrSpecification( ISpecification<T> left, ISpecification<T> right )        {            if ( left == null ) throw new ArgumentNullException( "left" );            if ( right == null ) throw new ArgumentNullException( "right" );            this._left = left;            this._right = right;        }        public override bool IsSatisfiedBy( T item )        {            return this._left.IsSatisfiedBy( item ) || this._right.IsSatisfiedBy( item );        }    }    public class NotSpecification<T> : Specification<T> where T : class    {        private readonly ISpecification<T> _left;        public NotSpecification( ISpecification<T> left )        {            if ( left == null ) throw new ArgumentNullException( "left" );            this._left = left;        }        public override bool IsSatisfiedBy( T item )        {            return !this._left.IsSatisfiedBy( item );        }    }    public class NameSpecification : Specification<UserInfo>    {        public override bool IsSatisfiedBy( UserInfo item )        {            if ( item == null ) throw new ArgumentNullException( "item" );            return item.Name.StartsWith( "JR", StringComparison.InvariantCultureIgnoreCase );        }    }    public class AgeSpecification : Specification<UserInfo>    {        public override bool IsSatisfiedBy( UserInfo item )        {            if ( item == null ) throw new ArgumentNullException( "item" );            return item.Age > 15;        }    }    public class UserInfo    {        public string Name { get; set; }        public int Age { get; set; }    }

 

其中 UserInfo 是一个测试类,NameSpecification, AgeSpeicification 是两个规约模式的实现。下面看一下测试代码:

    public class SpecificationTest    {        public void RunTest()        {            var users = new List<UserInfo> {                 new UserInfo{ Name = "JRoger1", Age = 11},                new UserInfo{ Name = "roger1", Age = 12},                new UserInfo{ Name = "JRoger2", Age = 18},            };            var nameSpec = new NameSpecification();            var ageSpec = new AgeSpecification();            var andSpec = nameSpec.And( ageSpec );            var orSpec = nameSpec.Or( ageSpec );            var notSpec = nameSpec.Not();            Console.WriteLine( "Name Specification ... " );            foreach ( var item in users )            {                if ( nameSpec.IsSatisfiedBy( item ) )                {                    Console.WriteLine( item.Name );                }            }            Console.WriteLine();            Console.WriteLine( "Age Specification ... " );            foreach ( var item in users )            {                if ( ageSpec.IsSatisfiedBy( item ) )                {                    Console.WriteLine( item.Name );                }            }            Console.WriteLine();            Console.WriteLine( "And Specification ... " );            foreach ( var item in users )            {                if ( andSpec.IsSatisfiedBy( item ) )                {                    Console.WriteLine( item.Name );                }            }            Console.WriteLine();            Console.WriteLine( "Or Specification ... " );            foreach ( var item in users )            {                if ( orSpec.IsSatisfiedBy( item ) )                {                    Console.WriteLine( item.Name );                }            }            Console.WriteLine();            Console.WriteLine( "Not Specification ... " );            foreach ( var item in users )            {                if ( notSpec.IsSatisfiedBy( item ) )                {                    Console.WriteLine( item.Name );                }            }            Console.ReadLine();        }    }

 

 

关于规约模式,网上也有很多讲解的。关键还是理解其是在什么情景下提出来的方法。至于规约模式的实现,基本思想是一样的。但是各种语言有根据各种语言的特性实现的版本,C#版的有一个比较好的使用 Lambda 表达式实现的。上面的实现版本算是中规中矩的。

规约模式学习总结