Pergunta

Existe uma maneira de definir um método, que é chamado sempre que eu chamar um get?

Eu tenho um objeto de contato e não quero definir updateLastUsed (); Em cerca de 30 Getters para meus membros.

Foi útil?

Solução

Eu teria sugerido AOP mas se for J2ME estamos falando de você é mais provável melhor fora manualmente inserindo "onGetCalled ()" em cada um de seus 30 assessores e depois de codificação que você precisa dentro desse método. Você pode querer passar em nome do método a ser chamado (ou propriedade acessado) no caso de você precisar dele no futuro.

Outras dicas

Em vez de acessar o getter para suas propriedades, você poderia criar um getter geral que leva o nome da propriedade como uma entrada. O tipo de retorno precisaria ser objeto se suas propriedades são de tipos diferentes.

Neste getter geral você chamar o método updateLastUsed () getter propriedade e. Para ser make segura todos os getters de propriedade privada.

Você pode adicionar em uma chamada para cada método (chato), ou usar alguma forma de AOP (por exemplo AspectJ, abaixo um exemplo) para corresponder getters do tipo e chamar o método updateLastUsed ().

Edit: Várias pessoas têm apontado 30 getters é um cheiro de código e invocando outro método é um efeito colateral. a primeira declaração é um indicador justo, mas não é uma regra. Poderia haver muitas razões para ter este tipo de tipo, sem mais informações que eu deixá-lo como conselho para verificar se você pode separar responsabilidades em dois ou mais tipos.

O outro ponto sobre os efeitos colaterais podem ou não ser relevante. Existem inúmeras preocupações transversais que faz sens para aplicar métodos getter. Por exemplo logging, autenticação e caching. O método exemplo updateLastUsed () pode ser parte de uma estratégia de cache, a crítica de modo inqualificável, a questão não é merecida na minha opinião.

Um exemplo de como implementar o pointcut e aconselhamento em AspectJ é o seguinte:

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 como AOP seria necessário para fazer isso. Eu não sei o quão bem suportada que está em J2ME diferente este .

Além de AOP, você poderia usar um java.lang.reflect.Proxy, ou manipulação de bytecode ...

Mas não no J2ME

Eu recomendo chamando updateLastUsed () 30 vezes.

Isto parece um trabalho para Aspect Oriented Programming (AOP).

A definição de um aspecto a ser executado por qualquer coisa que começa com get*

O "novo" AspectJ 5 material suporta o uso de anotações para definir pointcuts aspecto para que você possa anotar seus getters ter chamar um @Before pointcut executar o corpo do método.

Use uma expressão regular para anexar a chamada de método para os cabeçalhos getter.

Localizar:

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

Substitua por:

\0updateLastUsed();\1

Essas expressões foram testados usando Eclipse 3.5 (Galileo) usando "Substituir Tudo" na caixa de diálogo "Localizar / Substituir".

Note que o editor que você usa deve apoiar correspondência de várias linhas (ou você tem que habilitá-lo). Para EmEditor 8.05, eu tive que modificar a seqüência de pesquisa a ser:

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

para que a nova linha é casado explicitamente. Os restos cadeia de substituição como é.

Você poderia fazer algo extravagante, mas honestamente é por isso que macros foram adicionados aos editores, de modo que você pode código chato rapidamente repetição.

Gostaria apenas de fazer o método a ser chamado por todos os getters, e então usar uma macro para criar a chamada (se necessário para diferem por método). Isso tudo só tem que ser feito uma vez e então você simplesmente esquecer isso ...

Aqui está uma maneira. Não é bonito, mas você pode preferir-lo para a repetição:

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, meu get () é apenas incrementar accessCount, e você vai querer algum outro comportamento, mas a ideia está lá.

Eu diria Proxify o objeto para chamar o método desejado.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top