asp.net 组合模式的一个例子

复制代码 代码如下:

  using System;

  using System.Collections.Generic;

  using System.Linq;

  using System.Text;

  namespace Test

  {

  class Program

  {

  static void Main(string[] args)

  {

  var customer = new Customer

  {

  IsActive = true,

  LateFees = 100M,

  TotalRentNumber = 10

  };

  Console.WriteLine(customer.CanRent());

  Console.ReadKey();

  }

  }

  public interface ISpecification<T>

  {

  /// <summary>

  /// 是否可以租赁

  /// </summary>

  bool IsSatisfiedBy(T entity);

  /// <summary>

  /// 与操作

  /// </summary>

  ISpecification<T> And(ISpecification<T> other);

  /// <summary>

  /// 否操作

  /// </summary>

  ISpecification<T> Not();

  }

  /// <summary>

  /// 基类

  /// </summary>

  public abstract class CompositeSpecification<T> : ISpecification<T>

  {

  public abstract bool IsSatisfiedBy(T candidate);

  public ISpecification<T> And(ISpecification<T> other)

  {

  return new AndSpecification<T>(this, other);

  }

  public ISpecification<T> Not()

  {

  return new NotSpecification<T>(this);

  }

  }

  /// <summary>

  /// 与操作

  /// </summary>

  public class AndSpecification<T> : CompositeSpecification<T>

  {

  private ISpecification<T> leftSpecification;

  private ISpecification<T> rightSpecification;

  public AndSpecification(ISpecification<T> leftSpecification, ISpecification<T> rightSpecification)

  {

  this.leftSpecification = leftSpecification;

  this.rightSpecification = rightSpecification;

  }

  public override bool IsSatisfiedBy(T entity)

  {

  return leftSpecification.IsSatisfiedBy(entity) && rightSpecification.IsSatisfiedBy(entity);

  }

  }

  ///<summary>

  ///否操作

  /// </summary>

  public class NotSpecification<T> : CompositeSpecification<T>

  {

  private ISpecification<T> innerSpecification;

  public NotSpecification(ISpecification<T> innerSpecification)

  {

  this.innerSpecification = innerSpecification;

  }

  public override bool IsSatisfiedBy(T entity)

  {

  return !innerSpecification.IsSatisfiedBy(entity);

  }

  }

  /// <summary>

  /// 是否达到最大的规定租赁数

  /// </summary>

  public class HasReachedMaxSpecification : CompositeSpecification<Customer>

  {

  public override bool IsSatisfiedBy(Customer entity)

  {

  return entity.TotalRentNumber > 5;

  }

  }

  /// <summary>

  /// 是否激活

  /// </summary>

  public class CustomerActiveSpecification : CompositeSpecification<Customer>

  {

  public override bool IsSatisfiedBy(Customer entity)

  {

  return entity.IsActive;

  }

  }

  /// <summary>

  /// 是否欠费

  /// </summary>

  public class CustomerHasLateFeesSpecification : CompositeSpecification<Customer>

  {

  public override bool IsSatisfiedBy(Customer entity)

  {

  return entity.LateFees > 0;

  }

  }

  public class Customer

  {

  private ISpecification<Customer> hasReachedRentalThreshold;

  private ISpecification<Customer> customerIsActive;

  private ISpecification<Customer> customerHasLateFees;

  public Customer()

  {

  hasReachedRentalThreshold = new HasReachedMaxSpecification();

  customerIsActive = new CustomerActiveSpecification();

  customerHasLateFees = new CustomerHasLateFeesSpecification();

  }

  /// <summary>

  /// 用户租赁DVD数量

  /// </summary>

  public int TotalRentNumber

  {

  get;

  set;

  }

  /// <summary>

  /// 账户是否激活

  /// </summary>

  public bool IsActive

  {

  get;

  set;

  }

  /// <summary>

  /// 用户之前是否还欠费

  /// </summary>

  public decimal LateFees

  {

  get;

  set;

  }

  public bool CanRent()

  {

  ISpecification<Customer> canRent = customerIsActive.And(hasReachedRentalThreshold.Not()).And(customerHasLateFees.Not());

  return canRent.IsSatisfiedBy(this);

  }

  }

  }