如果没有上下文,这很难回答,所以我会尝试围绕我所拥有的信息编造一些东西,希望它能给你一个想法。
像这样创建一个简单的规范接口
interface ISpecification<T>
{
IsSatisfiedBy(T obj);
}
假装你有一个看起来像“银行”的基本界面
interface IBank
{
LedgerCode LedgerCode { get; set; }
}
和 LedgerCodes 的枚举
[Flags]
enum LedgerCodes
{
SUBS, BO, RCC
}
您可以制作一个简单的分类帐代码规范来检查 IBank 的 LedgerCodes(这是非常通用的,您需要根据您的需要使其具体化)
class LedgerCodeSpec : ISpecification<IBank>
{
private LedgerCode code;
public LedgerCodeSpecification(LedgerCode code)
{
this.code = code
}
public override bool IsSatisfiedBy(IBank obj)
{
return obj.LedgerCode == code;
}
}
您可以在适当的地方使用您的规范,在这里我使用它来提供简单的验证。另一个用途是“选择”,例如从存储库中获取数据
class Bank : IBank
{
private ISpecification<IBank> spec;
private LedgerCode code;
public Bank(ISepcification<IBank> spec)
{
this.code = code;
this.spec = spec;
}
public LedgerCode LedgerCode { get; set; }
public bool IsValid
{
get
{
return spec.IsSatisfiedBy(this);
}
}
}
最后是一些代码来快速测试/演示上述内容
class Main
{
public static void Main()
{
var spec = new LedgerCodeSpec(LedgerCodes.SUB)
var blueBank = new Bank(spec);
Console.WriteLine(blueBank.IsValid); // false
blueBank.LedgerCode = LedgerCodes.RCC | LedgerCodes.SUB;
Console.WriteLine(blueBank.IsValid); // false
blueBank.LedgerCode = LedgerCodes.SUB;
Console.WriteLine(blueBank.IsValid); // true
}
}
网上有一些很好的例子,添加了扩展方法和覆盖操作符,以提供简洁且更自然易读的规范,例如
class MessageSpecification : Specification<string>
{
public const int MIN_LENGTH = 5;
public const int MAX_LENGTH = 60;
public override bool IsSatisfiedBy(string s)
{
Specification<string> length = new LengthSpecification(MIN_LENGTH, MAX_LENGTH);
Specification<string> isNull = new IsNullSpecification<string>();
Specification<string> spec = length && !isNull;
return spec.IsSatisfiedBy(s);
}
}
我目前使用该模式的方式可能有点矫枉过正,但我喜欢删除、重用和通常使逻辑更加面向对象的想法。
编辑:在阅读了一些评论之后,您的问题似乎与一般调度问题有关,而不是与规范模式有关。给定您的界面,您可以更简单地做。
class BankFacade
{
public Send(IBlueBank bank)
{
// validate with specification
// do stuff with IBlueBank
}
public Send(IRedBank bank)
{
// validate with specification
// do stuff with IRedBank
}
//...
}
多想一些,你可以做一些类似的事情
class Parser
{
static class RedBankSpecification : ISpecification<XElement>
{
public override bool IsSatisfiedBy(XElement element)
{
return element.Value.equals("RED");
}
}
public void Parse(XDocument doc)
{
var rspec = new RedBankSpecification();
foreach(XElement e in doc)
{
if (r.IsSatisfiedBy(e))
{
IRedBank bank = new RedBank(e);
bankFacade.Send(bank);
}
}
//...
}
}
但是您可能并不真正需要该模式,并且您不应该尝试将问题硬塞到其中