Devemos escrever um projeto de arquitetura detalhado ou apenas um esboço ao projetar um programa?


8

Quando estou fazendo o design de uma tarefa, continuo lutando contra essa sensação incômoda de que, além de ser um esboço geral, será mais ou menos ignorado no final. Vou dar um exemplo:

Eu estava escrevendo um front-end para um dispositivo que possui operações de leitura / gravação. Fazia sentido no diagrama da classe fornecer uma função de leitura e gravação. No entanto, quando se tratou de escrevê-las, percebi que elas eram literalmente a mesma função, com apenas uma linha de código alterada (chamada de função de leitura versus gravação); portanto, para evitar duplicação de código, acabei implementando uma função do_io com um parâmetro que distingue entre operações. Adeus design original.

Essa não é uma mudança terrivelmente perturbadora, mas acontece frequentemente e também pode ocorrer em partes mais críticas do programa, por isso não posso deixar de me perguntar se há um ponto para projetar mais detalhes do que um esboço geral, pelo menos quando trata da arquitetura do programa (obviamente, quando você está especificando uma API, precisa explicar tudo).

Isso pode ser apenas o resultado da minha inexperiência em criar design, mas, por outro lado, temos metodologias ágeis que dizem "desistimos de planejar com antecedência, tudo vai mudar em alguns dias", o que geralmente é como eu me sinto.

Então, como exatamente devo "usar" o design?


1
A do_ioparece ser um detalhe de implementação interna dessa classe. A interface pública será e provavelmente ainda deve ser, read(...)e write(...)é muito mais detalhada sobre a intenção da chamada.
Johannes S.

Respostas:


6

Se fazia todo o sentido fornecer operações de leitura e gravação, por que removê-las?

Do ponto de vista do usuário, ainda faz todo o sentido. Os detalhes da implementação não devem interferir com uma interface fornecida.

O que você pode fazer é criar um do_io interno chamado por leitura e gravação.

No final, o processo de design segue estas etapas:

  • defina a interface
  • desenhar um design aproximado
  • refine sem alterar a interface acordada

1
As decisões de "otimização" +1 para evitar a duplicação de código não exigem necessariamente uma alteração no design original.
Marjan Venema

4

O design da arquitetura de um programa evolui com o tempo. Eu não acho que no começo você tenha todas as informações necessárias para ter um design correto.

Portanto, se você seguir o design que pensou no início, provavelmente se limitará.

A menos que você esteja criando uma API pública, acho que é correto fazer alterações no design ao longo do caminho.

Também uma das melhores coisas a fazer é investir em uma ferramenta que pode extrair o design do código (como NDepend for C #)


2

O Agile afirma responder a esse problema com algum sucesso. No entanto, Fred Brooks teve a resposta há 40 anos, quando escreveu "Escreva um para jogar fora, porque você irá de qualquer maneira". Quem não estuda história está fadado a repeti-la.

Então, o que fazer é tratar o design como um plano, feito com o único objetivo de alterá-lo. Projetos que não podem ser alterados estão condenados. Você deve estar preparado para jogar fora os maus.

Se o design é de uma API pública, interface ou algo semelhante, é preciso tomar muito cuidado, pois o custo da mudança é alto, no entanto, a incapacidade de mudar o condenará ao fracasso.

Não pense por um segundo que você é bom o suficiente e saiba o suficiente para acertar primeiro, segunda ou até terceira vez.


2

Na realidade, na maioria dos projetos da vida real, as coisas mudam:

  • (como você observou) o ambiente / plataforma / APIs que o programa usará pode ser diferente do que se supunha originalmente
  • os requisitos podem mudar a qualquer momento
  • o mercado / o mundo ao redor pode mudar, obsoletos alguns requisitos (ou todo o projeto)
  • ...

É por isso que os métodos Agile se opõem ao Big Design Up Front, porque ele apenas fornece uma falsa sensação de segurança, envolve muito esforço inútil e dificulta a adaptação às mudanças inevitáveis.

No entanto, o Agile não é igual a "desistir do planejamento muito à frente" . Os métodos ágeis envolvem a quantidade necessária de planejamento cuidadoso e cuidadoso, apenas não mais. Eles são muito disciplinados e diferentes da "codificação de cowboy". Fazer a quantidade certa de design é uma tentativa contínua de encontrar o equilíbrio certo entre super e sub-design. Mas IMHO é melhor errar um pouco demais, do que fazer pouco.

O design inicial não deve tentar cobrir tudo, mas deve dar a você uma sensação segura de que sabe seguir em frente com a implementação, você tem respostas para as perguntas fundamentais sobre a arquitetura e um modelo mental de como o uso conhecido casos vão funcionar na vida real. Na visão Agile, o teste real de um design é a implementação; portanto, não há problema em começar a escrever código mesmo durante a fase de design, apenas para ter uma idéia de como seria o design previsto ou para prototipar / validar rapidamente alguma suposição. . Observe, porém, que a maioria desses trabalhos iniciais deve ser descartada assim que a resposta à pergunta for determinada. Quase sempre é uma coisa ruim começar a criar um aplicativo de produção real a partir de um protótipo inicial.

E também é bom voltar e modificar o design se você fizer uma nova realização importante durante a implementação. Este é um feedback importante em dois níveis:

  • seu projeto concreto precisa ser adaptado ao mundo em mudança e
  • seu processo de design precisa ser adaptado para cobrir essas possibilidades no futuro (ou seja, da próxima vez, pense no caso de uso da leitura e gravação no dispositivo com antecedência).

2

É sempre importante quando você cria qualquer documento para entender qual é o seu objetivo.

Acho que temos que ter cuidado com o que chamamos de documentos de "arquitetura". É tudo uma questão de escopo.

Se você está falando de um sistema que requer várias equipes ou grupos de equipes, está falando de um documento cujo objetivo é detalhar no mínimo:

  • Quais são os componentes no sistema
  • Como os componentes estão conectados
  • Quais são as responsabilidades de cada componente
  • Quem deveria estar trabalhando em cada componente

Se o seu documento for para um sistema menor, você poderá reduzir o número de itens que precisa incluir, pois algumas suposições serão inerentes ao sistema existente. Por exemplo, suponha que você esteja montando um recurso que precisará ter o trabalho realizado em um site e algumas novas chamadas em uma API; seu documento servirá como uma maneira de definir o seguinte:

  • Que lógica viverá no site
  • Qual lógica viverá na API
  • Qual será a API que chama contratos (melhor palpite)

Esses documentos de resumo servem para trazer à tona as conversas sobre quem deve fazer o que e como eles devem se integrar. Depois que essas decisões são tomadas, as equipes podem operar amplamente de maneira autônoma, com uma chance muito menor de problemas de integração.

Quanto mais problemas de integração você perceber, mais detalhados serão os documentos.


1

Você parece ter encontrado um enigma comum no desenvolvimento de software. Não é possível planejar um sistema inteiro antes de começar a construí-lo, porque há muitas coisas que você ainda não sabe.

Essa é a razão pela qual as metodologias ágeis usam o desenvolvimento iterativo, porque permite que o feedback regular mude a direção do software, em vez de deixar as coisas irem mais longe do que é realmente necessário. Cada alteração afetará o design.

Portanto, tendo dito tudo isso, eu teria escrito dois métodos para o cenário específico descrito acima, mas teria encapsulado a lógica compartilhada em um terceiro método privado que pode ser usado pelos dois métodos. Dessa forma, os métodos públicos são responsáveis ​​por apenas uma coisa e são fáceis de nomear read_filee write_filedizer exatamente o que fazem, enquanto isso do_fileé ambíguo.

Livros como Clean Code , Robert C Martin e Emergent Design , Scott L Bain fornecerão informações mais detalhadas sobre esse assunto.


1

Isso pode ser apenas o resultado da minha inexperiência em criar design, mas, por outro lado, temos metodologias ágeis que dizem "desistimos de planejar com antecedência, tudo vai mudar em alguns dias", o que geralmente é como eu me sinto.

Não é possível planejar todos os detalhes com antecedência. É perfeitamente aceitável fazer alterações aqui e ali.

No entanto, é importante planejar com antecedência. Agilidade não significa design nem planejamento , mas significa que você está esperando mudanças.

Então, como exatamente devo "usar" o design?

Você deve usar seu design como ele é. Como não está escrito na pedra, é fácil alterá-lo.


1

A quantidade de tempo que você gasta na arquitetura deve ser determinada pelo grau de risco nessa parte do sistema.

Geralmente, você deve tomar uma decisão bastante cedo no (s) estilo (s) de arquitetura - em camadas, componente, pub-sub, etc. etc. Nenhuma quantidade de código limpo e acoplamento flexível facilitará a troca de estilos no final do um projeto.

Isso fornecerá uma idéia básica dos diferentes componentes do sistema e qual será o roteiro à medida que o sistema e os requisitos evoluírem com o tempo.

Depois de entrar nos casos de uso, acredito que você deve fazer o design suficiente para garantir a compreensão completa do problema e da solução. Se é o código da placa da caldeira que você fez repetidas vezes, o risco de errar (no sentido arquitetônico - você ainda precisará testar, é claro) é bem baixo e, portanto, é provável que haja uma quantidade de design inicial para ser razoavelmente mínimo. Se for um problema novo, ou com uma solução pouco clara ou potencialmente arriscada para os negócios, ela merecerá muito mais tempo pensando nas coisas.

É claro que existem várias maneiras de fazer isso - UML, protótipos, esboços do quadro branco, etc. Qualquer que seja o método que você use - o importante é lembrar que o objetivo deles é ajudá-lo a pensar e se comunicar sobre o seu design.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.