"lles finissent côte à côte en mémoire une fois que le constructeur de ta classe à fait son office. Tu maintiens qu'elles n'ont rien à voir entre elles ?
"
Je parle au niveau du sens, je vais pas faire un tableau d'int dès que j'ai plus d'un int en attribut dans une classe non ?
Et j'imagine qu'une fois compilé c'est optimisé tout seul de côté là j'espère
Ou alors j'ai pas compris ce que tu voulais dire
Raspberry-Pi
Merci mais c'est bien ce que je fais, je me demandais juste si il y avait une meilleur solution que de faire une méthode abstraite pour chaque attribut qui doit absolument être initialisé
Ouais le chaînage j'y avais pensé mais ça marche pas trop vu qu'ils doivent avoir un comportement différent et que donc dans tous les cas je dois avoir une classe LoupGarou
Ouais donc en fait ma solution est bonne à priori, ![]()
L'intérêt des immuables, c'est que tu sais que tu peux réutiliser chaque étape précédente sans risquer qu'elle soit souillée par l'ajout de comportements.
human = body.withLegs(2).withArms(2).withHead(1);
quadruped = body.withLegs(4).withHead(1);
cat = quadruped.thatCanMew();
dog = quadruped.thatCanBark();
// Ne changera pas la vie des autres objets ![]()
cat.setHealth(50);
Return_Returns
Ben... Qu'est-ce qui t'empêche dans ta chaîne de changer l'élément auquel est délégué le comportement ? C'est même un des principaux intérêts.
interface Behaviour {
public void move();
...
}
class WerewolfBehaviour() implements Behaviour {
public void move() {
// En cercle;
}
...
}
class WerewolfBehaviour() implements Behaviour {
public void move() {
// En ligne droite;
}
...
}
class Monster {
private Behaviour behaviour
Monster withBehaviour(Behaviour behaviour) {
Monster clone = this.clone();
clone.setBehaviour(behaviour);
return clone;
}
}
monster = new Monster();
humain = monster.withBehaviour(defaultBehaviour);
werewolf = monster.withBehaviour(werewolfBehaviour);
// Avance en ligne droite
humain.getBehaviour().move();
// Tourne en rond
werewolf .getBehaviour().move();
Il fallait bien entendu lire :
class DefaultBehaviour() implements Behaviour {
public void move() {
// En ligne droite;
}
Raspberry-Pi : "le développeur de l'API sera obligé de les implémenter et ne risque pas de les oublier,"
S'il n'a pas lu la doc pour savoir ce qu'il doit implanter, il ne la lira pas plus pour connaître la sémantique des fonctions qu'il faut qu'il implante et il fera nimp.
Return_Returns : "Je parle au niveau du sens"
j'insiste... penses-tu vraiment que tu te fatigues à regrouper des choses qui n'ont pas de sens ensemble ? ![]()
Après, pour cet histoire de tableau, j'attire ton attention sur le fait que j'ai pris soin de mettre "et de structure". De fait, j'avais initialement prévu de parler aussi des dictionnaires, mais j'ignore si ça existe en tant que structure primitive en Java (ça fait trop longtemps que je n'ai pas touché à ça
).
Sinon, encore une fois, ton choix d'opter pour des méthodes abstraites me paraît cohérent.
Quant au chaînage, on ne perdrait pas la const correctness avec cette méthode ? Je veux dire : on ne peut plus déclarer les attributs const avec cette technique, vu qu'on doit fournir des setters.
Chris_27
S'il n'a pas lu la doc/n'a pas d'IDE moderne pour lui indiquer ce qu'il peut faire, oui, il sera bien malheureux. Je serai dans ce cas tenté de faire mon Umberto Eco, s'il n'a pas eu le courage de passer l'étape de la doc, il peut aller se faire foutre et ne mérite pas d'utiliser l'API :D
PS : C'est du java, le problème est résolu : y'a pas de const :D
Plus sérieusement, vu que les setters du chaînage te retournent une nouvelle instance de ton objet, ils conservent la sémantique de la constante.
class Truc {
// A initialiser
private ConstanteImmuable belleConstante;
withBelleConstante(valeur) {
Truc clone = this.clone();
clone.belleConstante = valeur
return clone;
}
getBelleConstante() {
return belleConstante;
}
}
Je pense que ça ferait l'affaire, en java. Par contre, dans le cas de C++, je pense que tu as raison, on ne peut pas passer par const dans ce cas.
Nna, je pense que ca marcherait en C++ aussi (bien sur il faut faire attention a la tonne de copie qui va t'arrive dans la tete, mais peut etre que move constructor aide dans un cas comme ca).
tu peux faire un
Foo Foo::stuff() const {
Foo f (*this);
f.hp=12;
return f;
}
parceque le const porte sur this et pas sur le f qui est dedans
Hum... après vérification, on a effectivement le droit de séparer le "final int x" de la définition de x. Pour le coup, c'est moins con qu'en C++.
Sinon, je n'avais pas fait attention au fait que tu faisais des copies dans tes fonctions de chaînage. C'est tellement évident à mes yeux que c'est moisi niveau perfs que ça ne m'était pas venu à l'esprit.
Du coup, ma question est : pourquoi tu fais des copies ?
godrik : cf ma question ci-dessus. ![]()
Je suis d'accord que ca a l'air naze cote perf. Mais ici, le code est clairement hors du chemin critique de l'application. Ca ressemble a du code de gestion, du coup meme si il etait en ruby ca se passerait bien cote perf. </troll>
Si le garbage collector échoue à libérer la mémoire, tu vas payer ça cher jusqu'à la fin de l'exécution du programme. Et vu les bizarreries du code, je n'en voudrais pas vraiment au GC.
Chris_27
Le chaînage n'est pas destiné à être appelé à très haute fréquence. C'est vraiment pour réaliser ton templating que tu vas appeler la chaîne complète. Les "instances" seront des clones du dernier maillon. L'intérêt du clone, c'est que toutes les opération que tu vas effectuer sur cette copie ne souilleront pas la chaîne permettant de produire d'autres instances de tes objets.
humain = animal.withTruc(ça)...withChose( et enfin ça);
a = humain.clone();
b = humain.clone();
On ne clone que le dernier maillon pour "instancier".
PS : tu as répondu 22 minutes trop tôt, au passage. ![]()
Raspberry-Pi : j'ai du mal à croire ce que tu me racontes. En gros, tu es en train de me dire que tu veux de la persistance juste parce que c'est trop dur de sauvegarder une copie au moment opportun (si tant est que ça servent réelle, ce dont je doute puisqu'on est globalement en train de faire un constructeur déguisé) ?
Et le PS était évidemment pour godrik qui trolle un jeudi soir.
Non, la copie fait selon partie de la philosophie de la solution. Le but est de partager des parties de ta chaîne de configuration et de pouvoir rapidement combiner tes éléments. Ce sont de simples définitions de règles métier. Si tu n'utilises pas de copies, tu vas modifier le maillon précédent de la chaîne et tu ne pourras pas le réutiliser.
Prends 10 km de recul, et relis ce que j'ai écrit. ![]()
Si tu retires la copie, tu es obligé d'appeler la chaîne complète à chaque fois que tu as besoin de créer une instance d'un objet caractérisé par celle-ci.
raspberry,
chris suggere un truc du genre.
human = mamifere.clone();
human.setLegs(2);
human.setHarms(2);
human.setHair("low");
man = human.clone();
man.setMuscle("high");
woman = human.clone();
woman.setMuscle("low");
//pour faire dans le cliche. ![]()
les pro du java doivent être en vaccances"
on est au moins deux à s'être dit qu'on avait pas envie de répondre.
Excuse moi mais c'est surement la première fois en pas loin d'un an que je te vois répondre à un topic java ;) je pensais surtout à Raspberry-Pi pour le coup. Même si le titre fais peur, le sujet est pas ininteressant
godrik
Ah d'accord. Oui, c'est _beaucoup_ mieux, mais "my spidey senses are tingling", je me demande s'il n'y a pas un truc qui m'échappe en terme de souplesse, il faut que je réfléchisse à tête reposée là-dessus...