热门IT资讯网

设计模式-规约模式C#版

发表于:2024-11-30 作者:热门IT资讯网编辑
编辑最后更新 2024年11月30日,设计模式-规约模式C#版规约模式的使用场景就是规则,业务规则的碎片化。业务规则的组合是不固定的,需要做成很容易组合,也很容易拆散的方式,规约模式是一个选择。下面的例子是一个书店中,用户租书的场景。需要

设计模式-规约模式C#版

规约模式的使用场景就是规则,业务规则的碎片化。

业务规则的组合是不固定的,需要做成很容易组合,也很容易拆散的方式,规约模式是一个选择。

下面的例子是一个书店中,用户租书的场景。

需要判断用户的最大租书数和用户的状态,需要同时满足这两个要求,才可以继续租书。最大租书数和状态这两个规则拆散开来,在需要的时候再进行组合。不需要组合的地方,就单独使用这些规则。

针对一个实体有不同的规则,把这些规则碎片化,随意组合和拆散,这样就构成了规约模式。

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. namespace DomainModel.Model
  6. {
  7. ///
  8. /// 规约模式
  9. ///
  10. ///
  11. public interface ISpecification
  12. {
  13. bool IsSatisfiedBy(T entity);
  14. ///
  15. /// 与规约
  16. ///
  17. ///
  18. ///
  19. ISpecification And(ISpecification specification);
  20. ///
  21. /// 或规约
  22. ///
  23. ///
  24. ///
  25. ISpecification Or(ISpecification specification);
  26. ///
  27. /// 非规约
  28. ///
  29. ///
  30. ISpecification Not();
  31. }
  32. public class Customer
  33. {
  34. private ISpecification _hasReachedMax;
  35. private ISpecification _active;
  36. public Customer(ISpecification hasReachedMax, ISpecification active)
  37. {
  38. this._hasReachedMax = hasReachedMax;
  39. this._active = active;
  40. }
  41. public int TotalRentNumber { get; set; }
  42. public bool Active
  43. {
  44. get { return true; }
  45. }
  46. public bool CanRent()
  47. {
  48. var specification = this._hasReachedMax.Not().And(this._active.Not());
  49. return specification.IsSatisfiedBy(this);
  50. }
  51. }
  52. public class HasReachedMaxSpecification : CompositeSpecification
  53. {
  54. public override bool IsSatisfiedBy(Customer entity)
  55. {
  56. return entity.TotalRentNumber >= 6;
  57. }
  58. }
  59. public class CustomerActiveSpecification : CompositeSpecification
  60. {
  61. public override bool IsSatisfiedBy(Customer entity)
  62. {
  63. return entity.Active;
  64. }
  65. }
  66. ///
  67. /// 组合规约
  68. ///
  69. ///
  70. public abstract class CompositeSpecification : ISpecification
  71. {
  72. public abstract bool IsSatisfiedBy(T entity);
  73. public ISpecification And(ISpecification specification)
  74. {
  75. return new AndSpecification(this, specification);
  76. }
  77. public ISpecification Not()
  78. {
  79. return new NotSpecification(this);
  80. }
  81. public ISpecification Or(ISpecification specification)
  82. {
  83. throw new NotImplementedException();
  84. }
  85. }
  86. public class AndSpecification : CompositeSpecification
  87. {
  88. private ISpecification _left;
  89. private ISpecification _right;
  90. public AndSpecification(ISpecification left, ISpecification right)
  91. {
  92. this._left = left;
  93. this._right = right;
  94. }
  95. public override bool IsSatisfiedBy(T entity)
  96. {
  97. return this._left.IsSatisfiedBy(entity) && this._right.IsSatisfiedBy(entity);
  98. }
  99. }
  100. public class OrSpecification : CompositeSpecification
  101. {
  102. private ISpecification _left;
  103. private ISpecification _right;
  104. public OrSpecification(ISpecification left, ISpecification right)
  105. {
  106. this._left = left;
  107. this._right = right;
  108. }
  109. public override bool IsSatisfiedBy(T entity)
  110. {
  111. return this._left.IsSatisfiedBy(entity) || this._right.IsSatisfiedBy(entity);
  112. }
  113. }
  114. public class NotSpecification : CompositeSpecification
  115. {
  116. private ISpecification _inner;
  117. public NotSpecification(ISpecification inner)
  118. {
  119. this._inner = inner;
  120. }
  121. public override bool IsSatisfiedBy(T entity)
  122. {
  123. return !this._inner.IsSatisfiedBy(entity);
  124. }
  125. }
  126. }

参考文献

1.走向.NET架构设计-第五章-业务层模式,原则,实践(前篇)

0