Sugestão: Divida seu Modelo de Dados / Modelo de Relacionamento de Entidade longe do modelo de objeto de seu aplicativo
Em ambos os cenários, parece que o seu modelo de dados / entidade está misturado com o comportamento da sua aplicação.
Das entidades brutas data que vejo no seu modelo, parece que elas podem ser resumidas como:
De uma perspectiva de dados / entidades brutos, parece não haver necessidade real de entidades separadas representarem as tags Novo ou Em Revisão ; No seu segundo diagrama você tem várias entidades Tag
que parecem diferir apenas pelos dados armazenados; tornando essas entidades redundantes.
Além disso, as entidades acima certamente farão sentido em seu Modelo de Dados / Camada de Acesso a Dados, mas não parecem fazer sentido como objetos de aplicativo (isto é, objetos que contêm comportamento / métodos relacionados a seus requisitos funcionais - principalmente aqueles que cercam sua interface do usuário / Views).
Considere as funções típicas de um aplicativo de interface do usuário do CRUD
- Visualização somente leitura de uma lista de dados / registros abreviados parcialmente visíveis
- Visualizar dados, incluindo campos calculados com base em um instantâneo do banco de dados
- Caixa do editor para adicionar / atualizar novos dados
- Visualizar alterações antes da confirmação final (com a opção de descartar)
- Validar dados recém-digitados antes de ativar um botão
O problema de vincular seu comportamento ao seu modelo de entidade é que você não só dificulta muito as operações típicas de CRUD UI, mas também acaba com as classes de entidade que violam o SRP.
Entidades de dados de um modelo de dados existem para representar os dados persistentes / armazenados para o seu aplicativo e nada mais. Então, sem validação, sem comportamento de interface do usuário / exibição, sem consultas, sem lógica, apenas simples estruturados dados.
Considere colocar seu modelo de dados completo (com dados brutos, sem comportamento) em uma classe DataModel
, que pode incluir funções para seu armazenamento persistente, como Carregar / Salvar, e acessadores para os dados em si.
Em seguida, usando o modelo de dados para acesso a dados, você pode encapsular o restante do comportamento do aplicativo em objetos de aplicativo, que conhecem seu modelo de dados e sua estrutura, cuja finalidade, entre outras coisas, é gerar o Visualizar dados (também conhecido como "ver modelos" para criar um termo de interface do usuário popular - onde preocupações como a validação da interface do usuário podem normalmente ser usadas; modelos de exibição são objetos de aplicativos que são comumente usados em padrões como MVC / MVP / MVVM para preencher dados de exibição e para passar dados de UI para baixo para o aplicativo principal).
por exemplo:
// Possible ORM model:
class DataModel{
public List<BugReport> reports;
public List<Tag> tags;
public List<Duplicate> duplicates;
public void CreateReport(BugReport bugReport) { /* etc.. */ }
public void CreateTag(Tag tag) { /* etc.. */ }
public void Commit() { /* ... */ }
}
class BugReportMainApplication {
private DataModel model;
public BugReportMainApplication(DataModel dataModel) {
model = dataModel;
}
public BugReportListViewModel GetReportList(List<Tag> queryTags) {
// etc.
}
public EditorViewModel GetChangableReport(int id) {
// etc.
}
public void AssignTag(int bugReportId, Tag tag) {
// etc.
}
}
As entidades de dados brutos geralmente não devem estar interessadas em interfaces / polimorfismo porque elas não têm comportamento - portanto, o problema com relação ao método getDuplicate()
interface seria irrelevante para o modelo de entidade; em vez disso, manipulado em qualquer parte da sua lógica de aplicação que lide especificamente com a exibição / manipulação de seus links para duplicar BugReport
s.
Para resumir - considere dividir seu aplicativo em Camadas para evitar poluir as entidades que representam seus dados brutos com a lógica específica do aplicativo e evitar ser forçado a gravar compromissos / O trabalho gira em torno de abstrações imperfeitas, como a interface BugTag
.