Pergunta

Assim terminou ler este post por Greg Young, onde ele está falando sobre a Microsoft recomenda padrões com objetos de transferência de dados mudos. Ele deu a entender que na comunidade Java, as coisas estão tendendo a outra direção.

A minha pergunta é quanto lógica deve estar em seus objetos de entidade? Nossa filosofia onde eu trabalho (C # loja) é que se você não pode serializar-lo, não colocá-lo na entidade.

Foi útil?

Solução

Matt,

Eu diria que sua loja está escrevendo código processual. Quero deixar claro que não há nada de errado com que muitos sistemas grandes (incluindo muitos que eu tenho trabalhado em) foram escritos usando o código processual. Há um tempo e lugar para ele.

Agora o código de procedimento não tem lugar em um modelo de domínio. Se você quiser usar um estilo mais processual que é bom, mas usá-lo com algo parecido com um módulo de mesa ou um Active Record. Não é a falta de OO que eu estou considerando a possibilidade de ser tão destrutivo na orientação, mas o uso de um modelo de domínio com a lógica processual.

Isso faz com que um para gastar uma grande quantidade de recursos que constroem a camada de domínio (diferença de impedância, pensou tempo de processo para agregados de construção, isolamento, linguagem ubíqua etc) sem receber qualquer um dos benefícios que a camada de domínio (geralmente manutenção) seria de outra forma providenciar. Em outras palavras, enquanto você pode atender às suas necessidades funcionais muito bem você acaba gastando uma grande quantidade de seu orçamento com quase nenhum retorno.

Agora, para voltar ao que "é um comportamento" Eu gostaria de focar a questão a partir de uma Orientada a Objetos em oposição a um ponto de vista "Domain Driven Design". Um objeto geralmente encapsulam algum estado e geralmente expor alguns comportamentos.

reiteração rápida: estado encapsular, expor o comportamento

Então, o que comportamentos devem ter um objeto? Simplificando, devem ser os comportamentos que operam sobre o estado em que se encapsular. Em um mundo ideal OO comportamental do estado nunca seria exposta a partir os únicos comportamentos objeto. Coloque taticamente em código se começar a ver um código como:

Customer c = GetCustomerFromRepository();
c.Status = CustomerStatuses.Deleted;
c.LastUpdated = DateTime.Now;
c.UpdatedBy = GetCurrentUser();
CustomerRepository.Save(c);

Temos uma violação SRP ... Este código é o código que deve ser um comportamento do objeto cliente, porque a "responsabilidade" do objeto cliente é.

estado

Encapsulate sobre um cliente e expor comportamentos.

Como tal, podemos ver que seria melhor ter um método Customer.Delete (). (Sim, este é um mau exemplo eu sei ...)

Agora nós também chegar a este usando TDD. É muito mais fácil para nós para lidar em testes com a costura que o comportamento proporciona que as costuras onde todo o estado está exposta. A razão para isso é que eu não preciso duplicar a lógica em meus testes. O código do cliente não cuidado como funciona uma exclusão ... ele só se importa que o cliente expõe o comportamento. Como tal, em nossos testes, em vez de afirmar que c.State == CustomerStates.Deleted e c.UpdatedBy == getCurrentUser () etc etc Nós simplesmente afirmar que o método de exclusão foi chamado na costura cliente usando um mock.

Agora, para voltar ao título. A quantidade de lógica que deve estar em um objeto de negócios é a quantidade de lógica que cai sob a sua responsabilidade de encapsular seu estado. Às vezes isso é muito, às vezes não é. Há lugares onde você deseja usar serviços, bem ... um bom exemplo seria coordenar a interação entre muitos objetos de domínio para um determinado comportamento, mas mesmo aqui o serviço deve ser chamado comportamentos sobre os objetos de domínio .

Isso vai ajudar a esclarecer as coisas um pouco?

Greg

Outras dicas

Se você está chamando-lhes o seu "modelo de domínio objetos" então eu vou assumir que você está se referindo ao padrão de modelo de domínio do Fowler. http://martinfowler.com/eaaCatalog/domainModel.html

Dada essa suposição, então a resposta à sua pergunta é "toda a lógica de negócios", uma vez que é essencialmente a definição do padrão.

Infelizmente o termo "modelo de domínio" parece ter sido enfraquecido recentemente para dizer apenas um modelo de objeto de seus dados sem comportamento.

Se você não tiver feito isso, gostaria de encorajá-lo a ler PoEAA e decidir onde você acha que a lógica de domínio pertence em sua situação. Se você decidir sobre um modelo de domínio, então eu encorajo-vos a ler o livro DDD de Evan e aprender sobre as diferenças entre entidades, objetos de valor e serviços.

Espero que ajude!

Ultimamente, tenho sido brincando com a idéia de criar modelos de domínio que têm estrutura e apenas aqueles comportamentos que são universais para esse modelo (ou seja, comportamentos que podem ser usados ??em vários contextos limitados) com métodos de extensão para o comportamento específico para um contexto limitada. Isso mantém os modelos de domínio perto de um DTO (para aqueles que assim) e restringe o uso desse modelo de domínio apenas para os comportamentos permitidos dentro de um contexto limitada. De modo que poderia ser uma opção para uma resposta de meia-of-the-road. :)

O ponto principal é como se define a lógica. Para dar alguns exemplos:

  1. Eu não categorizar uma getFullName function () em uma entidade Pessoa, que apenas concatena algumas cadeias, como a lógica.
  2. Calcular um valor de item da ordem seria mais provável qualificar para ser lógica.
  3. Fazer algumas transações de reserva Eu definitivamente dizer é lógica.

O ponto 1 e talvez 2 iria para me para a entidade. O ponto 3 não. Então eu definir a lógica como:

  • qualquer operação que faz qualquer coisa relacionada a persistência (leitura / gravação)
  • qualquer operação que envolve qualquer outro (que não estão directamente relacionados com, por exemplo mestre-detalhe) entidade

IMO, qualquer uma dessas operações não pertencem em entidades.

Agora, por que / quando eu não iria colocar também apontam 1 e 2 Tipo operações em uma entidade? É uma situação bastante raro, mas eu não faria isso, assim que os dados armazenados nas necessidades da entidade a ser interpretado, de alguma forma antes que possa ser usado pelo aplicativo (por exemplo, se dependendo usuário atual, o conteúdo de campo X tem um significado diferente), o que significa próprios dados da entidade produz alguma lógica.

Tanto quanto eu entendo, toda a lógica de negócios relacionada com uma entidade deve ir para essa entidade. Este é constituído por qualquer lógica que define o comportamento ou a estrutura interna da entidade com base nas regras de negócios do sistema. Este não deve incluir lógica de apresentação ou a lógica de persistência (a exceção óbvia é com o padrão de projeto Active Record), mas deve incluir coisas tais como validação de dados, relações entidade, máquinas de estado e outras coisas que definem como se comporta entidade em termos de real coisa mundo que está tentando modelo.

A forma como eu tentar olhar para ele é para tentar fazer meus modelos ser tão resuable possível. Sempre tente pensar em como o modelo seria usado se ele onde a ser portado para um sistema diferente, onde o código do cliente (ou código usando a entidade) podem ser diferentes. Se a funcionalidade não faz parte da entidade será que ainda se comportam da mesma forma seguindo as mesmas regras de negócio? Se a resposta for não, então o a funcionalidade deve ir na entidade.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top