Convenções do Jmine

Business Objects

Um Business Object (BO) é um objeto persistível em banco de dados que representa algum dado do negócio do sistema. Os BOs de um sistema ficam sempre dentro de um pacote “domain”, e o conjunto deles é o domínio de um sistema ou módulo.

BOs podem ter regras de negócio descritas nas próprias classes, entretanto essa prática não se comporta muito bem quando um BO possui muitas regras de negócio, pois isso geraria uma classe com muitas responsabilidades. É mais comum que as regras de negócio de um BO fiquem em Actors, como será explicado mais abaixo, ficando o BO apenas com a responsabilidade da persistência dos dados.

Persister Listeners

Classes responsáveis por executar uma ou mais ações, quando uma entidade for modificada.

As ações podem ser disparadas em 7 momentos, quando houver alteração, inclusão ou exclusão, e podemos escolher se a ação será feita antes ou depois da modificação da entidade de fato ocorrer. Além disso temos um método especifico para a remoção das dependências dessa entidade.

É importante esclarecer que persister listeners não devem possuir ordem de execução e é aconselhável que não alterem o estado da entidade, garantindo que qualquer listener será executado como esperado.

Temos atualmente duas infras para se usar os persister listeners:

  • Na primeira, e mais atual, você cria uma Action, implementando jmine.tec.component.Action<E> e registra a mesma para uma ação + classe. (ex: afterInsert, PapelRF.class).
  • A segunda, é a estrutura antiga de persister listeners e a classe precisa estender jmine.tec.persist.impl.persister.listener.AbstractPersisterListener<T>, e todas as ações devem ser definidas nesta classe.

As principais vantagens da primeira estrutura, em relação a segunda são:

  • Ela nos permite criar uma classe para cada ação, cada uma com uma responsabilidade especifica, em vez de uma classe gigante com dezenas de ações misturadas.
  • Temos a flexibilidade de criar ações de acordo com a camada do jmine (ou dos produtos), e escolher quais fazem, ou não, sentido em cada um desses níveis (apenas mudando a configuração).

É recomendado utilizar a estrutura mais nova, mas é importante saber como a antiga funciona, pois ela é utilizada em vários listeners, que serão migrados apenas quando acharmos necessário.

Validators

Os validators são classes que garantem a integridade dos dados antes de serem gravados no BD. Eles são chamados pela infra de persistência, sempre que uma entidade é modificado no sistema. Note que estas validações não impedem nem substituem aquelas feitas em serviços e/ou telas de cadastro.

Temos 6 pontos onde o dado pode ser validado: inclusão, alteração ou exclusão e para cada uma das 3 ações básicas, temos a opção de fazer a validação antes ou depois da autorização do dado.

As nossas infras de validators possuem uma estrutura para tratar os erros (então não é necessário jogar as Exceptions para cima), mas a mensagem precisa ser internacionalizada, assim como nas Exceptions).

Atualmente temos duas estruturas de validators:

  • Na primeira, e mais atual, você deve extender jmine.tec.persist.impl.validator.AbstractValidator e registrá-lo no spring.
  • Na segunda estrutura, você deve extender a classe mine.tec.persist.impl.validator.AbstractBeanValidator e o seu validator precisa estar no pacote .validator, e a entidade que você quer validar no pacote ../domain

As principais vantagens da primeira estrutura, em relação a segunda são:

  • Ela nos permite criar vários validators, cada um garantindo uma determinada regra de negocio, em vez de uma classe gigante com dezenas de validações diferentes.
  • Temos a flexibilidade de criar validações de acordo com a camada do jmine (ou dos produtos), e escolher quais são as validações que fazem, ou não, sentido em cada um desses níveis (apenas configurando no spring).

Dado isso não se deve utilizar a estrutura antiga (que esta @Deprecated), mas é importante saber da sua existência, pois temos muitos validators antigos, que serão migrados apenas quando acharmos necessário.

Actors

Um actor é um objeto responsável pela execução de uma regra de negócio específica. Um actor deve ser thread safe (de preferência stateless) e ter um único método público que executa alguma regra de negócio (Single Responsibility Principle). Um actor pode fazer uso de outros colaboradores (inclusive outros actors) para executar ações complexas (Injeção de Dependências).

É comum nomear actors com o sufixo “Actor”, mas não é obrigatório. O bom nome pode ser um substantivo que descreve o que o actor faz. Por exemplo, um actor que contabiliza lucro por ser chamado de “ContabilizadorLucro”.

É um anti-pattern comum encontrar Actors com múltiplas reponsabilidades, todas referentes ao mesmo BO (ex.: para entidade Batata, um BatataActor que executa todas as ações relativas a Batata). Isso gera classes enormes, fortemente acopladas, pouco coesas, violam o Single Responsibility Principle e torna testes unitários quase impossíveis. Evite ao máximo, refatore se possível. Em Domain Driven Design tais objetos são denominados serviços - não confundir com serviços do Jmine, que têm um significado parecido, mas não idêntico.

Helpers (Utility Class)

São classes que agrupam métodos recorrentes no código e que não fazem parte do escopo do negócio. Basicamente são uma como uma biblioteca de métodos que centralizam e auxiliam a criação de outras classes. Normalmente os métodos das classes Helpers são estáticos.