Pergunta

Eu estava lendo um href="http://puredanger.com/techfiles/090204/Java7Preview.pdf" rel="nofollow noreferrer"> Java 7 apresentação prévia e não havia um slide em Chained Invocation . Aqui está o exemplo utilizado no slide:

// Construction with setters
DrinkBuilder margarita = new DrinkBuilder();
margarita.add("tequila");
margarita.add("orange liqueur");
margarita.add("lime juice");
margarita.withRocks();
margarita.withSalt();
Drink drink = margarita.drink();

// Construction with chained invocation
Drink margarita = new DrinkBuilder()
    .add("tequila")
    .add("orange liqueur")
    .add("lime juice")
    .withRocks()
    .withSalt()
    .drink();

E eu tenho sentimentos mistos sobre este. Não se deve cadeia muitas chamadas de método em um comunicado. Por outro lado, escrevendo margarita.this() e margarita.that() não é muito conveniente também.

Agora, eu vou para junto de Java a partir de Delphi mundo. E em Delphi há a with construção da linguagem. Esta é valorizado por alguns e odiado por muitos (ou é o contrário?). Acho with a ser mais elegante do que a idéia de invocação acorrentado (que eu acredito trabalhos sobre a base do método void retornando referência a objeto no qual ele foi invocado - e esta é a parte que eu não gosto, como void deve retornar nada ).

Gostaria muito de receber o recurso de linguagem with sendo adotado por Java, de modo que o código de exemplo poderia ser escrito assim:

Drink margarita = null;
with (new DrinkBuilder()) {
    add("tequila");
    add("orange liqueur");
    add("lime juice");
    withRocks();
    withSalt();
    margarita = drink();
}

Eu sou o único que prefere esta solução para a invocação acorrentado? Qualquer outra pessoa sente que with poderia ser uma extensão útil para a linguagem Java? (Lembra-me da pergunta de alguém sobre a necessidade de "Java ++" ...)

Foi útil?

Solução

com declaração pode ser traduzida em Java usando classes anônimas com initializer:

Drink margarita = new DrinkBuilder() {{
    add(“tequila”);
    add(“orange liqueur”);
    add(“lime juice”);
    withRocks();
    withSalt();
}}.drink();

as desvantagens do uso deste idioma estão bem documentados aqui .

Chained Invocation é um apelido para o Método encadeamento. Que é bem conhecida expressão e funciona com qualquer versão do Java:

class Chained {

    public Chained withFoo() { 
        // ...
        return this;
    }

    public Chained withBar() { 
        // ...
        return this;
    }
}    

a proposta de JDK 7 é permitindo do método de encadeamento também para vazio tipo de retorno :

class ChainedJava7 {

    public void withFoo() { 
        // ...
    }

    public void withBar() { 
        // ...
    }
}    

Outras dicas

Este que você pode interessar.

Eu gosto muito declarações with dessa forma, mas eu prefiro a versão VB deles:

With testObject
    .Height = 100
    .Text = "Hello, World"
    .ForeColor = System.Drawing.Color.Green
End With

Como cada atributo no bloco With ainda tem de ser precedido por um . você sabe que você está referenciando uma propriedade do objeto e não, digamos, uma variável local, reduzindo quaisquer conflitos de namespace.

Se tomarmos o exemplo:

with (new DrinkBuilder()) {
    add(“tequila”);
    add(“orange liqueur”);
    add(“lime juice”);
    withRocks();
    withSalt();
    margarita = drink();
}

não há nenhuma maneira fácil de dizer se withSalt() é um método de DrinkBuilder ou um método na classe local. Se você permitir que apenas os métodos do objeto with-ed no bloco with então eu acho que eles se tornam muito menos útil.

Eu não sou um fã deste uso de with; Eu prefiro muito mais a Python declaração with . Eu concordo com você que void deve significar void, no entanto. No exemplo que você fornecer, se uma pessoa realmente quer ser capaz de chamadas de método corrente devem apenas mudar os tipos de retorno sobre os seus métodos de modo que eles estão chainable.

Talvez as muitas muitas chamadas para um objeto são o sinal de que algumas necessidades de código para ser movido?

Joshua Bloch em Effective Java Item # 2 recomenda o uso de um Builder quando você tem um construtor com um monte de argumentos. Uma razão é que ele pode ser escrito para garantir que o objeto construído está sempre em um estado consistente. Ele também evita ter complexos "construtores telescópica" na classe do objeto construído. Ainda outra é que se você deseja que o objeto construído para ser imutável (por exemplo, para a segurança do thread), não pode ter métodos setter.

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