Soit entité A
concerne les entités B
et C
tant que 1: 1 .. *
En même temps B
ne contient qu'une partie de C
« clé s, mais avec A
» s touche, il est possible de relier B
-C
.Quelle est la meilleure façon de transmettre des données supplémentaires pour un flux de travail modifié?
La traduction en langage humain:
Le centre de comptabilité (A) se compose de branches (C), et un flux de paiements (B) provient du centre de comptabilité et contient BranchId qui est unique seulement dans un centre de comptabilité donné . . Wee besoin de vérifier l'exactitude de fourni BRANCHID et attacher le paiement à la Direction)
Nous traitons la collection de B
s:
class BsProcessor
{
private BProcessor _processor;
void ProcessBs(IEnumerable bs)
{
for (var b in bs)
{
_processor.Process(b);
}
}
}
Une des exigences de jour changent, et maintenant BProcessor
doit prendre une décision basée sur C
correspondant.
Du point de vue de la performance, il est préférable d'obtenir à l'avance tous les C
s pour les A
s qui s point à B
, puis transmettre ces données à BProcessor via la modification Process
signature de la méthode.
class BsProcessor
{
private BProcessor _processor;
private CProvider _provider;
void ProcessBs(IEnumerable bs)
{
var aKeys = bs.Select(b => b.aKey);
var cs = _provider.GetCsForAs(aKeys).ToDictionary(c => c.aKey);
for (var b in bs)
{
var cCandidates = cs[b.aKey];
_processor.Process(b, cCandidates);
}
}
}
BProcessor
essaie alors de trouver le C
correspondant.
Ceci est une solution de travail simple et rapide à coder et simple ...
Pour être honnête, je ne l'aime pas du tout. Je pense que cela viole SRP.
Il n'y a pas d'autre raison que la performance pour le BsProcessor
d'être au courant de Cs
.
La logique de trouver C
candidats et les matches appartient ni à BsProcessor
ni à BProcessor
, mais un service dédié CMatcher
class CMatcher
{
private CProvider _provider;
private IEnumerable<aKey> _aKeys;
public CMatcher(CProvider provider, IEnumerable<aKey> aKeys)
{
...
}
public C Match(aKey akey, cPartialKeyFromB partialKey)
{
}
}
Ce service doit être injecté et utilisé par BProcessor
. Comme ce service est contextuelle et nécessite la collecte de aKeys nous devons passer à l'usine:
class BsProcessor
{
private BProcessorFactory _factory;
void ProcessBs(IEnumerable bs)
{
var aKeys = b.Select(b => b.aKey);
var processor = _factory.Create(aKeys);
for (var b in bs)
{
processor.Process(b);
}
}
}
Je pense que cette solution est un peu plus complexe à coder, mais plus facile à tester. Le seul problème que j'ai est que BProcessor
contient plus d'une méthode, et ceux-ci ne doivent pas correspondre C
à B
, par conséquent, il n'est pas bon d'utiliser injection de constructeur, alors que l'injection de méthode fait BsProcessor
savoir environ CMatcher
ce qui est quelque peu similaire à initial Solution.
Ici, il commence à ressembler à BProcessor
mendie être divisé en classes séparées, et je me demande si SRP vaut tant refactoring et où la deuxième approche est en effet mieux que le premier?
Ce que vous proposez est un DDD. Je doute que l'équipe accepte facilement ce changement de paradigme du script de transaction. = (Néanmoins, merci pour la réponse.) –