Duvida com Fluent Interface

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

1 curtida

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/

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

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.

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.

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 ?

[quote=mmx][quote]

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

[/quote]

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 ?[/quote]

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

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.

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

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

:oops:

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