Design Mode-specification Mode C #
The application scenario of the Protocol mode is rules, and the business rules are fragmented.
The combination of business rules is not fixed and needs to be easily combined or split. The Protocol mode is an option.
The following example shows a bookstore where users Rent Books.
You must determine the maximum number of books you want to rent and the status of the users. You must meet these two requirements at the same time before you can continue to rent books. The maximum number of books rental and status rules are separated and combined as needed. These rules are used independently where they do not need to be combined.
There are different rules for an object. These rules are fragmented, randomly combined, and separated, thus forming the Protocol mode.
Using System;
Using System. Collections. Generic;
Using System. Linq;
Using System. Text;
Namespace DomainModel. Model
{
/// <Summary>
/// Protocol Mode
/// </Summary>
/// <Typeparam name = "T"> </typeparam>
Public interface ISpecification <T>
{
Bool IsSatisfiedBy (T entity );
/// <Summary>
/// And Protocol
/// </Summary>
/// <Param name = "specification"> </param>
/// <Returns> </returns>
ISpecification <T> And (ISpecification <T> specification );
/// <Summary>
/// Or Protocol
/// </Summary>
/// <Param name = "specification"> </param>
/// <Returns> </returns>
ISpecification <T> Or (ISpecification <T> specification );
/// <Summary>
/// Non-Protocol
/// </Summary>
/// <Returns> </returns>
ISpecification <T> Not ();
}
Public class Customer
{
Private ISpecification <Customer> _ hasReachedMax;
Private ISpecification <Customer> _ active;
Public Customer (ISpecification <Customer> hasReachedMax, ISpecification <Customer> active)
{
This. _ hasReachedMax = hasReachedMax;
This. _ active = active;
}
Public int TotalRentNumber {get; set ;}
Public bool Active
{
Get {return true ;}
}
Public bool CanRent ()
{
Var specification = this. _ hasReachedMax. Not (). And (this. _ active. Not ());
Return specification. IsSatisfiedBy (this );
}
}
Public class HasReachedMaxSpecification: CompositeSpecification <Customer>
{
Public override bool IsSatisfiedBy (Customer entity)
{
Return entity. totalequalnumber> = 6;
}
}
Public class CustomerActiveSpecification: CompositeSpecification <Customer>
{
Public override bool IsSatisfiedBy (Customer entity)
{
Return entity. Active;
}
}
/// <Summary>
/// Composite Statute
/// </Summary>
/// <Typeparam name = "T"> </typeparam>
Public abstract class CompositeSpecification <T>: ISpecification <T>
{
Public abstract bool IsSatisfiedBy (T entity );
Public ISpecification <T> And (ISpecification <T> specification)
{
Return new AndSpecification <T> (this, specification );
}
Public ISpecification <T> Not ()
{
Return new NotSpecification <T> (this );
}
Public ISpecification <T> Or (ISpecification <T> specification)
{
Throw new NotImplementedException ();
}
}
Public class AndSpecification <T>: CompositeSpecification <T>
{
Private ISpecification <T> _ left;
Private ISpecification <T> _ right;
Public AndSpecification (ISpecification <T> left, ISpecification <T> right)
{
This. _ left = left;
This. _ right = right;
}
Public override bool IsSatisfiedBy (T entity)
{
Return this. _ left. IsSatisfiedBy (entity) & this. _ right. IsSatisfiedBy (entity );
}
}
Public class OrSpecification <T>: CompositeSpecification <T>
{
Private ISpecification <T> _ left;
Private ISpecification <T> _ right;
Public OrSpecification (ISpecification <T> left, ISpecification <T> right)
{
This. _ left = left;
This. _ right = right;
}
Public override bool IsSatisfiedBy (T entity)
{
Return this. _ left. IsSatisfiedBy (entity) | this. _ right. IsSatisfiedBy (entity );
}
}
Public class NotSpecification <T>: CompositeSpecification <T>
{
Private ISpecification <T> _ inner;
Public NotSpecification (ISpecification <T> inner)
{
This. _ inner = inner;
}
Public override bool IsSatisfiedBy (T entity)
{
Return! This. _ inner. IsSatisfiedBy (entity );
}
}
}