Pregunta

¿Hay una manera de definir un método, que se llama cada vez que llame a un conseguir?

Tengo un objeto de contacto y no quiero establecer updateLastUsed (); en unos 30 Compuestos absorbentes para perfeccionar mis miembros.

¿Fue útil?

Solución

Me hubiera sugerido AOP pero si es J2ME estamos hablando de que es más probable mejor manualmente insertando "onGetCalled ()" en cada una de sus 30 descriptores de acceso y luego codificar lo que necesite dentro de ese método. Es posible que desee transmitir en nombre del método que se llama (o propiedad acceder) en caso de que lo necesite en el futuro.

Otros consejos

En lugar de acceder al comprador para sus propiedades, se puede crear un captador general, que lleva el nombre de la propiedad como una entrada. El tipo de retorno tendría que ser objeto si sus propiedades son de diferentes tipos.

En este captador general, se llama a la propiedad de captador y el método updateLastUsed (). Para ser hacer un uso seguro todos los captadores de propiedad privada.

Puede añadir en una llamada a cada método (aburrido), o utilizar algún tipo de AOP (por ejemplo AspectJ, a continuación para un ejemplo) para que coincida con getters del tipo y llamar al método updateLastUsed ().

Edit: Varias personas han señalado 30 getters es un olor de código y la invocación de otro método es un efecto secundario. la primera declaración es un buen indicador, pero no es una regla. Podría haber muchas razones para tener este tipo de tipo, sin más información que lo dejaría como asesoramiento para comprobar si se puede separar responsabilidades en dos o más tipos.

El otro punto sobre los efectos secundarios puede o puede no ser relevante. Hay numerosas cuestiones transversales que hace sens que se aplican a los métodos getter. Por ejemplo el registro, autenticación y el almacenamiento en caché. El ejemplo de método updateLastUsed () podría ser parte de una estrategia de almacenamiento en caché, la crítica de manera incondicional de la cuestión no es merecida en mi opinión.

Un ejemplo de cómo implementar el punto de corte y asesoramiento en AspectJ es el siguiente:

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

Algo así como AOP sería necesaria para hacer esto. No sé qué tan bien que es apoyado en J2ME que no sea esta .

Además de AOP, se puede utilizar un java.lang.reflect.Proxy, o la manipulación de código de bytes ...

Pero no en J2ME

Yo recomiendo llamar updateLastUsed () 30 veces.

Esto parece un trabajo de programación orientada a aspectos (AOP).

Definición de un aspecto a ser ejecutado por cualquier cosa que empieza con get*

El "nuevo" AspectJ 5 cosas apoya el uso de anotaciones para definir puntos de corte de aspecto por lo que podría anotar sus captadores tener llamar a un punto de corte @Before ejecutar el cuerpo del método.

Utilice una expresión regular para añadir la llamada al método getter a las cabeceras.

Buscar:

  

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

Reemplazar con:

  

\0updateLastUsed();\1

Estas expresiones se ensayaron usando Eclipse 3.5 (Galileo) usando "Reemplazar todo" en el "Buscar / Reemplazar" de diálogo.

Tenga en cuenta que el editor que utilice debe contribuir a adecuar múltiples (o tiene que activarlo). Para EmEditor 8.05, tuve que modificar la cadena de búsqueda a ser:

  

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

de modo que la nueva línea se corresponde de forma explícita. La cadena de reemplazo permanece como es.

Se puede hacer algo de fantasía, pero la verdad es por eso macros se añadieron a los editores, por lo que se puede repetir rápidamente código aburrido.

Me acaba de hacer que el método a ser llamado por todos los captadores, y luego usar una macro para crear la llamada (si es necesario para diferir en el método). Todo esto sólo se tiene que hacer una vez y luego sólo olvidarse de él ...

Aquí está una manera. No es bonita, pero es posible que prefiera a la repetición:

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

Obviamente, mi get () se acaba de incrementar accessCount, y usted querrá algún otro comportamiento, pero la idea está ahí.

Yo diría Proxify el objeto para llamar al método deseado.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top