Duvida com Fluent Interface

10 respostas
M

achei este link com exemplo de interface fluente

class Fluent
{
    private String name;
    private String address;
    private int age;

    public Fluent()
    {
        this.name = "";
        this.address = "";
        this.age = 0;
    }

    public Fluent addAddress(String address)
    {
        this.address = address;
        return this;
    }

    public Fluent addName(String name)
    {
        this.name = name;
        return this;
    }

    public Fluent addAge(int status)
    {
        this.age = status;
        return this;
    }

    @Override
    public String toString()
    {
        return "You have a Fluent object with: {(Name:"+this.name+"),
           (Address:"+this.address+"),(Age:"+this.age+")}";
    }
}

mas pelo que percebi interface fluente é so uma forma mais elegante de escrever o codigo pra setar
parametros na classe ?

e se eu precisar fazer GET ao inves de SET ? como ficam os exemplos ? quero implementar este modelo, mas fiquei em duvida com esta parte

10 Respostas

R

mmx,

Só para chamar a atenção, não se trata de um “interface” e sim de uma classe.

class Fluent {

    private String name;  
    private String address;  
    private int age;

	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getAddress() {
		return address;
	}
	public void setAddress(String address) {
		this.address = address;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}  

}

Dá uma lida: http://blog.caelum.com.br/nao-aprender-oo-getters-e-setters/

M

desculpem, faltou o resto do exemplo

class Fluent
{
    private String name;
    private String address;
    private int age;

    public Fluent()
    {
        this.name = "";
        this.address = "";
        this.age = 0;
    }

    public Fluent addAddress(String address)
    {
        this.address = address;
        return this;
    }

    public Fluent addName(String name)
    {
        this.name = name;
        return this;
    }

    public Fluent addAge(int status)
    {
        this.age = status;
        return this;
    }

    @Override
    public String toString()
    {
        return "You have a Fluent object with: {(Name:"+this.name+"),
           (Address:"+this.address+"),(Age:"+this.age+")}";
    }
}
public class FluentTest
{
    public FluentTest()
    {
        Fluent fluent = new Fluent()
                .addName("Hillol")
                .addAddress("Gulshan-1,Dhaka")
                .addAge(25);
        System.out.println(fluent);
    }

    public static void main(String[] args)
    {
        FluentTest fluentTest= new FluentTest();
    }
}
R

Fluent interfaces se trata de um Design Pattern (e não do uso de interfaces java).

Então, essa classe utiliza o design pattern fluent interface.

Uma das formas de se fazer fluent interfaces é utilizar uma técnica chamada method chaining.

Esse exemplo utiliza essa técnica.

Fluent fluent = new Fluent() .addName("Hillol") .addAddress("Gulshan-1,Dhaka") .addAge(25);

Retornando o próprio objeto nos métodos é possível encadear as chamadas.

Só é possível utilizar method chaining para setar os valores. Para pegar os valores não é possível.

R

Eu particularmente não gosto muito desse artigo. Ele foi escrito para desenvolvedores iniciantes, porém algumas informações podem mais confundir o leitor do que ajudar. O que o artigo propoe é muito sutil para ser avaliado por desenvolvedores iniciantes. E pode passar a impressao de que getters e setters estão errados. Utilizar getter e setter não é um erro.

Em resumo o que o artigo quer passar é: não exponha atributos sem necessidade. E não que usar getters e setters está errado.

M

era essa a minha duvida, esclarecido

Sobre o artigo, tranquilo, posso dizer q sei lidar bem com GETs e SETs

Agora uma ultima duvida: se na minha classe Fluent, eu inserir um metodo GAT, estarei descaracterizando o Pattern ?

R

mmx:

Só é possível utilizar method chaining para setar os valores. Para pegar os valores não é possível.

era essa a minha duvida, esclarecido

Sobre o artigo, tranquilo, posso dizer q sei lidar bem com GETs e SETs

Agora uma ultima duvida: se na minha classe Fluent, eu inserir um metodo GAT, estarei descaracterizando o Pattern ?

Não estará descaracterizando não… o fato de você ter um outro pattern não anula o primeiro… :slight_smile:

S

Só um comentário. Fluent API , ou Fluent Interface , não é um design pattern. É um estilo de design.
Para criar uma interface fluente normalmente usamos o padrão Method Chain ( encadeamento de métodos).
Colocar um retorno nos métodos que retorna o proprio objeto é a forma mais simples de Method Chain.

quando usamos builders podemos usar o method chain mais avançado em que o método não retorna o mesmo objeto, retorna outro. E este outro também tem uma api com method chain cujos metodos retornam o mesmo builder, o builder orginal ou um terceiro tipo de builder. E assim vai. Pode ficar complicado.

Tecnicas mais avançadas podem usam Monads para fazer encadeamento. No scala e no c# são usados. Por exemplo Linq é baseado em monad.
Aos olhos de quem usa parece method chaining.

Os padrões proxy e decorator também pode ser usado. O c# usa no link e o scala também permite isso. Isto é um truque que no java não funciona.

É usando por exemplo para interpretar s.contains() onde s é um string. Em java teriamos que criar uma classe filha de string para fazer isto ou mesmo um proxy, o que não é possivel porque a classe é final. Em scala o string é decorado para outro objeto automatixamente e o contains que é chaamdo é o do decorador.

Por outro lado se eu tenho um POJO com get/set eu tenho um PropertyBag. Neste padrão os set não retornam nada. Ao colocar retorno nos set estamos violando o propertybag e o padrão javabean.
é nessas circunstancias que criaríamos uma builder para o pojo. Não é boa ideia misturar method chain com javabean porque ha o risco do set não ser reconhecido como o modificador porque o retorno dele não é void.

R

Apenas para reforçar, essa observação é bastante importante.

M

entendo as colocações feitas aqui, ao que tudo indica terei que usar JavaBeans no meu projeto porque preciso dos metodos GET na minha classe, não posso apenas setar parametros

R

:oops:

Não conhecia essa metodologia, mas em toda caso, é algo novo que aprendi nesse post.

Criado 20 de março de 2013
Ultima resposta 21 de mar. de 2013
Respostas 10
Participantes 4