Sans contexte, il est difficile de répondre à cette question. Je vais donc essayer d'inventer quelque chose à partir des informations dont je dispose et j'espère que cela vous donnera une idée.
Créez une interface de spécification simple comme suit
interface ISpecification<T>
{
IsSatisfiedBy(T obj);
}
Supposons que vous disposiez d'une interface de base pour les "banques" ressemblant à ceci
interface IBank
{
LedgerCode LedgerCode { get; set; }
}
Et un enum de LedgerCodes
[Flags]
enum LedgerCodes
{
SUBS, BO, RCC
}
Vous pouvez créer une simple spécification de code de livre pour vérifier les LedgerCodes d'une IBank (ceci est assez général, vous devez le rendre spécifique à vos besoins).
class LedgerCodeSpec : ISpecification<IBank>
{
private LedgerCode code;
public LedgerCodeSpecification(LedgerCode code)
{
this.code = code
}
public override bool IsSatisfiedBy(IBank obj)
{
return obj.LedgerCode == code;
}
}
Le cas échéant, vous pouvez utiliser votre spécification, ici je l'utilise pour fournir une validation simple. Une autre utilisation est la "sélection", par exemple pour obtenir des données d'un référentiel.
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);
}
}
}
Et enfin un peu de code pour tester/démontrer rapidement ce qui précède.
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
}
}
Il existe de bons exemples sur le web qui permettent d'ajouter des méthodes d'extension et de remplacer des opérateurs pour obtenir une spécification succincte et, à mon avis, plus facile à lire.
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);
}
}
La façon dont j'utilise actuellement le modèle est probablement excessive, mais j'aime l'idée de supprimer, de réutiliser et, d'une manière générale, de rendre la logique plus OO.
Edit : après avoir lu certains des commentaires, votre problème semble être plus lié à un problème général de répartition plutôt qu'au modèle de spécification. étant donné vos interfaces, vous pourriez plus simplement faire.
class BankFacade
{
public Send(IBlueBank bank)
{
// validate with specification
// do stuff with IBlueBank
}
public Send(IRedBank bank)
{
// validate with specification
// do stuff with IRedBank
}
//...
}
en réfléchissant un peu plus, vous pourriez faire quelque chose du genre
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);
}
}
//...
}
}
Cependant, il se peut que vous n'ayez pas vraiment besoin du modèle et que vous ne deviez pas essayer d'y intégrer le problème.