Specification pattern: Difference between revisions

Content deleted Content added
m Add c++ sample code
Line 275:
return not self.subject.is_satisfied_by(candidate)
 
</syntaxhighlight>
 
=== [[C++ (programming language)|C++]] ===
<syntaxhighlight lang="cpp">
template <class T>
class ISpecification
{
public:
virtual ~ISpecification() = default;
virtual bool IsSatisfiedBy(T Candidate) = 0;
virtual ISpecification<T>* And(ISpecification<T>& Other) = 0;
virtual ISpecification<T>* AndNot(ISpecification<T>& Other) = 0;
virtual ISpecification<T>* Or(ISpecification<T>& Other) = 0;
virtual ISpecification<T>* OrNot(ISpecification<T>& Other) = 0;
virtual ISpecification<T>* Not() = 0;
};
 
template <class T>
class CompositeSpecification : public ISpecification<T>
{
public:
virtual bool IsSatisfiedBy(T Candidate) override { return false; }
 
virtual ISpecification<T>* And(ISpecification<T>& Other) override;
virtual ISpecification<T>* AndNot(ISpecification<T>& Other) override;
virtual ISpecification<T>* Or(ISpecification<T>& Other) override;
virtual ISpecification<T>* OrNot(ISpecification<T>& Other) override;
virtual ISpecification<T>* Not() override;
};
 
template <class T>
class AndSpecification final : public CompositeSpecification<T>
{
public:
ISpecification<T>& Left;
ISpecification<T>& Right;
 
AndSpecification(ISpecification<T>& InLeft, ISpecification<T>& InRight)
: Left(InLeft),
Right(InRight) { }
 
virtual bool IsSatisfiedBy(T Candidate) override
{
return Left.IsSatisfiedBy(Candidate) && Right.IsSatisfiedBy(Candidate);
}
};
 
template <class T>
ISpecification<T>* CompositeSpecification<T>::And(ISpecification<T>& Other)
{
return new AndSpecification<T>(*this, Other);
}
 
//
template <class T>
class AndNotSpecification final : public CompositeSpecification<T>
{
public:
ISpecification<T>& Left;
ISpecification<T>& Right;
 
AndNotSpecification(ISpecification<T>& InLeft, ISpecification<T>& InRight)
: Left(InLeft),
Right(InRight) { }
 
virtual bool IsSatisfiedBy(T Candidate) override
{
return Left.IsSatisfiedBy(Candidate) && !Right.IsSatisfiedBy(Candidate);
}
};
 
template <class T>
class OrSpecification final : public CompositeSpecification<T>
{
public:
ISpecification<T>& Left;
ISpecification<T>& Right;
 
OrSpecification(ISpecification<T>& InLeft, ISpecification<T>& InRight)
: Left(InLeft),
Right(InRight) { }
 
virtual bool IsSatisfiedBy(T Candidate) override
{
return Left.IsSatisfiedBy(Candidate) || Right.IsSatisfiedBy(Candidate);
}
};
 
template <class T>
class OrNotSpecification final : public CompositeSpecification<T>
{
public:
ISpecification<T>& Left;
ISpecification<T>& Right;
 
OrNotSpecification(ISpecification<T>& InLeft, ISpecification<T>& InRight)
: Left(InLeft),
Right(InRight) { }
 
virtual bool IsSatisfiedBy(T Candidate) override
{
return Left.IsSatisfiedBy(Candidate) || !Right.IsSatisfiedBy(Candidate);
}
};
 
template <class T>
class NotSpecification final : public CompositeSpecification<T>
{
public:
ISpecification<T>& Other;
 
NotSpecification(ISpecification<T>& InOther)
: Other(InOther) { }
 
virtual bool IsSatisfiedBy(T Candidate) override
{
return !Other.IsSatisfiedBy(Candidate);
}
};
 
template <class T>
ISpecification<T>* CompositeSpecification<T>::AndNot(ISpecification<T>& Other)
{
return new AndNotSpecification<T>(*this, Other);
}
 
template <class T>
ISpecification<T>* CompositeSpecification<T>::Or(ISpecification<T>& Other)
{
return new OrSpecification<T>(*this, Other);
}
 
template <class T>
ISpecification<T>* CompositeSpecification<T>::OrNot(ISpecification<T>& Other)
{
return new OrNotSpecification<T>(*this, Other);
}
 
template <class T>
ISpecification<T>* CompositeSpecification<T>::Not()
{
return new NotSpecification<T>(*this);
}
</syntaxhighlight>