Desacoplar Controle (WEB, Swing)

Tenho uma dúvida, foi discutida por parte neste tópico: http://www.guj.com.br/posts/list/30/24007.java

Normalmente ultilizo MVC apenas penssando em MVC para WEB e agora preciso implementar o código em Swing e WEB,
ultilizo o pattern Command, RequestHelper, com ServiceToWork (FrontControler e View Helper)
o problema é quando eu passo a requisição do FrontControler para o Command
uso o RequestHelper para achar o correto para a requisição, mas passo o HttpRequest e HttpResponse para o Command,
para poder pegar os valores que foram enviados da View para o Controle, na WEB ta bom assim, mas agora que preciso usar no Swing, HttpRequest ?
como posso desacoplar isso do Command ? talvez utilizando IoC ?

Pretendo usar o pattern Observer para o Swing…

Olá, acho que você tem erros de arquitetura, uma camada inferior do sistema nunca deve depender de uma camada superior, você não pode ter um servlet que chama um objeto que recebe uma servlet da camada superior, assim fica difícil abstrair…

O que você deveria ter feito era isolar as funcionalidades reais do sistema em uma camada e ai criar outra para a web.

Assim você pode aproveitar as regras de negócio já feitas e apenas criar outra VIEW para os dados da MODEL.

att. Carlos

Foi oque eu quiz dizer, não é legal ter um command dependendo do HttpServletRequest/Response,
por isso perguntei como seria uma forma “legal” de fazer isso, se você olhar no post que eu citei, verá oque estou dizendo.
Lá deram a idéia de abstrair o Request para uma classe Request(interface) e ai Dependendo do meu Controle (Web/Swing) implementar o RequestData e ou HttpRequest
Acredito que vou usar uma solução parecida com esta, mas gostaria de opniões.

[quote=maniacs]Foi oque eu quiz dizer, não é legal ter um command dependendo do HttpServletRequest/Response,
por isso perguntei como seria uma forma “legal” de fazer isso, se você olhar no post que eu citei, verá oque estou dizendo.
Lá deram a idéia de abstrair o Request para uma classe Request(interface) e ai Dependendo do meu Controle (Web/Swing) implementar o RequestData e ou HttpRequest
Acredito que vou usar uma solução parecida com esta, mas gostaria de opniões.[/quote]

Cara realmente o único meio que vejo para não refatorar todo o sistema é este usar adaptadores.

Procure algo sobre o padrão Adapter.

Não vejo nenhum problema do controle estar “acoplado” com o ambiente (Web,Desktop,Mobile), já que ele tem a função de interpretar essas requisições econverter no protocolo de comunicação específicodo para conversar com o modelo, receber a resposta e disponibiliza-la para a view.
Entretanto o que não se deve permirtir é o orquestramento do modelo pelo controle, já que esse orquestramento pode fazer parte de regras de negócio, acoplando assim o modelo ao negócio.
Para esse desacoplamento seria interessante uma fachada que orquestraria os objetos de domínio.

[quote=mateusbrum]Não vejo nenhum problema do controle estar “acoplado” com o ambiente (Web,Desktop,Mobile), já que ele tem a função de interpretar essas requisições econverter no protocolo de comunicação específicodo para conversar com o modelo, receber a resposta e disponibiliza-la para a view.
Entretanto o que não se deve permirtir é o orquestramento do modelo pelo controle, já que esse orquestramento pode fazer parte de regras de negócio, acoplando assim o modelo ao negócio.
Para esse desacoplamento seria interessante uma fachada que orquestraria os objetos de domínio.
[/quote]

Ao desenvolver programas devemos manter a baixa coesão, o sistema na forma especificada está com altíssima coesão para as camadas inferiores, isto não pode acontecer.

Assim você quando surge a necessidade de implementar algo para para outra forma de visualização dos dados, fica inviável.

Presentation é uma coisa.
business Logic é outra coisa.

Adapter é do Business Delegate isso ?
Acredito que ja tenha visto como ele funciona, vou ver como fica a implementação neste caso.

carlos, não consgui entender sua obsrvação.

talvez eu nao fui claro, mas o que quis dizer é que nao é necessario a preocupacao de desacoplar a camada de controle, desde que vc tenho uma camada de negocio desacoplada e não orquestrada pela camada de controle.
Pois o MVC visa a utilizacao do modelo, e desacoplamento entre exibicao (view) e estado (negocio).

Quno for mudar de ambiente,apenas crie outro controle e chame normalmente a camada de modelo.

Talvez o modelo dele esteje mal implementado e acoplado com o control.

[quote=mateusbrum]carlos, não consgui entender sua obsrvação.

talvez eu nao fui claro, mas o que quis dizer é que nao é necessario a preocupacao de desacoplar a camada de controle, desde que vc tenho uma camada de negocio desacoplada e não orquestrada pela camada de controle.
Pois o MVC visa a utilizacao do modelo, e desacoplamento entre exibicao (view) e estado (negocio).

Quno for mudar de ambiente,apenas crie outro controle e chame normalmente a camada de modelo.

Talvez o modelo dele esteje mal implementado e acoplado com o control.[/quote]

Na verdade a arquitetura imposta por ele está errada.

Realmente tinha te entendido errado.

Isso, acredito eu que ele quiz dizer o mesmo.
Mais alguma idéia de como posso implementar isto ?
Não tenho o código pronto e ainda posso refatoralo sem problemas…
Na verdade preciso algo realmente simples, é algo apenas para uma apresentação, o problema é precisar usar o código no Swing tbm, e implemtar muitos padroes a mais eu axo desnescessario para este trabalho

Isso, acredito eu que ele quiz dizer o mesmo.
Mais alguma idéia de como posso implementar isto ?
Não tenho o código pronto e ainda posso refatoralo sem problemas…
Na verdade preciso algo realmente simples, é algo apenas para uma apresentação, o problema é precisar usar o código no Swing tbm, e implemtar muitos padroes a mais eu axo desnescessario para este trabalho[/quote]

Cara não sei se já existe algum adapter disponivel, geralmente você é quem faz, se o sistema não tiver muitas classes então refatore pois está errado o seu modelo.

OK, irei fazer isso, refatorarei o código que ja tenho, você ja utilizou algum outro pattern para as regras de negócio além do BusinessDelegate ?

Aproveitando o assunto.

Qual sujestão vcs dariam para um desacoplamento perfeito entre controle e modelo, já que muitas vezes é necessário tomar decisão de navegabilidade de acordo com o modelo.
Ex :
Se fulano não tiver o registro, iniciar o processo de registro.

Controle -> Modelo.temRegistro ?
Controle <- nao
Controle -> Modelo.registrar!

Ou seja, uma pequena regra de negócio esta no controle.
Como contornar isso.

Um facade com alguns callbacks ?
Controle -> Fachada.temRegistro -> Modelo.temRegistro?
Fachada.callBackSemRegistro-> Controle.paginaDeregistro
OU
Fachada.callBackComRegistro-> Controle.paginaXYZ

Sendo que esses callback seriam implementados para cada ambiente.
Ficaria meio estranho não é ?
Além de uma camada superir “depender” de uma inferior.

Haveria alguma solucao para isso!?
Eu to viajando na maioneze ?

BusinessDelegate é uma camada para desacoplar o negocio.
Aquela velha historia, se o negocio muda, voce teria que mudar todas as chamadas do negocio, mas com outra camada tu so muda a camada e tudo fica redondo.
Seria interessante o SessionFacade, mesmo que tu nao estaja utilizando EJB a idéia é boa, na verdade é bem parecida, mas com propósitos distintos.

Hmmm, dessa vez fiz algo parecido com oque falei do tópico que mencionei no início do post,
como é apenas para mostrar o entendimento de MVC foi o suficiente:

Criei um Request e um Response, o comand retorna um Response e recebe um Request, isso no método execute,
o Request é uma interface e tem em seus métodos getParameter, assim eu implementei ela em uma classe, HttpRequest e passei o HttpServletRequest
para servir os parametros, fiz o frontControler trabalhar com a classe Response e pronto, desacoplei o command da WEB.

Sobre oque você perguntou, BusinessDelegate não funcionaria para você nisso? ja que BusinessDelegate é uma ou quase uma Facade

Blz,

Aqui tenho feito o seguinte (uso Faces):

tenho uma classe que representa o meu modelo de dados do banco:

public class Pedido {
    private Long idPedido;
    private Cliente cliente;
    private Date dataCompra;
    
    ... 
    
}

Tenho então um repositorio para consultas

public class RepositorioPedidos{
public List&lt;Pedido&gt; listarPedidosDoCliente(Cliente cliente){...}
public Pedido recuperarPedidoPorCodigo(Long codigo){...}
    
}

Por fim tenho a minha camada de negócios

public class ServicoDeOrcamento{

    public efetuarNovoPedido(Cliente cliente,Pedido pedido){
        PedidoRepositorio pr = new PedidoRepositorio();
        List&lt;Pedido&gt; pedidos = pr.listarPedidosDoCliente(cliente);
        if (pedidos.size() ==0) {
            // cliente novo não fez nenhum pedido ir para analise de crédito 
        }
        
        // salva novo pedido do cliente e faz mais alguma coisa
    }
}

Ai no final eu crio uma camada WEB para acessar o serviço:


public class BeanFormOrcamento {

    public fazerPedidoCliente(Long idCliente,Pedido pedido){
        RepositorioCliente rc = new RepositorioCliente();
        Cliente cliente = rc.recuperarClientePorCodigo(idCliente);
        
        ServicoDeOrcamento so = new ServicoDeOrcamento();
        so.efetuarNovoPedido(cliente,pedido);
    }

}

Desta forma basta eu fazer outra VIEW em SWT que toda a minha lógica de negócio foi aproveitada. Não Preciso reescrever a lógica ou adapta-la, basta usar.

Ps. Adapter é um padrão que é usando quando se deseja adaptar sua classe para ser usada por outro objeto. exemplo:

Sua tomada em casa é de 2 pinos, mas o computador é de 3 pinos então usa-se um adaptador para ligar na tomada (beijamin).

O mesmo em Software:

tenho o seguinte problema:
Preciso comparar uma array de bytes com regex. só que regex somente aceita objetos do tipo CharSequence.

    byte[] sca = "helo carlos".getBytes();

    Pattern p = Pattern.compile("^(?i)(helo) .+");
    Matcher m = p.matcher(sca);
    return m.matches();

o código acima vai da erro, mas eu preciso usar array de bytes. o que fazer?

use um adaptador (Adapter) que adapta a array para ser usada como uma CharSequence, veja a interface da charSequence:

public interface CharSequence {
    int length();
    char charAt(int index);
    CharSequence subSequence(int start, int end);
    public String toString();
}

Aqui está o adaptador:

public class CharSequenceByteArray implements CharSequence {

    private byte[] buffer;

    public CharSequenceByteArray(byte[] buffer) {
        this.buffer = buffer;
    }

    public int length() {
        return buffer.length;
    }

    public char charAt(int index) {
        return (char) buffer[index];
    }

    public CharSequence subSequence(int start, int end) {
        return new CharSequenceByteArray(Arrays.copyOfRange(buffer, start, end));
    }
}

agora eu faço assim uso o adaptador:

    byte[] sca = "helo carlos".getBytes();

    Pattern p = Pattern.compile("^(?i)(helo) .+");
    Matcher m = p.matcher(new CharSequenceByteArray(sca));
    return m.matches();

Este código não da erro, porque eu adaptei uma interface em outra.

Isto é o padrão adapter.

att. Carlos

Obrigado pelas respostas carlos.uneb, tomara que oque foi discutido aqui ajude mais alguem.

entendeu agora o uso do adapter ?

Sim, ontem a noite eu olhei como funciona o pattern e tinha entendido, mas o seu exemplo mostrou de forma bem clara, obrigado mais uma vez :wink:
Agora vamos ver outro Pattern hehehe :wink:

Ao contrário, temos que ter alta coesão e baixo acoplamento.