O que é um design melhor para expor informações em um sistema de rastreamento de bugs?

5

Estamos trabalhando em um sistema BugTracking e ainda estamos no processo de aprendizado.

Um BugReport tem um título, descrição, (...) e também uma tag. Uma etiqueta representa o progresso do BugReport, e.

  • Novo: BugReport recém-criado
  • Em revisão: uma correção foi feita e está em revisão.
  • Duplicar: O BugReport é uma duplicata de outro BugReport (por exemplo, é o mesmo erro)

No último caso, apenas um BugReport deve ser marcado como duplicado e deve armazenar o BugReport do qual é duplicado.

Há um caso de uso em que um BugReport deve ser inspecionado: "O sistema mostra uma visão geral detalhada do relatório de bug selecionado (...)"

Entre os colegas, há uma discussão sobre qual projeto é melhor.

Considere seguir dois designs. Apenas partes relevantes do sistema são mostradas. A interface do usuário não é necessariamente parte do sistema.

Design 1

Prós:
Nessedesign,ousuáriorecebeumainstânciadainterfaceIBugReportnaqualosinspetoresrelevantessãodefinidos(getTitle(),getDescription(),...).Assim,ousuárioécapazderecuperarapenasasinformaçõesnecessárias.

Contras:
Essedesignimplicaquetodoobjetodenegóciosprecisarádeumainterfacequedefinamétodosquepossamserusadospelousuário.Alémdisso,quandogetDuplicate()échamadoemumBugTag,ousuáriopoderecuperarumnuloseoBugTagnãoforumDuplicate.Se,nofuturo,porexemploSobrevisãoénecessárioterumcampo(porexemplo,umcampodeusuárioqueindicaquemestárevisandooBugReport),métodosadicionaisterãoqueserdefinidoseimplementadosemtodasasclassesBugTagqueamaioriadelesretornaránull,similarmenteagetDuplicate()./p>

Osparesquesãoafavordessedesigntêmidéiassemelhantesparaoutrasdecisõesdedesign,ouseja,quandoaplicável,retornamumainterfacedeumobjetodenegócios.

Design2

[NOTA:noBugReport,inspecionarState()devesernomeadoinspecionarBugReport()]

Prós:
QuandoosBugTagsganhamcamposadicionais,somenteométodoinspectState()teráqueseralteradodeacordo.Nãohánecessidadedeinterfacesparaosobjetosdenegócios.osistemafazexatamenteoqueocasodeusopergunta:inspecioneoBugReport(istoé,retorneumaStringrepresentandosuarepresentação).

Contras:OusuáriorecebeumaStringnaqualtodasasinformaçõesdoBugReportestãoconcentradas.Seousuárioquiserapenasotítulo,eleaindareceberáasinformaçõescompletasdoBugReport.

Osparesquesãoafavordestedesigntêmideiassemelhantesparaoutrasdecisõesdedesign,ouseja,analisarasinformaçõesparaumaStringeexporissoparaomundoexterior.

Somosumpequenogrupodetrêspessoasnasquaiseucrieiosegundodesigneoutrapessoacomoprimeirodesign.Estamosdiscutindomuitosobreissoeestamosambosfirmementedepé.Aterceirapessoatentaavaliarosdoisdesignsedarprósecontras.

Estamostentandoaplicar Princípios de GRASP . Acoplamento e coesão são princípios muito importantes em nosso design. A extensibilidade é importante, assim como o projeto sofre várias iterações. Cada iteração requer funcionalidade adicional. Por tudo isso, argumento que o segundo design é muito melhor. É, por exemplo, muito mais extensível.

Quais são os prós e contras adicionais não mencionados acima? Ambos os projetos estão ok ou são um / ambos os projetos não concluídos?

Esta questão surgiu após isso .

    
por Auberon 20.03.2016 / 15:51
fonte

3 respostas

3

Ambos os designs violam: Diga, não pergunte.

Pode ser tarde demais. O resto do seu design, ou a sua mentalidade, pode estar exigindo a maneira de fazer as coisas. Se não, considere um mundo onde você não pergunta BugTag o que está acontecendo. Você diz quando é hora de fazer isso.

BugTag


display(): void

Desta forma, BugTag é um objeto de comportamento e não um objeto de dados (como String). Ele ainda conterá dados, mas os dados serão encapsulados para que nenhum outro objeto precise saber disso. Você precisará passar algo do BugTag para conversar quando for exibido. Mas você realmente não deveria se sentir obrigado a devolver os dados a ninguém. Esses são seus dados. Guarde-a com inveja.

    
por 20.03.2016 / 20:33
fonte
1

A interface BugTag nem deveria saber que Duplicate existe. No design 2, ele não sabe. Não quer saber. Isso é bom. Ter getDuplicate() no BugTag no Design 1 cria uma violação do princípio de abertura / fechamento esperando para acontecer.

Como, então, você cria um link navegável de um BugReport para outro? Bem, você faz como design 1. Você acabou de chamar de algo que não implica Duplicate existe.

BugTag


getLinkedBugReport(): BugReport
inspectState(): String

Agora, você tem um design que não será quebrado se, posteriormente, você precisar adicionar um Working BugTag ou até mesmo um Revisiting BugTag vinculado a um BugReport .

    
por 20.03.2016 / 20:16
fonte
1

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:

  • BugReport
  • Tag
  • Duplicar

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 .

    
por 20.03.2016 / 21:33
fonte