2009-08-20 5 views
4

Beaucoup de gens connaissent cet article: more on getters and setters. Je pense qu'il fait un travail convaincant de dépeindre le côté diabolique des getters/setters. Je l'ai également testé en essayant de convertir un projet existant (inachevé) en code sans getters/setters. Ça a marché. La lisibilité du code s'est grandement améliorée, moins de code et j'ai même réussi à me débarrasser des getters/setters où j'ai d'abord pensé qu'ils étaient vraiment nécessaires. Sauf pour un endroit.est-ce que les 'getters et setters sont mal' échouent pour le calque de vue?

Obtenir des modèles à la partie vue est l'endroit où je pense que cette approche manque le point. Dans l'article, l'auteur utilise un générateur pour exporter le modèle. Le problème est: il y a autant de contrôle sur ce qui est mis dans le constructeur que ce que vous auriez obtenu avec les getters. Oui, il cache l'implémentation, la façon dont elle est représentée dans le modèle. Mais les getters ne sortent pas du modèle quelque chose de très différent de ce qui a été mis là-dedans. Si vous créez un objet Money en passant '5' à travers le constructeur, money.getAmount() ne retournera pas ce converti dans une autre devise ou dans un tableau avec un élément '5' dedans.

Ce que vous définissez vous obtenez. Et à travers la vue, nous fixons des valeurs, et ces valeurs que nous attendons quand nous leur demandons (obtiennent) d'un objet qui est censé contenir ce que nous avons placé en premier lieu. Un constructeur pour exporter ces derniers attend la même chose.

C'est un peu long pour une question. Mais je voudrais être mis au défi à mon avis. Les getters et les setters sont-ils mauvais pour le transport de données de modèle vers la couche de vue?

Il y a beaucoup de gens qui pensent que les getters/setters ne sont pas mal du tout. Ce n'est pas non plus ce que je voudrais entendre défendre, car je pense qu'ils sont mauvais dans d'autres endroits que ceux que j'ai mentionnés.

+1

Vous devriez voir le livre d'Alan Holub http://www.amazon.com/Holub-Patterns-Learning-Design-Looking/dp/159059388X Il dit beaucoup que les getters et setters sont mauvais et quand ils sont acceptables . Il montre beaucoup d'exaples, donc ce serait trop pour les écrire ici. –

+0

Merci. Je vais y regarder. – koen

Répondre

3

Pour les cas très simples, un objet de données n'a aucun comportement à encapsuler, donc les arguments basés sur l'amélioration de l'encapsulation du comportement ne s'appliquent pas vraiment.

La plupart des vues que j'ai créées ont été pilotées par les événements. Dans une vue pilotée par événement, vous vous enregistrez pour un événement de modification sur le modèle et actualisez la vue lorsque le modèle change, plutôt que de passer le modèle et d'obtenir la valeur de chaque attribut, puis de le mettre à jour. Étant donné que le mécanisme d'événement permet au modèle de pousser son état à la vue, la vue n'a pas besoin de getters pour tirer l'état (et si le modèle est également un écouteur, vous n'avez pas besoin de builders). Si vous ne modifiez qu'un seul attribut dans un modèle avec des milliers d'attributs, dans quelle mesure un générateur et un nouveau modèle transmis à la vue fonctionneraient-ils correctement? Si au lieu de penser à un modèle comme un glob de données, mais plutôt de le considérer comme implémenter un cache dans le transfert des événements de notification d'état de la couche de construction/persistance aux écouteurs/vues, alors il est facile de voir comment il a un comportement qui peut être encapsulé plutôt que d'être purement état qui peut être interrogé.

+1

Le modèle pousse certaines données vers la vue, mais c'est plus ou moins la même chose que d'obtenir les données. Vous attendez-vous à un résultat différent entre StackOverflowPost.getTitle() et StackOverflowPost.RegisterObserver (vue) où la vue obtient alors le titre (get) poussé? – koen

+0

Sur une note de côté: les observateurs ne sont-ils pas utilisés de cette façon pour être avertis quand un «getSomething» change? – koen

+0

'objet de données' est le nom de 'structure' dans tout est un langage objet. –

1

Il existe un autre modèle, utilisé dans le langage Scala, mais qui peut vraiment être utilisé n'importe où. C'est le modèle Constructor/Extractor. Le constructeur est juste cela, le constructeur d'une classe. L'extracteur est une méthode qui, lorsqu'elle est appelée, renvoie les paramètres qui, passés à un constructeur, créent un clone de cet objet. Pour les langages dynamiques, il suffit de retourner une liste et d'en finir avec elle. Pour les langues typées statiquement, vous pouvez passer d'une liste d'objets, qui doivent ensuite être traités pour que chaque type puisse être assigné correctement, ou vous devez avoir une classe tuple paramétrée par type, de sorte que vous puissiez retourner chaque paramètre avec le type correct.

Dans le cas spécifique de Scala, ses extracteurs sont similaires aux méthodes statiques Java et ils reçoivent un objet en entrée.Il renvoie les paramètres, ou il renvoie None, qui exécute une fonction analogue à Java null. L'idée est que vous pouvez décomposer ce que vous avez composé, ce qui correspond à peu près à ce qu'une vue pourrait vouloir. Maintenant, une autre notion que vous pourriez avoir est que "tell, ne demande pas" a l'intention de garder les règles de gestion avec les données auxquelles il s'applique. Maintenant, les règles de gestion d'une vue appartiennent nécessairement à la vue, donc vous vous retrouvez avec le problème de devoir demander au modèle les données ... si vous n'inversez pas le jeu. Le modèle pourrait dire l'affichage pour afficher les données, en lui passant les champs pertinents au lieu d'être demandé pour eux. Ainsi, le modèle indique à la vue d'afficher les données et la vue indique au modèle de les mettre à jour.

Questions connexes