J'ai quelques Il existe différentes façons de Maintenant, je veux ajouter un Je sais que je peux coder le puis i peut aussi avoir chaque sous-classe ajouter un Quelle est la façon commune / la meilleure pratique de faire cela?
Peut-il être fait sans changer les sous-classes? P> Mise à jour forte> p> L'objectif du Q n'est pas sur la bonne façon de concevoir une telle fonctionnalité (qui est assez facile),
mais sur la manière dont cette fonctionnalité peut être basoclass code> avec une méthode
void dosshaniquing () code>.
Fosomething code> et ils sont mis en œuvre par
Sous-classe1 code>,
Sous-classe2 code> et
Sous-Class3 code>. p>
Boolean Active code> Propriété au
basoclass code> de sorte que lorsque
dosomething code> est appelé sur une instance qui reviendrait sans rien faire. p>
Basoclass code> pour avoir
dosomething () code> qui ressemble à quelque chose comme: p>
@Override réellement () code > Au lieu de
@override dosomething () code> dans les sous-classes.
Mais il se sent mal ... En ce sens qu'il a déjà été convenu que les sous-classes devraient fournir une implémentation de
dossomique () code> et ils ne sont pas au courant de
réellement () code> . p>
si (! this.getactive ()) retourner; code> au début de sa mise en œuvre de
DOSMATHIAT () Code> Mais cela semble aussi faux que sa fonctionnalité commune que je préférerais rester communes. P>
actif code> serait vrai, mais il est souhaitable que sur Toute instance de ladite sous-catégorie si quelqu'un appelle
setactive (false) code> alors il deviendra des appels inactifs et consécutifs vers
.Dosomething () code> ne fera rien ... p> p>
3 Réponses :
Je me tromperai peut-être, mais peut-être que vous recherchez la méthode de modèle ou juste chercher le modèle avec Google, il y a de très beaux sites à ce sujet.
J'espère pouvoir aider. P>
Cela n'aide pas non plus parce que cela nécessite à nouveau que je sache à l'avance que je veux avoir cette fonctionnalité ...
Désolé, je n'ai pas vu la section de mise à jour de votre question. Avec cela, je dirais que le motif de décorateur (Prinilpe ouvert) autour de votre classe de base où vous implémentez cette nouvelle fonctionnalité car Marco13 mentionné. Mais bien sûr, les plus agréables soultions peuvent être venues.
Vous voulez utiliser @ArtonD code> conseils de AspectJ et faire quelque chose comme ceci:
BEFORE ======
SubClass1: doSomething() called.
SubClass2: doSomething() called.
SubClass3: doSomething() called.
AFTER ======
Blocking instance<1> method: my.first.spring.aop.aspectj.SubClassN#doSomething([]) !!
Blocking instance<2> method: my.first.spring.aop.aspectj.SubClassN#doSomething([]) !!
Blocking instance<3> method: my.first.spring.aop.aspectj.SubClassN#doSomething([]) !!
Bonjour Alex, je tiens tout d'abord à vous remercier pour une réponse très écrite. C'était très intéressant de lire et peut probablement aider les autres. Malheureusement, je ne peux pas l'utiliser comme j'utilise Java 6 et n'utilise pas le printemps. Et même si ce n'était pas le cas, c'est un peu trop mort pour moi pour que cela puisse ajouter cela. Cela dit, j'accepterai toujours votre réponse en raison de sa haute qualité et j'ajouterai une autre réponse décrivant ce que j'ai fini par faire moi-même.
@EPELEG La solution est compatible avec Java 6. Il suffit de changer maven.compiler.source code> et
maven.compiler.target code> à 1.6. Il est possible d'utiliser AspectJ sans printemps. Cela entraînera plus de travail pour la mise en place de tout.
@EPELEG Voici le code source complet comme une commodité: FileDropper.com/adviceAroundSample
Alors, ce que je ferais, c'est ce que je ferais, c'est le suivant:
Ajouter à la classe de base Une nouvelle signature pour DOSMATHIGHT CODE> P>
@Override
public boolean someThingCanBeDone() {
return base.someThingCanBeDone() && someConditionLocalToTheSubclass;
}
Faites réellement
réellement () code>
abstrait code> et
protégé code> dans votre classe de base. Demandez-le dans les cours d'enfant.
Dosomething () Code> devrait éventuellement être
final code>. En Java, suivez les conventions de nommage Java.
L'intention est donc d'avoir cette fonctionnalité de définition du drapeau
actif code> dans toutes les classes - également dans les dérivés? Si tel est le cas, la solution suggérée par Sotirios Delimanolis semble la plus appropriée. Sinon, en fonction de l'intention réelle, vous pouvez envisager une classe "wrapper" qui déléguette l'appel uniquement lorsque le drapeau est défini - comme
si (actif) déléguée.dosomething () code>
Changé le boîtier de mes méthodes (désolé pour cela). Travailler avec abstraite protégé
réellement_dosomething () code> est une bonne idée si c'est la façon dont les choses sont prévues pour commencer ... Mon Q consiste à changer une situation existante. (Peut-être que la réponse reste la même) ... N'y a-t-il aucune façon raisonnable de faire cela 1) sans introduire de changer les classes? 2) Sans introduire une méthode nouvelle et différente? Que feriez-vous si vous aviez des dizaines ou des centaines de sous-classes pour la baseClass? Serez-vous au HVAE pour tout changer? et tout le code qui les utilise déjà?
@EPELEG À cause du polymorphisme, vous ne pouvez pas forcer un appel sur un objet de sous-classe pour passer d'abord la mise en œuvre du parent. Il y aura des changements considérables à faire. Vous pouvez les minimiser en refactorant d'abord le nom de la méthode de
dosomething () code> à
réellement_dosomething () code> puis changez simplement la classe mère en ajoutant un nouveau
DOSMATHIAT () < / code> méthode.
@Alex, je ne suis pas assez familier avec la programmation orientée forme, et je ne sais pas que je comprends comment utiliser votre commentaire.
J'ai posté une réponse (longue) décrivant en profondeur comment vous pouvez ajouter la fonctionnalité sans rien casser.