Arquitetura para a / camada de acesso a banco de dados de objetos de negócios

StackOverflow https://stackoverflow.com/questions/118955

  •  02-07-2019
  •  | 
  •  

Pergunta

Por várias razões, estamos escrevendo uma nova biblioteca de armazenamento objetos de negócios / dados. Um dos requisitos desta camada é separar a lógica das regras de negócio, e a camada de armazenamento de dados reais.

É possível ter várias camadas de armazenamento de dados que implementam o acesso ao mesmo objeto - por exemplo, uma fonte principal de armazenamento de dados "banco de dados" que implementa a maioria dos objetos, e outra fonte "ldap" que implementa um objeto de usuário. Neste cenário, o usuário pode opcionalmente vir de uma fonte LDAP, talvez com funcionalidade ligeiramente diferente (por exemplo, não é possível salvar / atualizar o objeto Usuário), mas caso contrário, é usado pela aplicação da mesma maneira. Outro tipo de armazenamento de dados pode ser um serviço web, ou um banco de dados externo.

Existem duas formas principais que estão olhando para implementar isso, e eu e um colega de trabalho discordam em um nível fundamental que é correto. Eu gostaria de alguns conselhos sobre qual é o melhor para usar. Vou tentar manter minhas descrições de cada tão neutra quanto possível, como eu estou procurando alguns objetivos pontos de vista aqui.

  • Os objetos de negócios são classes base e armazenamento de dados objetos objetos de negócios herdar. ofertas de código cliente com objetos de armazenamento de dados.

    Neste caso, as regras comuns de negócios são herdadas por cada objeto de armazenamento de dados, e são os objetos de armazenamento de dados que são diretamente usados ??pelo código do cliente.

    Isto tem a implicação que determina código cliente qual o método de armazenamento de dados a utilizar para um dado objecto, porque tem de declarar expressamente um exemplo para este tipo de objecto. necessidades código de cliente para saber explicitamente as informações de conexão para cada tipo de armazenamento de dados que está usando.

    Se um armazenamento de dados de camada implementa a funcionalidade diferente para um determinado objeto, o código do cliente sabe explicitamente sobre isso em tempo de compilação porque o objeto parece diferente. Se o método de armazenamento de dados é alterado, o código do cliente tem de ser actualizada.

  • Objetos do negócio objetos de armazenamento de dados Encapsular.

    Neste caso, objetos de negócios são directamente utilizados pelo aplicativo cliente. aplicação cliente passa ao longo informações de conexão base para camada de negócios. Decisão sobre qual método de armazenamento de dados de um determinado usos de objetos é feita por código de objeto de negócios. informações de conexão seria um pedaço de dados obtidos a partir de um arquivo de configuração (app cliente não sabe realmente / cuidado com detalhes do mesmo), que pode ser uma cadeia de conexão única para um banco de dados, ou várias cadeias de ligação de peças para vários tipos de armazenamento de dados. tipos de conexão adicionais de armazenamento de dados também pode ser lido a partir de outro local - por exemplo, uma tabela de configuração em um banco de dados que URLs Especifica a vários serviços na web.

    A vantagem aqui é que, se um novo método de armazenamento de dados é adicionado a um objeto existente, uma configuração pode ser definida em tempo de execução para determinar qual o método a utilizar, e é completamente transparente para os aplicativos cliente. aplicativos cliente não precisam ser modificados se o método de armazenamento de dados para uma determinada mudanças objeto.

  • Os objetos de negócios são classes base, fonte de dados objetos herdam a partir de objetos de negócios. ofertas de código de cliente primeiramente com classes de base.

    Este é semelhante ao primeiro método, mas o código do cliente declara variáveis ??dos tipos de objetos de negócios de base e Load () / Create () / etc métodos estáticos sobre os objetos de negócios devolver os objetos digitado-fonte de dados apropriadas.

    A arquitetura desta solução é semelhante ao primeiro método, mas a principal diferença é a decisão sobre qual objeto de armazenamento de dados para usar para um dado objeto de negócios é feito pela camada de negócio, e não o código do cliente.

Eu sei que já existem bibliotecas ORM que fornecem alguma desta funcionalidade existente, mas por favor desconto aqueles para agora (há a possibilidade de que uma camada de armazenamento de dados é implementada com uma destas bibliotecas ORM) - também notar que eu sou deliberadamente não dizendo o que a linguagem é sermosed aqui, a não ser que ele é fortemente tipado.

Eu estou procurando alguns conselhos gerais aqui sobre qual método é melhor para uso (ou fique à vontade para sugerir outra coisa), e por quê.

Foi útil?

Solução

i pode sugerir uma outra alternativa, com possivelmente melhor desacoplamento: objetos de negócios objetos de uso objetos de dados e de dados implementar objetos de armazenamento. Isso deve manter as regras de negócio nos objetos de negócios, mas sem qualquer dependência da fonte ou formato de armazenamento, permitindo que os dados objetos de apoio, seja manipulações são necessários, incluindo a mudança do armazenamento de objetos dinamicamente (por exemplo, para online / manipulação off-line)

este cai na segunda categoria acima (objetos de negócios objetos de armazenamento de dados Encapsular), mas semântica dos dados separa de mecanismos de armazenamento de forma mais clara

Outras dicas

Você também pode ter uma fachada para manter do seu cliente para chamar o negócio diretamente. Também cria pontos de entrada comuns ao seu negócio.

Como disse, o seu negócio não deve ser exposto a qualquer coisa, mas o DTO e fachada.

Sim. Seu cliente pode lidar com DTOs. É a maneira ideal para passar dados através de sua aplicação.

Eu geralmente preferem o "objeto de negócios encapsula objeto de dados / armazenamento" melhor. No entanto, no curto você pode encontrar alta redundância com seus objetos de dados e seus objetos de negócios que podem parecer não vale a pena. Isto é especialmente verdadeiro se você optar por um ORM como a base de sua camada de acesso a dados (DAL). Mas, no longo prazo é onde o off pagamento real é: o ciclo de vida da aplicação. Tal como ilustrado, não é incomum para "dados" para vir de um ou mais subsistemas de armazenamento (não se limitando a RDBMS), especialmente com o advento da computação em nuvem, e como normalmente o caso em sistemas distribuídos. Por exemplo, você pode ter alguns dados que vem de um serviço RESTful, outro pedaço ou objeto de um RDBMS, outro de um arquivo XML, LDAP, e assim por diante. Com essa percepção, isto implica a importância de muito bom encapsulamento do acesso aos dados do negócio. Tome cuidado para que dependências você expõe (DI) através de seus c-res e propriedades também.

Dito isso, uma abordagem que eu tenho sido brincando com é colocar a "carne" da arquitetura em um controlador de negócio. Pensando de acesso a dados contemporânea mais como um recurso do pensamento tradicional, o controlador então aceita em um URI ou outra forma de metadados que pode ser usado para saber o que recursos de dados deve gerir para os objetos de negócios. Em seguida, os objetos de negócios NÃO-se encapsular o acesso a dados; em vez do controlador faz. Isso mantém o seu negócio objetos leve e específico e permite que o seu controlador para fornecer otimização, modularidade, ambiente transação, e assim por diante. Note-se que o seu controlador seria então "host" suas coleções de objetos de negócios, bem como a peça controlador de muitos ORMs fazer.

Além disso, também consideram a gestão de regras de negócios. Se você é vesgo duro em sua UML (ou o modelo em sua cabeça como eu faço: D), você vai notar que seu negócio governa modelo são, na verdade, um outro modelo, às vezes até mesmo persistente (se você estiver usando um motor de regras de negócio, por exemplo) . Eu consideraria deixar o controlador negócios também realmente controlar suas regras subsistema também, e deixe a sua referência de objeto de negócios as regras através do controlador. A razão é porque, inevitavelmente, implementações de regras muitas vezes precisam realizar pesquisas e cruzamento de dados, a fim de determinar a validade. Muitas vezes, ele pode exigir tanto pesquisas de objetos de negócios hidratados, bem como pesquisas de banco de dados back-end. Considere detectar entidades duplicadas, por exemplo, onde apenas o "novo" é hidratado. Deixando suas regras a serem gerenciados pelo controlador do negócio, você pode então fazer mais qualquer coisa que você precisa sem sacrificar o que agradável abstração limpa no seu "modelo de domínio".

Em pseudo-código:

using(MyConcreteBusinessContext ctx = new MyConcreteBusinessContext("datares://model1?DataSource=myserver;Catalog=mydatabase;Trusted_Connection=True ruleres://someruleresource?type=StaticRules&handler=My.Org.Business.Model.RuleManager")) {

User user = ctx.GetUserById("SZE543");
user.IsLogonActive = false;
ctx.Save();
}

//a business object
class User : BusinessBase {
  public User(BusinessContext ctx) : base(ctx) {}

  public bool Validate() {
    IValidator v = ctx.GetValidator(this);
    return v.Validate();
  }
}

// a validator
class UserValidator : BaseValidator, IValidator {
 User userInstance;
 public UserValidator(User user) {
  userInstance = user;
 }

 public bool Validate() {
   // actual validation code here
   return true;
 }
}

Os clientes nunca deve lidar com o armazenamento de objetos diretamente. Eles podem lidar com DTO diretamente, mas qualquer objeto que tem qualquer lógica para o armazenamento que não está envolvido em seu objeto de negócios não deve ser chamado pelo cliente diretamente.

Confira CSLA.net por Rocky Lhotka.

Bem, aqui estou eu, o colega de trabalho Greg mencionado.

Greg descreveu as alternativas que temos vindo a considerar com grande precisão. Eu só quero acrescentar algumas considerações adicionais para a descrição situação.

O código do cliente pode não ter consciência sobre DataStorage onde objetos de negócios são armazenados, mas é possível, quer no caso em que há apenas um DataStorage, ou há vários datastorages para o mesmo tipo de objeto de negócios (usuários armazenados no banco de dados local e externo o LDAP), mas o cliente não criar esses negócios objetos. Em termos de análise do sistema, isso significa que não deve haver casos de uso em que a existência de dois datastorages de objetos do mesmo tipo podem afetar o fluxo de caso de uso.

Assim que a necessidade de distinguir objetos criados em diferentes armazenamentos de dados surgem, o componente cliente deve tornar-se consciente sobre multiplicidade de armazenamentos de dados em seu universo, e inevitavelmente se tornará responsável pela decisão que o armazenamento de dados para uso no momento do objecto de criação (e, penso eu, carregamento a partir de um objecto de armazenamento de dados). camada de negócios pode fingir que está fazendo estas decisões, mas o algoritmo de tomada de decisão será baseada no tipo e conteúdo da informação proveniente do componente do cliente, fazendo com que o cliente efetivamente responsável pela decisão.

Esta responsabilidade pode ser implementado de várias maneiras: ele pode ser um objeto de conexão de tipo específico para cada armazenamento de dados; ele pode ser segregared métodos para chamar para criar novas instâncias BO etc.

Saudações,

Michael

CLSA tem sido em torno de um longo tempo. No entanto, eu gosto da abordagem que é discutido em Eric Evans livro http://dddcommunity.org/

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