Dans notre application Delphi 2007, nous utilisons un grand nombre des constructions suivantes
FdmBasic:=TdmBasicData(FindOwnerClass(AOwner,TdmBasicData));
FindOwnerClass parcourt la hiérarchie Propriétaire du composant actuel vers le haut pour rechercher une classe spécifique (dans l'exemple TdmBasicData). L'objet résultant est stocké dans la variable de champ FdmBasic. Nous l'utilisons principalement pour transmettre des modules de données.
Exemple: lors de la génération d'un rapport, les données résultantes sont compressées et stockées dans un champ Blob d'une table accessible via un module de données TdmReportBaseData. Dans un module distinct de notre application, il existe une fonctionnalité pour afficher les données du rapport sous une forme paginée à l'aide de ReportBuilder. Le code principal de ce module (TdmRBReport), utilise une classe TRBTempdatabase pour convertir les données de blob compressées en différentes tables qui sont utilisables dans le Reportdesigner d'exécution Reportdesigner. TdmRBReport a accès à TdmReportBaseData pour toutes sortes de données liées au rapport (type de rapport, paramètres de calcul de rapport, etc.). TRBTempDatabase est construit dans TdmRBReport mais doit avoir accès à TdmReportBasedata. Donc, cela se fait maintenant en utilisant la construction ci-dessus:
constructor TRBTempDatabase.Create(aOwner: TComponent);
begin
inherited Create(aOwner);
FdmReportBaseData := TdmRBReport(FindOwnerClass(Owner, TdmRBReport)).dmReportBaseData;
end;{- .Create }
Mon sentiment est que cela signifie que TRBTempDatabase connaît beaucoup de son propriétaire, et je me demandais s'il s'agissait d'une sorte d'odeur de code ou d'Anti-pattern.
Qu'en pensez-vous? Est-ce une odeur de code? Si oui, quelle est la meilleure façon?
la source
Réponses:
Ce type ressemble à un modèle de localisateur de service qui a été décrit pour la première fois par Martin Fowler (qui a été identifié comme un anti-modèle commun).
L'injection de dépendances basée sur la construction est préférée à un localisateur de services car elle favorise la visibilité des paramètres requis et facilite les tests unitaires plus simples.
De plus, il enfreint également la loi de Déméter
La meilleure façon
En fait, la meilleure façon est de supprimer l'appel du localisateur de service au sein de la classe et de passer le bon propriétaire en tant que paramètre à l'intérieur de son constructeur. Même si cela signifie que vous avez une classe de service qui effectue une recherche de propriétaire puis la transmet au constructeur de classe
la source
As a simple example, when one wants to walk a dog, it would be folly to command the dog's legs to walk directly; instead one commands the dog and lets it take care of its own legs.
L'une des difficultés avec les objets enfants en sachant trop sur le parent est que vous finissez par mettre en œuvre des modèles qui peuvent (et le plus souvent) devenir trop étroitement couplés, ce qui crée des maux de tête de dépendance majeurs et devient souvent très difficile à modifier et à maintenir en toute sécurité plus tard. plus tard.
Selon la profondeur de connexion de vos deux classes, cela ressemble un peu à la description de Fowler de la fonctionnalité Envie ou des odeurs de code d'intimité inappropriées.
Il semble qu'il soit nécessaire de charger ou de lire une classe avec des données, auquel cas vous pouvez utiliser un certain nombre de modèles alternatifs pour briser la dépendance entre l'enfant et sa chaîne de parents, et il semble que vous devez déléguer la tâche d'accéder à votre classe de données plutôt que de rendre la classe d'accesseur de données responsable de tout faire elle-même.
la source