Padrão Facade

Procurei no site, mas não encontrei.

Alguém poderia me dar um exemplo, pode ser bem simples, de um facade em camadas?
É que estou com a seguinte dúvida: eu tenho várias classes, Televisao, Som, DVD e Projetor. Cada um com um conjunto de métodos particulares. Eu criei uma classe facade para facilitar o acesso a alguns comandos, digamos ligar, que liga todos os aparelhos. A dúvida é com relação aos demais comandos desses equipamentos. Para criar um facade em camadas, eu crio mais um facade (tendo os comandos mais avançados) herdando do primeiro ou simplesmente crio o facade e pronto, sem qualquer herança e somente os comandos avançados (essa não me parece a alternativa correta)?

dê um exemplo do que chaama de “comandos avançados”. Só faz sentido usado façade quando vc orquestra vários serviços ( o padrão completo se chama Service Façade). Se quer mandar um comando especifico para um só serviço vc chama o serviço diretamente.

Veja o diagrama de classes abaixo:

É um facade simples (GOF). Perceba que os eletrodomésticos possuem comandos mais avançados que apenas ligar e desligar. A definição desse padrão diz que posso criar fachadas em camadas. Se eu quiser fazer isso utilizando o meu exemplo, eu devo criar uma nova fachada herdando da classe Facade e colocar nele os comandos (métodos) mais avançados dos eletrodomésticos?

Se não ficou claro, como ficaria um facade em camadas?

No Facade você pode ter um Facade para cada classe ou um mesmo Facade para todas.

Mas no seu caso, vc criou apenas um facade e criou variáveis de instancias para cada uma das classes. Então, apenas chame os métodos através destas variáveis.

Tipo assim:

[code]
public class Facade {

private Televisao televisao;
private DVD dvd;
private Som som;

...

}

public class Exemplo {
private Facade facade;

...

void go() {
	facade = new Facade();
	
	facade.getTelevisao().ligarTV();
	
	facade.getDVD.ligarDVD();
	
	facade.getSom().ligarSom();
}

}[/code]

[quote=romarcio]No Facade você pode ter um Facade para cada classe ou um mesmo Facade para todas.

Mas no seu caso, vc criou apenas um facade e criou variáveis de instancias para cada uma das classes. Então, apenas chame os métodos através destas variáveis.

Tipo assim:

[code]
public class Facade {

private Televisao televisao;
private DVD dvd;
private Som som;

...

}

public class Exemplo {
private Facade facade;

...

void go() {
	facade = new Facade();
	
	facade.getTelevisao().ligarTV();
	
	facade.getDVD.ligarDVD();
	
	facade.getSom().ligarSom();
}

}[/code][/quote]

A minha dúvida não é como chamar Facade a partir de um cliente, mas sim como implementar um facade em camadas. No meu exemplo, eu criei apenas um facade.

Faz de conta que meu cliente não deseja apenas as opções básicas que ofereci no primeiro facade. Ele deseja um facade com opções avaçadas de controle de som, além de outros. Para implementar as camadas que o padrão descreve, como faço? Crio um outro facade herdando do primeiro e forneço um método que acessa essas outras opções avançadas?

PS: do jeito que está o meu diagrama, eu sei que o cliente pode acessar qualquer método diretamente. Para criar o que quero, o diagrama pode ser modificado.

Define “Façade em camadas”.

Existe uma diferença entre “Layer Façade” (Façade da Camada) e “Façade Layer” (Camada de Façades) Este segundo não existe.

[quote=ECO2004][quote=romarcio]No Facade você pode ter um Facade para cada classe ou um mesmo Facade para todas.

Mas no seu caso, vc criou apenas um facade e criou variáveis de instancias para cada uma das classes. Então, apenas chame os métodos através destas variáveis.

Tipo assim:

[code]
public class Facade {

private Televisao televisao;
private DVD dvd;
private Som som;

...

}

public class Exemplo {
private Facade facade;

...

void go() {
	facade = new Facade();
	
	facade.getTelevisao().ligarTV();
	
	facade.getDVD.ligarDVD();
	
	facade.getSom().ligarSom();
}

}[/code][/quote]
[/quote]

Este código não é uma façade. Não ha chama telescopica num façade. O código é apenas

[code]
public class Facade {

private Televisao televisao;
private DVD dvd;
private Som som;

//não ha acesso publico aos atributos acima

    public void ligar(){

             televisão.ligar();
            dvd.ligar();
           som.ligar();

   }

}

public class Exemplo {

void go() {
	Facade facade = new Facade();
	
	facade.ligar();
}

}[/code]

Eu simplesmente desejo estruturar o meu sistema em camadas usando o padrão de projeto Façade.

Esse padrão pode ser usado para essa finalidade. Eu não sei como explicar melhor o que quero, já que não sei como implementar.

Podem mudar o diagrama para mostrar como seria a estruturação desse sistema em subsistemas.

[quote=ECO2004]Eu simplesmente desejo estruturar o meu sistema em camadas usando o padrão de projeto Façade.

Esse padrão pode ser usado para essa finalidade. Eu não sei como explicar melhor o que quero, já que não sei como implementar.

Podem mudar o diagrama para mostrar como seria a estruturação desse sistema em subsistemas. [/quote]

O sistema já está dividido em subsistemas : televisão, som , dvd, etc… Esses sistemas/serviços estão todos na mesma camada. E vc tem um Façade que está dando acesso a essa camada. É só isso. Não ha nada mais a fazer.

Eu quero fornecer vários façades…cada um representando uma camada. O primeiro fornece um conjuntos de comandos básico ao cliente. Se o cliente desejar mais comandos, ele pode utilizar outra fachada, e assim por diante.

Se eu fornecer apenas façades, sem conexão entre elas, não estará configurado um sistema em camadas.

[quote=ECO2004]Eu quero fornecer vários façades…cada um representando uma camada. O primeiro fornece um conjuntos de comandos básico ao cliente. Se o cliente desejar mais comandos, ele pode utilizar outra fachada, e assim por diante.

Se eu fornecer apenas façades, sem conexão entre elas, não estará configurado um sistema em camadas.[/quote]

Vc está misturando as bolas e estás misturando feio…

Fornecer mais comandos usando outra interface não é outra camada. Não tem nada que ver com camadas.
Vc já definiu sua camada de serviços que são a tv, som, dvd , etc… pronto. Não ha mais camadas no seu sistema de 5 classes. Vc quer mais camadas ? então crie mais camadas abaixo dos serviços ou acima do façade. Criar outro façade não é criar outra camada.

Agora, não ha razão para que o mesmo façade não possa fazer os comandos avançados. Aliás até deve, pela simples razão que é mais DRY. Porque vou ter outra classe conversando com os mesmos serviços se posso usar a mesma ?
Além disso faz sentido para o cliente só usar uma interface para controlar tudo. Esse foi o propósito de criar o façade para começo de conversa.

    public class Facade {  
      
        private Televisao televisao;  
        private DVD dvd;  
        private Som som;  
      
       //não ha acesso publico aos atributos acima  
      
            public void ligar(){  
      
                     televisão.ligar();  
                    dvd.ligar();  
                   som.ligar();  
      
           }  

           public void definirVolume(int volume){

                  televisão.definirVolume(volume);  
                    dvd.definirVolume(volume);  
                   som.definirVolume(volume);  
          }
      
      
    }  
      
    public class Exemplo {  
      
        void go() {  
            Facade facade = new Facade();  

            facade..volume(20);              
            facade.ligar();  


        }  
    }  

O façade existe para criar uma coerência para que usa. O cliente poderia usar os serviços em separado, mas assim é mais simples. A superficie da sua camada é menor ( a superficie é o numero de métodos publicados) o que facilita a manutenção futura.

Em resumo. O que você quer, não faz sentido. Ou pelo menos não com os nomes que vc está usando. Vc quer fazer outra interface e outra classe, ok, faça. Mas não diga que isso é uma camada.
Mas se vc entendeu bem o padrão Façade , vc não iria fazer outra interface e classe.

ECO2004, eu tenho uma apostila da GlobalCode muito boa de design-patterns , fala sobre facade e tem exemplos. Caso precise, me mande um MP que lhe envio.
Att Espinheira

[quote=sergiotaborda][quote=ECO2004]Eu quero fornecer vários façades…cada um representando uma camada. O primeiro fornece um conjuntos de comandos básico ao cliente. Se o cliente desejar mais comandos, ele pode utilizar outra fachada, e assim por diante.

Se eu fornecer apenas façades, sem conexão entre elas, não estará configurado um sistema em camadas.[/quote]

Vc está misturando as bolas e estás misturando feio…

Fornecer mais comandos usando outra interface não é outra camada. Não tem nada que ver com camadas.
Vc já definiu sua camada de serviços que são a tv, som, dvd , etc… pronto. Não ha mais camadas no seu sistema de 5 classes. Vc quer mais camadas ? então crie mais camadas abaixo dos serviços ou acima do façade. Criar outro façade não é criar outra camada.

Agora, não ha razão para que o mesmo façade não possa fazer os comandos avançados. Aliás até deve, pela simples razão que é mais DRY. Porque vou ter outra classe conversando com os mesmos serviços se posso usar a mesma ?
Além disso faz sentido para o cliente só usar uma interface para controlar tudo. Esse foi o propósito de criar o façade para começo de conversa.

    public class Facade {  
      
        private Televisao televisao;  
        private DVD dvd;  
        private Som som;  
      
       //não ha acesso publico aos atributos acima  
      
            public void ligar(){  
      
                     televisão.ligar();  
                    dvd.ligar();  
                   som.ligar();  
      
           }  

           public void definirVolume(int volume){

                  televisão.definirVolume(volume);  
                    dvd.definirVolume(volume);  
                   som.definirVolume(volume);  
          }
      
      
    }  
      
    public class Exemplo {  
      
        void go() {  
            Facade facade = new Facade();  

            facade..volume(20);              
            facade.ligar();  


        }  
    }  

O façade existe para criar uma coerência para que usa. O cliente poderia usar os serviços em separado, mas assim é mais simples. A superficie da sua camada é menor ( a superficie é o numero de métodos publicados) o que facilita a manutenção futura.

Em resumo. O que você quer, não faz sentido. Ou pelo menos não com os nomes que vc está usando. Vc quer fazer outra interface e outra classe, ok, faça. Mas não diga que isso é uma camada.
Mas se vc entendeu bem o padrão Façade , vc não iria fazer outra interface e classe.[/quote]

Obrigado. Eu estava confundindo então o que eram as camadas no padrão.