Alguém conhece um padrão para desenvolvimento de Camada de protocolo?
Por exemplo, o meu sistema recebe mensagens binárias e deve interpretar de que tipo é essa mensagem,
para tomar a decisão de que objetivo criar.
Pode haver mensagens do tipo A, B, C… meu sistema deve “olhar” dentro do pacote e instanciar
o objeto MensagemA, ou MensagemB ou MensagemC.
Mais ou menos uma serealização e deserealização.
Se existir algum design pattern que aborde isso, vai ser bem vindo.
Eu uso o Proxy para representar localmente objetos remotos.
Ainda não estou bem certo se é seu caso…
ViniGodoy
Eu utilizava os padrões Strategy juntamente com o FactoryMethod.
O Strategy definia um conjunto de “MessageDecoders”. Uma mensagem de protocolo pode precisar ser quebrada em duas ou três estruturas diferentes, por isso esse padrão era conveniente.
O FactoryMethod era só uma interface na qual, dado um pacote, sabia que decoder escolher e como devolver o resultado.
Jean_Utf
Massa… vou dar uma estudada pra ver se consigo adaptar no meu projeto.
Valeu!
ViniGodoy
O legal é que, como cada mensagem geralmente tem um message code, você pode criar um HashMap com o id da mensagem e o decoder. Aí vc só faz assim:
public Message decode(ByteBuffer bytes) {
Header h = decodeHeader(bytes); //Decodifica o cabeçalho
MessageDecoder d = decoders.get(h.getType()); //Usa o mapa decoders para obter o decoder certo
return d.decode(bytes); //Decodifica o corpo da mensagem.
}
Jean_Utf
Quase isso que estou fazendo… mas ao invez de um HashMap, eu uso um Factory.
O que tive de fazer diferente foi o retorno. Não posso retornar um Message porque quem espera
precisaria saber o tipo dessa message.
O que eu fiz foi uma Factory de ITratadorOperacao, com um método tratarOperacao(bytes), que no seu caso é o HashMap.
Eu seto os bytes nesse método, e a instância de ITratadorOperacao que recebi da factory, trata os dados.
Foi a única solução que pensei.
Valeu cara!
ViniGodoy
No caso o método decode() é o método fábrica.
Para testar o tipo da mensagem retornada, basta usar o instanceOf.
Jean_Utf
Sim, sim… poderia usar também um getTipo da vida e fazer um switch…
Mas quero fugir disso… tentar deixar o mais encapsulado e escalável possível.
Pra quando adicionarem um novo tipo de mensagem, eu tenha que alterar a menor quantidade (nenhuma de preferência) de classes possível,
e apenas ADICIONAR classes novas.
Mas é isso ae… valeu!
ViniGodoy
Eu usava novamente um map, que associava uma determinada class de mensagem a um MessageHandler.
Depois, sempre que uma mesagem nova era criada, havia apenas 2 pontos do código a serem alterados:
a) A criação de um novo decoder.
b) A criação de um novo handler.
A mensagem era codificada pela fábrica, e então entregue a todos os handlers, listeners daquela determinada classe. Eu também incluí um globalHandler para caso alguém queira ouvir absolutamente tudo (muito útil para geração de log).