Pergunta

O que é o equivalente de Java de delegados de cacau?

(eu entendo que eu possa ter uma interface passado para uma classe, e ter essa classe chamar os métodos apropriados, mas eu estou querendo saber se há alguma outra forma de conseguir algo mais próximo de Cacau / protocolos informais de Objective-C)

Foi útil?

Solução

A resposta curta é não há nada em Java o mais perto que você gostaria, mas existem alternativas. O padrão de delegado não é difícil de implementar, é apenas não é tão conveniente como fazê-lo com Objective-C.

A razão "protocolos informais" trabalho em Objective-C é porque os suportes de linguagem categorias , que permitem que você adicione métodos para classes existentes sem subclasse-los, ou mesmo ter acesso ao código-fonte. Assim, a maioria dos protocolos informais são uma categoria em NSObject. Isso é claramente impossível em Java.

Objectivo-C 2.0 opta por métodos de protocolo @optional, que é uma abstracção mais limpa e muito preferido para o novo código, mas ainda mais a partir de ter um equivalente em Java.

Honestamente, a abordagem mais flexível é definir um protocolo de delegado, em seguida, ter aulas de implementar todos os métodos. (Com IDEs modernos, como Eclipse, este é trivial.) Muitas interfaces Java tem uma classe de adaptador que o acompanha, e esta é uma abordagem comum para não exigir que o usuário para implementar uma série de métodos vazios, mas restringe a herança, o que torna inflexível projeto do código . (Josh Bloch aborda esta em seu livro "Effective Java".) Minha sugestão seria a de só fornecer uma interface em primeiro lugar, em seguida, adicione um adaptador se é realmente necessário.

Faça o que fizer, evitar jogar um UnsupportedOperationException para métodos "não implementadas". Isso força o classe delegar a exceções identificador para os métodos que devem ser opcionais. A abordagem correta é implementar um método que não faz nada, retorna um valor padrão, etc. Estes valores devem ser bem documentados para métodos que não têm um tipo de retorno void.

Outras dicas

Melhor analógico para um protocolo informal que posso pensar é uma interface que também tem uma classe de adaptador para permitir implementadores evitar a implementação de cada método.

public class MyClass {

    private MyClassDelegate delegate;

    public MyClass () {

    }

    // do interesting stuff

    void setDelegate(MyClassDelegate delegate) {
        this.delegate = delegate;
    }

    interface MyClassDelegate {
        void aboutToDoSomethingAwesome();
        void didSomethingAwesome();
    }

    class MyClassDelegateAdapter implements MyClassDelegate {

        @Override
        public void aboutToDoSomethingAwesome() {
            /* do nothing */
        }

        @Override
        public void didSomethingAwesome() {
            /* do nothing */
        }
    }
}

Então, alguém pode vir e apenas implementar as coisas que eles se preocupam com:

class AwesomeDelegate extends MyClassDelegateAdapter {

    @Override
    public void didSomethingAwesome() {
        System.out.println("Yeah!");
    }
}

Ou isso, ou puro reflexão chamando "conhecidos" métodos. Mas isso é uma loucura.

Não há nada que você parar de usar o padrão de delegado em seus objetos Java (Não é apenas um padrão comumente usado no JDK como é em Cocoa). Basta ter um ivar delegate de um tipo que está em conformidade com a sua interface de WhateverDelegate, em seguida, em seus métodos de instância que você deseja delegar, encaminhar a chamada de método para o objeto delegado se ele existir. Você provavelmente iria acabar com algo que se parece muito com este , exceto em Java em vez de Obj-C.

Quanto interfaces opcionais ir, isso seria mais difícil. Eu sugeriria que declara a interface, declarando uma classe abstrata que implementa opcional métodos como métodos vazios, e depois uma subclasse da classe abstrata, substituindo os métodos opcionais que deseja este objeto específico de implementar. Há uma limitação potencialmente grave aqui devido à falta de herança múltipla em Java, mas que é tão perto que eu poderia vir acima com.

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