Content deleted Content added
m Reverted edits by 80.91.200.89 (talk) to last revision by 2A01:E0A:84B:9950:BD4B:293D:F4F4:D0A: editing tests |
m corrected compilation error |
||
(4 intermediate revisions by 3 users not shown) | |||
Line 1:
{{
[[
In computer programming, the '''specification pattern''' is a particular [[software design pattern]], whereby [[business rules]] can be recombined by chaining the business rules together using [[boolean algebra|boolean logic]]. The pattern is frequently used in the context of [[___domain-driven design]].
A specification pattern outlines a business rule that is combinable with other business rules.
As a consequence of performing runtime composition of high-level business/___domain logic, the Specification pattern is a convenient tool for converting ad-hoc user search criteria into low level logic to be processed by repositories.
Line 11:
== Code examples ==
===
{{Further|C Sharp (programming language)}}
<syntaxhighlight lang="csharp">
{
bool IsSatisfiedBy(object candidate);
ISpecification And(ISpecification other);
ISpecification AndNot(ISpecification other);
ISpecification Or(ISpecification other);
ISpecification OrNot(ISpecification other);
ISpecification Not();
}
public abstract class CompositeSpecification : ISpecification
{
public abstract bool IsSatisfiedBy(object candidate);
public ISpecification And(ISpecification other)
{
}
public ISpecification AndNot(ISpecification other)
{
}
public
{
return new OrSpecification(this, other);
}
return new OrNotSpecification(this, other);
}
public ISpecification Not()
{
return new NotSpecification(this);
}
}
public class AndSpecification : CompositeSpecification
{
private ISpecification _leftCondition;
private ISpecification _rightCondition;
public AndSpecification(ISpecification left, ISpecification right)
_leftCondition = left;
}
public override bool IsSatisfiedBy(object candidate)
{
return _leftCondition.IsSatisfiedBy(candidate) && _rightCondition.IsSatisfiedBy(candidate);
}
}
public class AndNotSpecification : CompositeSpecification
{
private ISpecification _leftCondition;
private ISpecification _rightCondition;
public AndNotSpecification(ISpecification left, ISpecification right)
_leftCondition = left;
}
public override bool IsSatisfiedBy(object candidate)
{
return _leftCondition.IsSatisfiedBy(candidate) && _rightCondition.IsSatisfiedBy(candidate) != true;
}
}
public class OrSpecification : CompositeSpecification
{
private ISpecification _leftCondition;
private ISpecification _rightCondition;
public OrSpecification(ISpecification left, ISpecification right)
_leftCondition = left;
}
public override bool IsSatisfiedBy(object candidate)
{
return _leftCondition.IsSatisfiedBy(candidate) || _rightCondition.IsSatisfiedBy(candidate);
}
}
public class OrNotSpecification : CompositeSpecification
{
private ISpecification _leftCondition;
private ISpecification _rightCondition;
public OrNotSpecification(ISpecification left, ISpecification right)
{
_rightCondition = right;
}
public override bool IsSatisfiedBy(object candidate)
{
return _leftCondition.IsSatisfiedBy(candidate) || _rightCondition.IsSatisfiedBy(candidate) != true;
}
}
{
private ISpecification _wrapped;
public NotSpecification(ISpecification x)
{
_wrapped = x;
}
public override bool IsSatisfiedBy(object candidate)
{
return !_wrapped.IsSatisfiedBy(candidate);
}
}
</syntaxhighlight>
=== C# 6.0 with generics ===
{{Further|C Sharp (programming language)}}
<syntaxhighlight lang="csharp">
public interface ISpecification<T>
{
bool IsSatisfiedBy(T candidate);
ISpecification<T> And(ISpecification<T> other);
ISpecification<T> AndNot(ISpecification<T> other);
ISpecification<T> Or(ISpecification<T> other);
ISpecification<T> OrNot(ISpecification<T> other);
ISpecification<T> Not();
}
public abstract class LinqSpecification<T> : CompositeSpecification<T>
{
public abstract Expression<Func<T, bool>> AsExpression();
public override bool IsSatisfiedBy(T candidate) => AsExpression().Compile()(candidate);
}
public
{
public abstract bool IsSatisfiedBy(T candidate);
public ISpecification<T> And(ISpecification<T> other) => new AndSpecification<T>(this, other);
public ISpecification<T> AndNot(ISpecification<T> other) => new AndNotSpecification<T>(this, other);
public ISpecification<T> Or(ISpecification<T> other) => new OrSpecification<T>(this, other);
public ISpecification<T> OrNot(ISpecification<T> other) => new OrNotSpecification<T>(this, other);
public ISpecification<T> Not() => new NotSpecification<T>(this);
}
public class AndSpecification<T> : CompositeSpecification<T>
{
private ISpecification<T> _left;
private ISpecification<T> _right;
public AndSpecification(ISpecification<T> left, ISpecification<T> right)
{
_left = left;
_right = right;
}
public override bool IsSatisfiedBy(T candidate) => _left.IsSatisfiedBy(candidate) && _right.IsSatisfiedBy(candidate);
}
public class AndNotSpecification<T> : CompositeSpecification<T>
{
private ISpecification<T> _left;
private ISpecification<T> _right;
public AndNotSpecification(ISpecification<T> left, ISpecification<T> right)
{
}
public override bool IsSatisfiedBy(T candidate) => _left.IsSatisfiedBy(candidate) && !_right.IsSatisfiedBy(candidate);
}
public class OrSpecification<T> : CompositeSpecification<T>
{
private ISpecification<T> _left;
private ISpecification<T> _right;
public OrSpecification(ISpecification<T> left, ISpecification<T> right)
{
_left = left;
_right = right;
}
public override bool IsSatisfiedBy(T candidate) => _left.IsSatisfiedBy(candidate) || _right.IsSatisfiedBy(candidate);
}
public class OrNotSpecification<T> : CompositeSpecification<T>
{
private ISpecification<T> _left;
private ISpecification<T> _right;
public OrNotSpecification(ISpecification<T> left, ISpecification<T> right)
{
_right = right;
}
public override bool IsSatisfiedBy(T candidate) => _left.IsSatisfiedBy(candidate) || !_right.IsSatisfiedBy(candidate);
}
public class NotSpecification<T> : CompositeSpecification<T>
{
ISpecification<T> other;
public NotSpecification(ISpecification<T> other) => this.other = other;
public override bool IsSatisfiedBy(T candidate) => !other.IsSatisfiedBy(candidate);
}
</syntaxhighlight>
===
{{Further|Python (programming language)}}
<syntaxhighlight lang="python">
from abc import ABC, abstractmethod
Line 279:
</syntaxhighlight>
===
{{Further|C++}}
<syntaxhighlight lang="cpp">
template <class T>
Line 422 ⟶ 423:
</syntaxhighlight>
===
{{Further|TypeScript}}
<syntaxhighlight lang="typescript">
export interface ISpecification {
Line 511 ⟶ 512:
==Example of use==
In the
# they are overdue,
Line 517 ⟶ 518:
# they are not already with the collection agency.
This example is meant to show the
This usage example assumes a previously defined <code>OverdueSpecification</code> class that is satisfied when an invoice's due date is 30 days or older, a <code>NoticeSentSpecification</code> class that is satisfied when three notices have been sent to the customer, and an <code>InCollectionSpecification</code> class that is satisfied when an invoice has already been sent to the collection agency.
Using these three specifications, we created a new specification called <code>SendToCollection</code> which will be satisfied when an invoice is overdue, when notices have been sent to the customer, and are not already with the collection agency.
<syntaxhighlight lang="csharp">
var
var
var
//
var
var
foreach (var
{
if (sendToCollection.IsSatisfiedBy(invoice))
{
invoice.SendToCollection();
}
}
Line 553 ⟶ 556:
* [https://web.archive.org/web/20110724151447/http://www.dpdk.nl/opensource/specification-pattern-for-selection-on-lists specification pattern in flash actionscript 3] by Rolf Vreijdenberger
{{Design
[[Category:Architectural pattern (computer science)]]
[[Category:Software design patterns]]
[[Category:Programming language comparisons]]
<!-- Hidden categories below -->
[[Category:Articles with example C Sharp code]]
[[Category:Articles with example C++ code]]
[[Category:Articles with example JavaScript code]]
[[Category:Articles with example Python (programming language) code]]
|