2

Soirée. J'ai du mal à trouver un modèle de conception approprié pour certaines situations de composition profonde. Permettez-moi de présenter un exemple. Disons que nous avons une classe de type Corporation qui a beaucoup de classes de type Filiale qui ont beaucoup de classes de type Département qui dans le type contiennent plusieurs classes de type Unité qui à leur tour contiennent plusieurs classes de type Employé. Maintenant, supposons que le cas d'utilisation consiste à compter le nombre d'employés pour chaque société. Je pourrais boucler chaque corpration, boucle encore pour chaque filiale, et ainsi de suite, dans quelque chose qui se traduirait par une boucle imbriquée, 4 niveaux de profondeur. De plus, je violerais la loi de Demeter en référençant ma chaîne de classe à plusieurs niveaux en dessous, quelque chose qui est si étroitement coupé qu'il casserait le moment même où j'ai modifié ma chaîne.Composition de classe profonde et la loi de Demeter

Une autre chose que je pourrais faire est d'ajouter des tonnes (ok peut-être pas tonnes, mais quelques-unes) de références de raccourcis. Par exemple, une société peut elle-même contenir une liste d'employés qui ne doivent jamais passer par la chaîne pour les compter. De cette façon, les classes sont moins étroitement couplées (mais le sont-elles?) Et le problème consiste maintenant à maintenir la synchronisation de la liste des employés pour la Corporation et l'Unité. Je pourrais utiliser le modèle Observer pour les garder à jour, mais je pense vraiment que quelque chose ne va vraiment pas avec cette idée ou, à tout le moins, je n'utilise pas vraiment la meilleure solution. Comme je suis sûr que c'est un domaine extrêmement commun, quelqu'un pourrait-il être assez aimable pour me diriger vers un modèle de conception approprié?

Merci.

Répondre

1

Je ne comprends pas exactement la deuxième question, mais je réponds à la première question.

Comme la loi de Déméter stipule que chaque entité doit avoir moins de connaissances sur d'autres unités

Donc, en utilisant ce principe dans votre conception

class Corporation{ 

    //All the stuff about corporation 

    //Don't ask for what's inside corporation 
    public int countEmployees(){ 
     //will apply the logic needed to calculate 
    } 

} 

meilleur code client avec la loi de Déméter :

corporationInstance.countEmployees(); //let the corporation handle how to count and not expose inner details 

Sans loi de Déméter

corporationInstace.getSubsidiaries().getSomethingElse()..... //exposing the inner details of class which creates a chain that is bad. 

MISE À JOUR:

En utilisant la solution indiquée ci-dessus, vous pouvez aller en autant de profondeurs que vous voulez en créant la méthode countEmployees() à l'intérieur Subsidiaries et Unit au besoin. Il est inutile de casser l'encapsulation ou d'utiliser le pattern Observer ici.

Appliquer le Tell Don't ask principe que vous l'avez souligné dans le même commentaire et déléguer la responsabilité du calcul des employés réels sur la classe qui contient les employés.

Department - > uses count method on subsidiaries to add their count 
Subsidiaries - > uses Units to count 
Unit - > Uses employees to count 
+0

C'est ce que je suggérais en mentionnant les méthodes de raccourci. Cependant, si je devais mettre en place un countEmployees(), je devrais avoir, disons, un tableau d'employés, non? Ce qui devrait essentiellement être le même tableau d'employés que la classe Unit contiendrait. Et je devrais les synchroniser, probablement avec un pattern Observer. Est-ce ce que vous suggérez aussi? – ctsag

+0

Personne dont la propriété est Employés? Est-ce de l'unité? Ensuite, vous aurez besoin de faire des méthodes de raccourci pour les filiales, qui à leur tour appellent la méthode de raccourci de l'unité qui contiendrait des employés. Vous n'avez pas besoin d'extraire les employés de la classe d'unité. –

+0

Ainsi, chaque méthode dans une chaîne de classe séquentielle contiendrait une méthode countEmployees() qui appelait la méthode counteEmployees() de la classe suivante. C'est logique je suppose, en ce sens que je peux compter les employés à n'importe quel niveau de la chaîne que je veux. J'aime cette approche, merci pour votre contribution Narendra. Au fait, comment appelleriez-vous ce principe? Est-ce [Tell, ne demandez pas] (http://pragprog.com/articles/tell-dont-ask)? – ctsag

0

que vous voulez envoyer un courriel au client à partir d'un lien ou un bouton. Vous pourriez l'écrire comme customer.getSomeParticularContactInfo (addressType) .sendEmail() ou client.sendEmail() qui appelle ensuite (à l'intérieur du client) getSomeParticularContactInfo ("primary"). sendEmail().

Vous êtes sur la mauvaise voie. Cela casse seule responsabilité, je veux dire, l'objet client n'a pas besoin de savoir, comment envoyer un e-mail, l'objet client est responsable uniquement de la façon de fournir l'adresse e-mail appartient au client. Donc, pour cette fonctionnalité, vous devez créer une autre interface comme Notifier et un EmailNotifier qui implémente Notifier. Par la suite, vous appellerez EmailNotifier.notify (client)

Questions connexes