Domanda

C'è un modo per definire un metodo, che è chiamato ogni volta che chiamare un get?

Ho un oggetto contatto e non voglio impostare updateLastUsed (); in circa 30 Getters per i miei soci.

È stato utile?

Soluzione

avrei suggerito AOP ma se è J2ME che stiamo parlando si è più probabile meglio manualmente inserendo "onGetCalled ()" in ciascuna delle vostre 30 funzioni di accesso e quindi la codifica tutto ciò che serve all'interno di tale metodo. Si consiglia di passare nel nome del metodo chiamato (o proprietà accede) in caso di necessità in futuro.

Altri suggerimenti

Invece di accedere al getter per le vostre proprietà, è possibile creare un getter generale che prende il nome della proprietà come input. Il tipo di ritorno avrebbe bisogno di essere oggetto se le proprietà sono di diversi tipi.

In questo getter generale, si chiamano il getter proprietà e il metodo updateLastUsed (). Per essere sicuri make tutti i getter di proprietà privata.

È possibile aggiungere in una chiamata a ogni metodo (noioso), o utilizzare una qualche forma di AOP (ad esempio AspectJ, qui di seguito per un esempio) in modo che corrisponda getter del tipo e chiamare il metodo updateLastUsed ().

Modifica: Diverse persone hanno fatto notare 30 getter è un odore di codice e invocando un altro metodo è un effetto collaterale. la prima affermazione è un indicatore giusto, ma non è una regola. Ci potrebbero essere molte ragioni per avere questo tipo di tipo, senza ulteriori informazioni avrei lasciato come consiglio per verificare se è possibile separare le responsabilità in due o più tipi.

L'altro punto per gli effetti collaterali può o non può essere rilevante. Ci sono numerose preoccupazioni trasversali lo rende sens da applicare getter metodi. Per esempio la registrazione, l'autenticazione, e il caching. Il metodo esempio updateLastUsed () potrebbe essere parte di una strategia di caching, la critica in modo non qualificato della questione è immeritato, a mio parere.

Un esempio di come implementare il pointcut e la consulenza in AspectJ è la seguente:

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();
    }       
}

Qualcosa di simile AOP sarebbe necessaria per fare questo. Non so quanto bene sostenuto che si trova sul J2ME diverso questo .

Inoltre AOP, si potrebbe utilizzare un java.lang.reflect.Proxy, o manipolazione bytecode ...

Ma non su J2ME

Mi consiglia di chiamare updateLastUsed () 30 volte.

Questo appare come un lavoro per Aspect Oriented Programming (AOP).

La definizione di un aspetto che deve essere eseguito per qualsiasi cosa che inizia con get*

Il "nuovo" AspectJ 5 roba supporta l'uso di annotazioni per definire pointcut aspetto così da poter annotare i tuoi getter avere chiamare un @Before pointcut esecuzione del corpo del metodo.

Utilizzare un'espressione regolare per aggiungere la chiamata al metodo alle intestazioni getter.

Ricerca:

  

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

Sostituire con:

  

\0updateLastUsed();\1

Queste espressioni sono state testate con Eclipse 3.5 (Galileo) con "Sostituisci tutto" nella sezione "Trova / Sostituisci" finestra di dialogo.

Si noti che l'editor utilizzato deve supportare corrispondenza multilinea (o devi abilitarlo). Per EmEditor 8.05, ho dovuto modificare la stringa di ricerca di essere:

  

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

in modo che la nuova linea è abbinato in modo esplicito. La stringa di sostituzione rimane come è.

Si potrebbe fare qualcosa di eccezionale, ma devo dire che questo è il motivo per cui le macro sono stati aggiunti per gli editori, in modo da poter ripetere rapidamente il codice noioso.

Vorrei solo fare il metodo di essere chiamato da tutti i getter, e quindi utilizzare una macro per creare la chiamata (se aveva bisogno di differire di metodo). Questo ha tutto solo per essere fatto una volta e poi basta non pensarci più ...

Ecco un modo. Non è abbastanza, ma si potrebbe preferire alla ripetizione:

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);
    }
}

Ovviamente, la mia get () è solo incrementare accessCount, e si vorrà qualche altro comportamento, ma l'idea c'è.

Direi Proxify l'oggetto per chiamare il metodo desiderato.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top