Question

Est-il possible de définir une méthode, qui est appelée chaque fois que j'appeler obtenir?

J'ai un contact d'objets et ne veux pas mettre updateLastUsed (); dans environ 30 absorbantes pour parfaire mes membres.

Était-ce utile?

La solution

Je l'ai suggéré AOP mais si elle est J2ME dont nous parlons, vous êtes très probablement mieux manuellement insérer « onGetCalled () » dans chacun de vos 30 accesseurs puis coder tout ce que vous avez besoin dans cette méthode. Vous voudrez peut-être passer nom de la méthode appelée (ou propriété accessible) dans le cas où vous avez besoin dans l'avenir.

Autres conseils

Au lieu d'accéder au getter pour vos propriétés, vous pouvez créer un getter général qui prend le nom de la propriété en entrée. Le type de retour devrait être objet si vos propriétés sont de différents types.

Dans ce getter général que vous appelez le getter de la propriété et la méthode updateLastUsed (). Pour être SÛRETÉ tous les apporteurs de propriété privée.

Vous pouvez ajouter dans un appel à toutes les méthodes (ennuyeux), ou utiliser une certaine forme d'AOP (par exemple AspectJ, exemple ci-dessous) pour correspondre aux apporteurs du type et les appeler la méthode updateLastUsed ().

Edit: Plusieurs personnes ont signalé 30 getters est une odeur de code et d'invoquer une autre méthode est un effet secondaire. la première déclaration est un bon indicateur, mais pas une règle. Il pourrait y avoir de nombreuses raisons d'avoir ce genre de type, sans plus d'informations je partirais comme des conseils pour vérifier si vous pouvez séparer les responsabilités en deux ou plusieurs types.

L'autre point sur les effets secondaires peuvent ou non être pertinent. Il y a de nombreuses questions transversales, il fait sens à appliquer aux méthodes getter. Par exemple l'enregistrement, l'authentification et la mise en cache. L'exemple méthode updateLastUsed () pourrait faire partie d'une stratégie de mise en cache, la critique si non qualifié de la question est imméritée à mon avis.

Un exemple de la façon de mettre en œuvre la pointcut et des conseils en AspectJ est la suivante:

package test;

public aspect TestAspect {
    /**
     * Match all getters of test.Contact and bind the target.
     */
    protected pointcut contactGetters(Contact contact) : 
        execution(* test.Contact.get*()) && target(contact);

    /**
     * Before execution of each getter, invoke the updateLastUsed() method
     * of the bound target.
     */
    before(Contact contact): contactGetters(contact) {
        contact.updateLastUsed();
    }       
}

serait nécessaire Quelque chose comme AOP pour le faire. Je ne sais pas comment bien soutenu qui est sur J2ME autre que ce .

En plus de l'AOP, vous pouvez utiliser un java.lang.reflect.Proxy, ou la manipulation de bytecode ...

Mais pas sur J2ME

Je recommande d'appeler updateLastUsed () 30 fois.

Cela ressemble à un emploi pour la programmation orientée aspect (AOP).

Définir un aspect à exécuter pour tout ce qui commence par get*

La « nouvelle » trucs AspectJ 5 prend en charge l'utilisation des annotations pour définir aspect pointcuts pour que vous puissiez annoter vos apporteurs d'avoir appeler un @Before pointcut exécution du corps de la méthode.

Utilisez une expression régulière pour ajouter l'appel de méthode pour les en-têtes getter.

Rechercher:

  

\w+ get\w+\s*\(\)\s*\{(\s*)

Remplacer par:

  

\0updateLastUsed();\1

Ces expressions ont été testées à l'aide Eclipse 3.5 (Galileo) en utilisant "Remplacer tout" dans la boîte de dialogue "Rechercher / Remplacer".

Notez que l'éditeur que vous utilisez doit prendre en charge correspondant multiligne (ou vous devez l'activer). Pour EmEditor 8.05, je devais modifier la chaîne de recherche comme:

  

\w+ get\w+\s*\(\)\s*\{\s*(\n\s*)

de telle sorte que la nouvelle ligne est en correspondance explicitement. La chaîne de remplacement reste comme il est.

Vous pouvez faire quelque chose de fantaisie, mais honnêtement c'est pourquoi les macros ont été ajoutées aux éditeurs, de sorte que vous pouvez rapidement répéter le code ennuyeux.

Je voudrais juste faire de la méthode à appeler par tous les apporteurs, puis utiliser une macro pour créer l'appel (si elle devait différer par la méthode). Tout cela ne doit être fait une fois et vous venez de l'oublier ...

Voici une façon. Il est pas joli, mais vous pouvez préférer à la répétition:

public class GetterTest extends TestCase {
    private static class Thing {
        public int  accessCount;
        private String  name;
        private int age;

        private <T> T get(T t) {
            accessCount++;
            return t;
        }

        public String getName() {
            return get(name);
        }

        public int getAge() {
            return get(age);
        }
    }

    public void testGetIncrementsAccessCount() throws Exception {
        Thing t = new Thing();
        assertEquals(0, t.accessCount);
        t.getName();
        assertEquals(1, t.accessCount);
        t.getAge();
        assertEquals(2, t.accessCount);
    }
}

De toute évidence, mon get () est juste incrémentant accessCount, et vous voulez un autre comportement, mais l'idée est là.

Je dirais Proxify l'objet d'appeler la méthode souhaitée.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top