• 规约模式学习总结


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

    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 表达式实现的。上面的实现版本算是中规中矩的。

  • 相关阅读:
    第一次博客作业
    自我介绍
    第一次个人编程作业
    第一次博客作业
    第一次个人编程作业
    第一次博客作业
    Alpha冲刺
    Alpha冲刺 (2/10)
    Alpha 冲刺 (1/10)
    福大软工 · 第七次作业
  • 原文地址:https://www.cnblogs.com/jroger/p/4244842.html
Copyright © 2020-2023  润新知