Dans le discours de réflexion de Rich Hickey sur la conférence goto " La valeur des valeurs " à 29 minutes, il parle des frais généraux d'un langage comme Java et fait une déclaration comme, "Toutes ces interfaces tuent votre réutilisation." Que veut-il dire? Est-ce vrai?
Dans ma recherche de réponses, je suis tombé sur:
Le principe de moindre connaissance AKA The Law of Demeter qui encourage les interfaces API hermétiques. Wikipedia répertorie également certains inconvénients.
Kevlin Henney Imperial Clothing Crisis qui fait valoir que l'utilisation, et non la réutilisation, est l'objectif approprié.
Le discours de " Stop Writing Classes " de Jack Diederich qui plaide contre la suringénierie en général.
De toute évidence, tout ce qui est écrit assez mal sera inutile. Mais comment l'interface d'une API bien écrite empêcherait-elle l'utilisation de ce code? Il y a des exemples à travers l'histoire de quelque chose fait pour un but étant utilisé plus pour autre chose . Mais dans le monde du logiciel, si vous utilisez quelque chose dans un but auquel il n'était pas destiné, il se brise généralement.
Je cherche un bon exemple d'une bonne interface empêchant une utilisation légitime mais involontaire de code. Cela existe-t-il? Je ne peux pas l'imaginer.
Je n'ai pas regardé la présentation complète de Rich Hickey, mais si je le comprends bien, et à en juger par ce qu'il dit à propos de la marque des 29 minutes, il semble se disputer sur les types tuer la réutilisation. Il utilise vaguement le terme "interface" comme synonyme de "type nommé", ce qui est logique.
Si vous avez deux entités { "name":"John" }
de type Person
et { "name": "Rover" }
de type Dog
, en Java-land, ils ne peuvent probablement pas interagir à moins de partager une interface ou un ancêtre commun (comme Mammal
, ce qui signifie écrire plus de code). Ainsi, les interfaces/types ici "tuent ta réutilisation": même si Person
et Dog
se ressemblent, l'une ne peut pas être utilisée de manière interchangeable avec l'autre, sauf si vous écrivez du code supplémentaire pour le supporter. Remarque Hickey plaisante également sur les projets dans Java nécessitant beaucoup de classes ("Qui ici a écrit une Java utilisant seulement 20 classes?")), Ce qui semble être un conséquence de ce qui précède.
Dans les langages "axés sur les valeurs", cependant, vous n'affecterez pas de types à ces structures; ce ne sont que des valeurs qui partagent la même structure (dans mon exemple, elles ont toutes deux un champ name
avec une valeur String) et peuvent donc facilement interagir, par exemple ils peuvent être ajoutés à la même collection, passés aux mêmes méthodes, etc.
Pour résumer, tout cela semble être quelque chose à propos de égalité structurelle vs égalité explicite de type/interface . Sauf si j'ai raté quelque chose dans les parties de la vidéo que je n'ai pas encore regardées :)
Il fait probablement référence au fait fondamental qu'une interface ne peut pas être instanciée. Vous ne pouvez pas reuse
une interface. Vous ne pouvez implémenter que du code qui le prend en charge et lorsque vous écrivez du code pour une interface, il n'y a pas de réutilisation.
Java a l'habitude de fournir des cadres de nombreuses API qui prennent une interface en argument, mais l'équipe qui a développé l'API n'a jamais implémenté un large éventail de classes pour vous réutiliser avec ces interfaces.
C'est un peu comme un framework GUI qui a une interface IWindow
pour une boîte de dialogue, et ensuite vous pouvez ajouter des interfaces IButton
pour les contrôles. Sauf qu'ils ne vous ont jamais donné une bonne classe Button
qui implémente IButton
. Il vous reste donc à créer le vôtre.
Les frameworks abstraits qui ont un large éventail de classes de base fournissant des fonctionnalités de base sont plus réutilisables, et cela fonctionne mieux lorsque ces classes abstraites sont accessibles à ceux qui utilisent le framework.
Les développeurs Java ont commencé à faire cette chose où leurs couches API exposaient uniquement interfaces
. Vous pouvez implémenter ces interfaces, mais vous ne pouvez jamais réutiliser les classes du développeur qui a implémenté ces interfaces. C'est un peu comme un style de cape et de poignard de développement d'API.
Je pense que la diapositive 13 lors de sa présentation ( La valeur des valeurs ) aide à comprendre ceci:
Valeurs
- N'avez pas besoin de méthodes
- Je peux vous envoyer des valeurs sans code
et tout va bien
D'après ce que je comprends, Hickey suggère que si je dois, par exemple, doubler la valeur que vous m'avez envoyée, j'écris simplement du code ressemblant à
MyValue = Double(YourValue)
Vous voyez, le code ci-dessus est le même, peu importe la valeur que vous avez envoyée - une sorte de réutilisation parfaite.
Maintenant, à quoi cela ressemblerait-il dans le langage ayant des objets et des interfaces?
Doublable MyValue = YourValue.Double()
oh, attendez! que faire si YourValue
n'implémente pas Doublable
? non pas qu'il ne puisse pas être doublé, il peut parfaitement l'être mais ... et s'il n'y a tout simplement pas de méthode Double
? (et s'il y a une méthode appelée say TwiceAsMuch
?)
Euh oh nous avons un problème. YourValue.Double
ne fonctionnera pas, il ne peut plus être réutilisé . D'après ma lecture de la diapositive ci-dessus, il s'agit de ce que Hickey voulait dire quand il a dit: "Toutes ces interfaces tuent votre réutilisation!"
Vous voyez, les interfaces supposent que les objets sont transmis "avec leurs méthodes", ainsi que le code qui fonctionne sur ces derniers. Pour utiliser des objets, il faut comprendre comment appeler ce code, quelle méthode appeler.
Lorsque prévu méthode est manquant, il y a un problème, même si sémantiquement, l'opération souhaitée est parfaitement logique pour un objet. Comme indiqué dans la présentation, les valeurs ne font pas besoin méthodes ("je peux vous envoyer des valeurs sans code et vous êtes bien"), permettant d'écrire du code les traitant de manière générique.
Note latérale: notion de passer autour valeurs sans code me rappelle en quelque sorte un Flyweight pattern dans OOP.
un objet qui minimise l'utilisation de la mémoire en partageant autant de données que possible avec d'autres objets similaires; c'est une façon d'utiliser des objets en grand nombre lorsqu'une simple représentation répétée utiliserait une quantité de mémoire inacceptable ... Les objets poids mouche sont par définition objets de valeur . L'identité de l'instance d'objet est sans conséquence, donc deux instances Flyweight de même valeur sont considérées comme égales ...
Les utilisations de Flyweight que j'ai vues ont généralement suivi la même approche de suppression du code (méthodes, interfaces) des objets et de transmission de trucs autour, ainsi, valeurs sans code, s'attendant à ce que la réception du code dispose des moyens nécessaires pour les exploiter.
Cela ressemble à peu près à la diapositive, "les valeurs n'ont pas besoin de méthodes. Je peux vous envoyer des valeurs sans code et tout va bien".
Dans un monde idéal (c'est-à-dire mon), les classes et les interfaces décrivent toujours le comportement, mais le fait est que trop souvent elles finissent vraiment par décrire des données. Hier encore, j'ai regardé la vidéo de quelqu'un construire une soi-disant classe BankAccount
qui n'était rien de plus qu'une int
glorifiée (en effet, elle était beaucoup moins utile qu'une int
, donc ' tuant "la réutilisation que j'aurais eue si elle avait simplement été laissée comme int
), le tout au nom d'un" bon "design. La quantité de code, de sueur et de larmes gaspillée à réinventer continuellement des représentations alambiquées de données est stupéfiante; si vous n'utilisez pas les données de manière significative, laissez-les simplement.
Maintenant, c'est l'étape où Rich Hickey se contente de jeter le bébé avec l'eau du bain et de dire que nous devrions tous aller vivre au pays des valeurs (un voisin du royaume des noms). Je pense, d'un côté, que OOP peut et favorise la réutilisation (et surtout la découverte, ce que je trouve manquant dans la programmation fonctionnelle) lorsqu'il est utilisé judicieusement. Si vous recherchez un OOP principe qui capture le mieux cette tension, je pense que cela pourrait être http://c2.com/cgi/wiki?TellDontAsk (qui bien sûr est un proche cousin de Demeter)