Tu préfères quoi :
Tu me diras que c'est juste du sucre syntaxique... Je te répondrais que oui, mais qu'est-ce qui n'en est pas ?Code:
1
2 truc.setProp(machin.getProp()); truc.Prop = machin.Prop;
Version imprimable
Ce qui me dérange avec les propriétés en java, c'est que lorsque je crée de simples POJO destinés à servir par exemple de parameter objects, le standard "m'oblige" à demander à mon IDE de générer 50 lignes de bouse pour polluer ma classe.
Et si je manque de bol, ces méthodes faisant partie d'une API publique, je suis obligé de documenter ces bêtises à double lorsque j'ai des choses intéressantes à raconter sur la propriété, ce qui arrive tout de même malheureusement assez souvent.
Bien que je m'y conforme, j'ai toujours trouvé assez débile de devoir générer des get/set partout. Je triche en utilisant lombok lorsque c'est possible. C'est un point que je trouve mieux réussi dans scala dont la syntaxe autorise de laisser visible un membre public et de le passer plus tard en propriété intelligente sans casser le code à la compilation.
Ca évite d'écrire de la plomberie tout en préservant cette (soi-disant) encapsulation si chère aux yeux du monde.
Ok c'est vrai que l'autoproperty c'est top pour les DTO, et pour les copies de propriété c'est plus clean.
En même temps comme j'ai toujours aimé les interfaces fluides et que j'utilise cela énormément pour coder ainsi que du pattern factory (mécaniquement), j'avoue que même en C# j'utilise des méthodes pour setter
donc pour moi c parfois plus verbeux en Java, mais pour l'utilisateur de l'API, généralement ça ne change rien.Code:
1
2
3
4
5
6 var _instance =NonsenseObject.CreateNewEmpty() .MakeSense(true) .BuildChaosOrganiser(false) .FinalySetIteration(3000) .BuildObject();
Sauf effectivement les lambda si j'utilise une convention de paramètres dans un singleton.
En C# 3.0, tu peux initialiser avec les appels de propriétés:
Code:MaClasse obj = new MaClasse() { Prop=toto, Prop2=tata };
En même temps, avec .NET 4, tu peux faire :
Code:
1
2
3
4
5 class Truc{ public Truc(int a=0, int b=2, int c=4, string machin="bidule"){...} } new Truc(b:3, machin:"trucmuche");
conceptuellement, je ne comprends pas comment on peut penser objet sans penser ses constructeurs.
Au contraire, toutes les possibilités de création d'un objet devrait être connues et maitrisées. C'est d'ailleurs une des problèmatiques qu'adresse l'ioc.
Donc tu ne peux jamais tester correctement ton objet, vu que tu ne sais pas si le testeur ou même le code du test l'instancient correctement.Citation:
La différence c'est que dans le cas des propriétés, tu n'es pas obligé de créer un grand nombre de constructeurs avec toutes les surcharges possibles pour initialiser.
Et pour le problème de construction, il y a justement les concepts de fabriques qui sont intéressants.
Ca aussi c'est un argument contre les "mauvais programmeurs".
En pratique, tu vas pas t'amuser à instancier un objet à coup de memberinit sur des membres privés.
Tu vas pas non plus t'amuser à instancier un objet manuellement, en dehors de son constructeur...
Quand tu fais du memberinit, tu appelles un constructeur, et ensuite tu initialises des propriétés. En gros, ça te permet de faire ça :
Sauf que c'est légèrement plus lisible :Code:
1
2
3
4
5
6 Truc truc = new Truc(); truc.setBidule(bidule); Machin m = new Machin(chose); m.setFoo(bar); m.setPlop(ploup); m.setBidule(truc);
Après, c'est une question de goût, mais y'a aucune différence entre les deux.Code:
1
2
3
4
5 var m = new Machin(chose){ Foo = bar, Plop = ploup, Bidule = new Truc { Bidule = bidule } };
Je rappelle que les propriétés en C# sont traduites en getter/setter en CIL, que les divers "sucres syntaxiques" autour des constructeurs ou des appels de méthodes avec paramètre par défaut sont aussi convertis en l'équivalent qui va bien...
Bref, y'a aucune histoire de rupture d'encapsulation derrière tout ça.
L'initialisation ne marche que sur les publics, bien sûr.
Et le problème du "Ouin il faut utiliser que les constructeurs" est tout aussi présent en Java.
Ben si quelque part si tu dois attacher une propriété non initialisée à la construction, la plupart du temps c'est une composition.
Par soucis de maintenance, j'utiliserai une méthode avec une signature explicite.
Je comprends bien que ce soit lpus lisible ou plus simple, ça ne veut pas pour autant dire que c'est bien ou mieux.
Genre, tu feras truc.setMachin(..) ?
Comme dit plus haut, y'a pas de différence entre propriété et getters/setters. C'est que du sucre syntaxique.
Rien t'empêche de mettre une grosse méthode derrière ton getter ou setter de propriété...
En fait, la seule différence entre les deux (Java et .NET, ici), c'est qu'en Java, tu n'as pas ce sucre syntaxique pour les propriétés.
Avoir un choix syntaxique (plus lisible qui plus est) n'est pas une bonne chose parce que celui-ci induit des différences fonctionnelles (qui n'existent pas) ?..
Comme si y'avait pas d'attribut qui empêche la sérialisation...
Ce qui en fait un avantage des propriétés sur les getters/setters: Choix contre absence de choix.