Tenho uma dúvida quanto à implementação do padrão State.
Vou expor meu exemplo prático para tentar explicar exatamente onde quero chegar.
Tenho um CRUD de Nota Fiscal no meu sistema. Cada nota fiscal pode estar EMITIDA (acabou se ser cadastrada), CANCELADA e LIQUIDADA (ver o diagrama de estados e de classes).
Minhas dúvidas são as seguintes:
Os estados são da minha camada de modelo? Ou estariam na camada de negócios?
É correto ter na implementação de cada método das classes concretas de NotaState todo o negócio da transição de estado? Por exemplo, ao cancelar uma nota fiscal Faturada, eu devo cancelar as Contas a Pagar/Receber geradas por esta nota antes de cancelá-la (entenda este processo como, para cada Conta a Pagar/Receber eu devo atualizar seu estado no Banco de Dados e em seguida alterar o estado da nota fiscal e persistí-lo também).
Este procedimento de persistência deve ser chamado pelo método “cancelar()” da classe concreta Faturada? Ou este método vai apenas me retornar um “sim” ou “não” para executar o procedimento?
A princípio implementar todo o procedimento dentro do método “cancelar()” me pareceu mais correto, já que a intenção do padrão State é facilitar a transição de estados diminuindo o número de testes e deixando mais coeso o tratamento de cada transição.
Porém, o Analista que me passou este trabalho me recomendou que eu não fizesse a parte de persistência através dos métodos de NotaState, mas sim a partir do meu Controller. O State está me servindo simplesmente como alguém que só me diz “pode fazer isto” ou “não pode fazer isto”. Desta maneira, em alguns casos, tenho que fazer a “gambiarra” de guardar o Estado anterior para saber o que caminho devo seguir.
[quote=hugonardo]Olá a todos!
Tenho uma dúvida quanto à implementação do padrão State.
Vou expor meu exemplo prático para tentar explicar exatamente onde quero chegar.
Tenho um CRUD de Nota Fiscal no meu sistema. Cada nota fiscal pode estar EMITIDA (acabou se ser cadastrada), CANCELADA e LIQUIDADA (ver o diagrama de estados e de classes).
Minhas dúvidas são as seguintes:
Os estados são da minha camada de modelo? Ou estariam na camada de negócios?
[/quote] O Domain Logic aqui se refere a um pattern states “Permitir a um objeto alterar o seu comportamento quanto o seu estado interno mudar. O objeto irá aparentar mudar de classe.”, estamos falando em objetos de estado/comportamento, neste momento se situamos ao domínio.
“Operação esta vem pela regência da interface sobre as demais entidades que recebem o state.”
Implementação é código, o que você tem é uma simples atividade de estado EstadoConcreto Implementa um comportamento associado ao estado do contexto. Estado define uma interface para encapsular o comportamento associado com um estado particular do contexto. Contexto define a interface de interesse as classes mantém uma instância de um EstadoConcretoque define o estado atual
Nota: se você não entendeu o Marcio Duran, não se preocupe, você não é o único.
[quote=hugonardo]Minhas dúvidas são as seguintes:
Os estados são da minha camada de modelo? Ou estariam na camada de negócios?
[/quote]
Não existe camada de modelo. Essa palavra faz parte do padrão MVC, que não é uma divisão de camadas. Os seus estados estão na camada de negócio.
Não existe o “correto”, mas a sua escolha faz sentido e não tem problema nenhum.
Melhor ainda, porque não dar à classe concreta Faturada uma instância de um DAO? Tipo, coloca um parâmetro de DAO no construtor, e, ao chamar cancelar(), é invocado no final apenas uma linha do método do DAO.
Sim, você está certo.
Mande seu analista tomar no &*)@!
Esse “controller” é invenção de gente que não sabe OO e só ouviu falar de MVC, mas não sabe o que é.
Ou seja, está apenas fingindo seguir design patterns e príncipios de OO. As classes que implementam State podem tomar voz ativa em suas decisões. Claro, não pode fazer tudo, pra isso você pode separar responsabilidades em outras classes. Mas dizer que o estado só pode “dizer” e não “fazer” remete ao objetos anêmicos, porém em versão “power”.
Você quer produzir um conceito que não é MVC, Model View Control para simplesmente você querer explicar como ter a ação do objeto acionar ao estado de apertar um botão na tela para voltar ação do estado do objeto somente isso.
Quanto a Patterns State em qualquer outra situação mais complexas ou não dizer Camada de Negócios, não é tão o caso podemos ter outros patterns que não sejam de operação e sim de estrutura e combina-los com outros que vão fazer melhor sentindo e pensar em N-tier.
Aqui você sai da responsabilidade do que ele objetiva o States à fazer e delega responsabilidade para persistência, então não é mais só patterns states ?
Mais fácil assim, ao invés de você pensar em programação procedural pense em orientação a objetos sabendo que você deva compreender que opeção simples de estados podem ser melhor combinadas e extendidas deacordo com a atividade se propõe a fazer, para querer pensar sobre MVC se baseando em 3-tiers.
[quote=Leonardo3001]Nota: se você não entendeu o Marcio Duran, não se preocupe, você não é o único.
Não existe o “correto”, mas a sua escolha faz sentido e não tem problema nenhum.
[/quote]
Sera que é responsabilidade da NF, ou ainda dos estados da NF, controlar toda a logica de cancelamento da nota fiscal?
Sera que é uma boa o teu dominio conhecer objetos da infraestrutura? Particularmente nesse caso eu preferiria uma exceção ou por a NF num estado de “erro”, dependendo do caso.
Discordo novamente. A intencao do padrao State é controlar e validar a mudanca do estado do objeto, o que deve ser feito em consequencia desta mudanca do estado ou nao (caso nao seja valida) nao é problema dele.
Seja la o nome que for dado ao objeto (controller, facade, service, etc…) é uma solucao possivel. Particularmente acho melhor que a dos states controlando tudo.
Discordo de novo, qualquer coisa que um state faca que va alem do seu papel como state é atribuicao de responsabilidade que nao lhe pertence.