A necessidade de especificação de design de software diminuiu significativamente com a evolução de linguagens de programação mais expressivas?


16

Para muitas pessoas de TI, inclusive eu há alguns anos, o processo ideal de desenvolvimento de software envolveria a criação de documentos de projeto detalhados com muitos diagramas UML antes que uma linha de código fosse escrita. (Isso parece uma descrição do modelo em cascata, mas é o mesmo com o ágil, exceto que as iterações são menores.)

Nos últimos dois ou três anos, mudei completamente de idéia. Ainda acho que uma especificação detalhada de requisitos com casos de teste associados é absolutamente essencial. Para projetos grandes, eu também exigiria um esboço da arquitetura geral antes de começar a codificar. Mas todo o resto deve ser feito em código, tanto quanto possível. No caso ideal, não deve haver descrição do design do software, exceto o próprio código.

Como cheguei a essa conclusão? Aqui estão alguns argumentos:

Comentários

As ferramentas para escrever documentos ou criar diagramas fornecem pouco feedback. Sim, existem ferramentas de modelagem que realizam algumas verificações de consistência nos diagramas UML, mas são limitadas e têm muita sobrecarga.

Sem feedback, é difícil reconhecer e corrigir erros.

Assim que você escreve o código, recebe muitos comentários, por exemplo:

  • Erros e avisos do compilador
  • Resultados da análise de código estático
  • Testes unitários

Os erros podem ser rapidamente reconhecidos e corrigidos.

Consistência

Para garantir que o código seja consistente com seus documentos, você deve verificar novamente e novamente. Se houver alterações frequentes, é difícil manter o código e os documentos sincronizados.

Reestruturação

Existem ferramentas e técnicas poderosas para refatorar código, enquanto a refatoração de descrições ou diagramas textuais geralmente é difícil e propensa a erros.


Há uma condição prévia para fazer isso funcionar: O código deve ser fácil o suficiente para ler e entender. Provavelmente isso não pode ser alcançado com o Assembler, Basic ou Fortran, mas as linguagens modernas (e as bibliotecas) são muito mais expressivas.

Portanto, se meus argumentos são válidos, deve haver uma tendência a especificações ou documentação de design de software menos ou mais leves. Existe alguma evidência empírica para esta tendência?


2
O design inicial caiu em desuso devido ao desenvolvimento ágil que ganha popularidade à medida que a indústria amadurece. As linguagens cada vez mais expressivas e as ferramentas cada vez mais leves tornaram mais fácil o protótipo, permitindo um desenvolvimento mais ágil. Eu acho que há alguma causa entre os dois.
Reponha Monica

14
Para minha experiência, "a criação de documentos de projeto detalhados com muitos diagramas UML antes de uma linha de código ser escrita" nunca foi uma boa idéia - pelo menos não na época em que eu trabalhava como programador profissional, que é mais do que um década mais longa que a UML. Escolher um design de alto nível antes da codificação, no entanto, é e foi uma boa idéia quando se espera que os sistemas tenham um determinado tamanho. Mas UML IMHO não é a ferramenta certa para isso.
Doc Brown

2
Preguiçoso demais para uma resposta adequada: linguagens de programação mais expressivas e computadores mais poderosos levam a necessidades de programas cada vez mais capazes e complexos, o que leva a especificações de requisitos mais complicadas.
Whatsisname 8/17

2
Leitura recomendada: superando as médias .
Robert Harvey

1
Eu trabalhei em um projeto com um design UML completo. A partir do qual geramos código. Cheguei à conclusão de que nunca mais quis fazê-lo. Era muito mais difícil mudar a UML do que mudar o código; e um modelo UML grande é pelo menos tão difícil quanto um monte de código-fonte. O código "gerado" foi difícil de ler e o gerador deixou "marcadores" no código.
Nick Keighley

Respostas:


9

Eu questiono a premissa de que as línguas são cada vez mais expressivas. Com o código ASP.NET de hoje em c #, escrevo aproximadamente no mesmo nível que escrevi quando escrevi o código ASP no Visual Basic. Ainda usamos c ++. Javascript adicionou recursos, mas no geral o idioma não mudou. O mesmo com o SQL.

Eu acho que essas outras mudanças são mais significativas:

  1. Adoção de testes de unidade automatizados. Alguns diriam que os testes são a especificação. Portanto, não removemos a necessidade de escrever especificações; em vez disso, escrevemos eles no código e não nos documentos do Word.

  2. Mudanças na metodologia de implantação. No passado, era muito caro cometer um erro, porque você precisaria enviar uma cópia atualizada do seu software. Então você tinha que ter cuidado. Com aplicativos orientados pela Web, você pode implantar correções para uso imediato e pode reagir a problemas em vez de antecipá-los, reestruturando o código à medida que avança.

  3. Adoção de padrões de design. Quando todo mundo conhece os padrões, você dificilmente precisa projetar algo; você pode simplesmente dizer "adicionar uma fábrica de repositórios" e sua equipe deve fazê-lo sem precisar ver a UML.

  4. Contratos de dados da SOA. Quase tudo é SOA hoje em dia. Tudo que você precisa é de um WSDL. Os dias de definição e documentação de formatos de transferência de dados se foram. A mudança atual em direção a mais RESTful e microsserviços continua essa tendência.

  5. Softwares são menores. Em parte como resultado das arquiteturas SOA, as equipes estão escrevendo programas menores que estão interligados. Cada componente individual é menos complexo e requer menos design inicial; Além disso, é mais fácil alterar parte da arquitetura sem interromper a solução geral, devido aos disparos forçados pelas definições de interface entre os componentes.

  6. Muito, muito mais uso de bibliotecas estabelecidas. O .NET CLR oferece uma grande quantidade de funcionalidades prontas para uso, portanto, não é necessário criar, por exemplo, um esquema para armazenar em cache os dados da sessão. Bibliotecas de terceiros, como jQuery UI ou Bootstrap, estabelecem padrões para escrever código para funcionar de certa maneira. Você não precisa documentar isso; as equipes devem poder usá-las.

  7. Maturidade da indústria. Os SWEs aprenderam que não existe um projeto "Battlestar Galactica" em que você passa anos e anos tentando alcançar um objetivo específico; quando esses anos tiverem passado, a meta terá mudado. Hoje sabemos que o tempo de colocação no mercado é muito mais importante do que obter tudo exatamente do jeito que queremos no design.

  8. Engenheiros com melhor e mais consistente formação. Hoje em dia, você pode contratar engenheiros que entendam as melhores práticas (espero) e apenas implementá-las sem um documento de design informando o que fazer.

  9. As ferramentas de produtividade como o TFS permitem que você escreva uma tarefa simples que faça referência a um caso de uso e forneça alguns pontos para quaisquer decisões técnicas ambíguas. Você não precisa de muito mais do que isso. Os desenvolvedores podem revisar, estimar, obter revisões de código, fazer check-in etc. tudo através da ferramenta. Isso é muito mais eficiente do que trabalhar com documentos externos, pois une tudo.

Você ainda precisa de documentos de design para algumas coisas ... por exemplo, se seu aplicativo for dividido em diferentes componentes desenvolvidos por equipes diferentes, você precisará pelo menos informar qual componente é responsável por quais requisitos. Mas, na maioria das vezes, as metodologias de desenvolvimento atuais permitem muito mais liberdade, oferecendo ferramentas para gerenciar e conter qualquer risco que possa surgir de um desenvolvedor que toma uma decisão ruim.


3
Nossa indústria tem amadurecido ... um pouco. O item 5 é de longe a mudança mais importante; afeta positivamente todos os outros. Mas o fato de mudarmos todas as nossas tecnologias a cada 5 anos sugere que ainda temos um longo caminho a percorrer, e a expressividade da linguagem (a única coisa que é relativamente estável ao longo do tempo porque a melhoria significativa nessa área é tão difícil) produz mais ganhos do que você acredita.
Robert Harvey

1
Nem tudo é progresso: o salto principal foi, graciosamente, com a invenção do compilador. Mas ainda ensinamos fluxogramas, uma abstração no código assembler (e muitas outras práticas obsoletas). Provavelmente porque esquecemos o porquê?
Ctrl-alt-delor 9/17

6

Eu argumentaria por não .

Por uma simples razão de que

Para muitas pessoas de TI, inclusive eu há alguns anos, o processo ideal de desenvolvimento de software envolveria a criação de documentos de projeto detalhados com muitos diagramas UML antes que uma linha de código fosse escrita.

Nunca foi considerado "ideal", pois a Extreme Programming existe desde os anos 90 . E como você diz:

No caso ideal, não deve haver descrição do design do software, exceto o próprio código.

Foi discutido há séculos. Por exemplo, este artigo lendário de 1992: O que é design de software .

A descrição acima mostra que você pode ter um processo "extremo" com arquitetura altamente evolutiva e abordagem iterativa sem a necessidade de linguagens complexas ou IDEs.

Em vez disso, eu diria que essa mudança "aparente" do design inicial com muitos diagramas e documentos de casos de uso para uma abordagem mais evolutiva e iterativa é simplesmente gerentes da "velha escola" sendo substituídos por novos, que cresceram muito mais ambiente dinâmico e para quem é muito mais fácil aceitar e trabalhar em um ambiente mais "ágil".


6

Concordo bastante com isso, mas acho que começou muito antes do que você sugere. Eu também acho que há outro grande fator além da expressividade. Quando meu pai começou a programar, ele teve que criar cartões perfurados e agendar um horário no computador. Você pode ter uma chance por dia para executar seu programa. Não havia muito tempo para desperdiçar o código de construção, deixá-lo falhar e corrigi-lo. Você conseguiu duas ou três fotos e, se não estava funcionando, estava com problemas.

O risco disso significava que era crucial gastar muito tempo extra para planejar seu programa. As pessoas escreviam seu código a lápis e depois o transferiam para os cartões perfurados. À medida que a tecnologia avançava, era possível codificar diretamente no terminal, mas você ainda estava usando recursos compartilhados e a CPU era cara. Uma metodologia de teste primeiro seria completamente insustentável nesse mundo. Se você não planejasse com antecedência, seus colegas estariam em sua mesa com forquilhas.

Os recursos de computação tornaram-se mais baratos e melhores em um ritmo incrível. Muitas das restrições sob as quais todas essas práticas foram desenvolvidas são completamente eliminadas. Como eufórico, o afastamento disso realmente começou nos anos 90. A continuação de grande parte do grande projeto inicial foi pura inércia.

Portanto, sim, a expressividade aprimorada das linguagens de programação teve um impacto nisso, pelo simples fato de que é mais fácil usar código expressivo como sua própria documentação. O custo de produção de um documento que diz o que o código diz é muito alto e seu valor (inevitavelmente está errado em algum nível). Ao mesmo tempo, o custo de jogar merda na parede e ver o que fica é basicamente desprezível.


3

Acho que você esquece o objetivo de ter documentos de design em primeiro lugar!

Os documentos de design (requisitos, casos de uso, modelos etc.) nos permitem descrever, entender e discutir o sistema em alto nível. A quantidade de detalhes deixados de fora desses documentos é o que os torna úteis.

Não é necessário ter documentos que descrevam o comportamento exato do sistema do sistema em todos os detalhes, pois o próprio código-fonte serve a esse propósito.

O desenvolvimento de software pode ser considerado o processo de transformar especificações legíveis humanas de alto nível em especificações inequívocas de baixo nível, executáveis ​​por uma máquina. Mas você precisa de entrada para esse processo.


Certamente, é necessária uma documentação de alto nível que não lide com detalhes. Mas é exatamente o que espero de uma boa linguagem de programação. Deve permitir escrever código em diferentes níveis de detalhe. O código não precisa ser uma bagunça não estruturada de instruções de baixo nível.
Frank Puffer

@FrankPuffer, um diagrama vale 100.000 LoC.
RubberDuck

1
@RubberDuck Ocorre-me que a capacidade (ou a falta dela) de gerar vários diagramas úteis a partir do código pode ser uma medida da expressividade de um idioma. Não existe um diagrama que você possa desenhar que não possa ser expresso em algum tipo de linguagem. A questão é se esse idioma pode transmitir as mesmas informações de uma maneira que possa ser facilmente escrita ou lida.
JimmyJames

1
@RubberDuck: Os diagramas fazem sentido em alguns casos, por exemplo, para explicar a arquitetura geral. Mas não acho que devam ser o padrão. Definitivamente, existem diagramas bons e úteis, mas infelizmente a maioria das UML que eu vi é mais confusa do que útil. E o pior é que muitas vezes difere da implementação real.
Frank Puffer

Gosto que você mencione a geração de diagramas @JimmyJames. Eu prefiro geração do que criação manual. Você tem um argumento muito válido, mas me pergunto se é uma função da expressividade ou do ferramental.
11337 RubberDuck

1

No caso ideal, não deve haver descrição do design do software, exceto o próprio código.

Isso está mais distante do que você sugere. Até coisas como tipos dependentes (que, na minha opinião, são bastante promissoras em teoria) estão dentro de vários anos.

A verificação formal é bastante difícil e, por esse motivo, o único local em que a verificação formal é comumente usada são as bibliotecas de criptografia.

Testes unitários

Se o teste de propriedade não atingiu o mainstream, acho que isso não será prático por muito tempo.

Além disso, escrever bons testes (que não precisam ser editados com todos os refatores, mas ainda assim detectam erros suficientes) é bastante difícil.

Para garantir que o código seja consistente com seus documentos, você deve verificar novamente e novamente. Se houver alterações frequentes, é difícil manter o código e os documentos sincronizados.

Provavelmente é mais fácil usar uma ferramenta de teste de documentação no momento.

Há uma pré-condição para fazer isso funcionar: O código deve ser fácil o suficiente para ler e entender.

Infelizmente, é difícil projetar linguagens não apenas extremamente expressivas, mas também eminentemente legíveis. Idiomas como o Go priorizam a legibilidade e prejudicam o pensamento de nível superior.

Finalmente, na minha experiência, melhores linguagens e ferramentas não levam a software com menos bugs, mas a projetos maiores. Não há realmente nenhuma maneira plausível de pandocter sido escrita em 1970.

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.