Como as equipes profissionais de desenvolvimento de software lidam com a complexidade do design em projetos não triviais?


9

Primeiro, percebo que essa pergunta pode ser um tanto longa e vaga e peço desculpas por isso. Provavelmente, este é um problema básico com um nome abreviado para qualquer pessoa que "entenda", mas, como me falto a esse respeito, tenha paciência comigo ao descrever o problema.

Faço programação dessa maneira ou de outra desde os 11 anos de idade. Isso significa que eu tenho me ensinado tudo desde o início. Eu recebi uma educação técnica, mas não estritamente em Ciência da Computação (me formei em Engenharia Fotônica). Tivemos cursos de programação, é claro, mas isso era basicamente coisas básicas para mim e eu não aprendi muitas coisas novas. Eu continuei me educando ao longo do caminho pela alegria e sempre soube que seguiria uma carreira em programação, mas todos os meus projetos eram bem pequenos na época. Não tive problemas para mantê-los em minha mente e mantê-los.

Agora, eu me encontro na liderança de uma equipe, mas não no ambiente corporativo - trabalho para a universidade desenvolvendo software científico (em C ++) para aplicativos de engenharia. De repente, o projeto está crescendo (relativamente) e eu tenho problemas para entender o assunto na maioria das vezes. Estou perdendo muito tempo e esforço em duas coisas principalmente:

  1. Quando tenho que retornar a uma seção do código em que não trabalho há algum tempo, tenho dificuldade em lembrar como funcionou. Passo muito tempo revisando os arquivos de cabeçalho das classes relevantes e lendo os comentários que eu coloquei ao longo dos arquivos de origem. Eu gostaria que houvesse alguma forma de "esquema" que eu pudesse vislumbrar e recuperar a imagem mais facilmente;
  2. Quando eu introduzo mudanças, às vezes percebo, no meio do caminho, que o que estou tentando fazer irá quebrar as coisas em outro lugar (ou pior, isso só aparece em tempo de execução como uma surpresa). Eu reverto e começo a fazê-lo de maneira diferente, apenas para descobrir que negligenciei a influência em algum outro componente. Eu gostaria que houvesse algum "diagrama de arquitetura" onde eu pudesse ver como as coisas são feitas, como o que estou tentando fazer influenciará outros componentes e uma maneira de planejar detalhadamente antes de começar a implementar as alterações.

A maioria das pessoas com quem trabalho tem histórias semelhantes às minhas - orientação técnica forte e, às vezes, ótimas habilidades, mas sem meios de organizar seu trabalho. No entanto, seus projetos geralmente são muito menores que os meus, então eles lidam de alguma forma. De qualquer forma, o que isso significa para mim é que estou sozinho e não tenho ninguém para aprender as boas práticas.

Fiz um curso de pós-graduação em gerenciamento de TI e, apesar de bastante satisfatório, é voltado principalmente para não programadores, ensinando sobre metodologias de gerenciamento de projetos, estimativas de orçamento / cronograma, arquitetura corporativa etc. - não sobre design e planejamento de software. Tudo bem, estou tentando aprender essas coisas também. Obviamente, foram introduzidas algumas ferramentas (como UML) e os tipos de processos de desenvolvimento de software (em cascata, iterativo, ágil ...), mas obviamente não detalhados, e é difícil decidir o que escolher e usar ( e até que ponto).

Eu tenho lido muitas perguntas e respostas sobre design de software no SO - há muitas sobre como fazer isso usando essa ou aquela ferramenta ou metodologia específica, e se eu estivesse convencido de que a documentação UML resolveria meus problemas - eu pegaria e comece a usá-lo. Mas algumas pessoas juram, outras dizem que é inútil. Estou procurando uma resposta em um nível mais alto de abstração - existem maneiras de resolver os dois problemas que estou tendo e como você o faz pessoalmente? O que devo aprender para poder fazer isso, possivelmente sem estar vinculado a uma ferramenta específica? Eles vêm e saem de moda de tempos em tempos, e espero que sua aplicabilidade varie de acordo com o tipo de projeto.

Muito obrigado pela leitura, não consegui dizer o que quero dizer mais brevemente (falta de experiência e vocabulário em design de software).


2
Eu acho que a resposta profissional mais comum para as dificuldades das quais você está falando é: "Foda-se", seguida de culpar o gerenciamento, o produto ou algum outro SOB aleatório.
Edward Strange

Respostas:


9

Quando tenho que retornar a uma seção do código em que não trabalho há algum tempo, tenho dificuldade em lembrar como funcionou. Passo muito tempo revisando os arquivos de cabeçalho das classes relevantes e lendo os comentários que eu coloquei ao longo dos arquivos de origem.

Imagine como o pobre rapaz que vem depois de você se sentirá - ele nem sequer tem o benefício de saber como o seu código funciona. Em vez de tentar decifrar seu código, você deve revisar a documentação que escreveu para o módulo em questão. Essa documentação deve oferecer uma visão razoavelmente precisa do que o módulo faz por que. Não é "o módulo começa inicializando três matrizes usando um loop for triplo ...", mas: "esse módulo recupera os dados coletados pelo sensor principal do Fabulotron, reorganiza-os no formato padrão Neopolitan (chocolate, baunilha, morango), e entrega ao módulo de análise ".

Em um mundo perfeito, você teria um documento de design que define os vários módulos do sistema e descreve suas respectivas responsabilidades, e cada um dos seus módulos pode apenas consultar esse documento para explicar o que eles fazem: "Este módulo fornece o Serviço de coleta de dados Fabulotron, conforme detalhado na seção 4.8 do documento de design: http://fabulotron.org/design/section4-8.html . " Se você não tiver algo parecido, comece a escrever uma visão geral de cada módulo enquanto trabalha nele. Você não precisa escrever um livro - alguns parágrafos costumam ser suficientes para orientá-lo.

Quando eu introduzo mudanças, às vezes percebo, no meio do caminho, que o que estou tentando fazer irá quebrar as coisas em outro lugar (ou pior, isso só aparece em tempo de execução como uma surpresa). Eu reverto e começo a fazê-lo de maneira diferente, apenas para descobrir que negligenciei a influência em algum outro componente.

Isso pode ser uma indicação de que seus módulos estão muito interconectados. Quanto mais independente você puder criar seus módulos / classes / unidades, menor a probabilidade de você encontrar esse tipo de problema. Tente tornar as interfaces entre os módulos o mais explícitas possível e tente limitá-las exatamente ao que precisa estar lá. Uma interface é um contrato - se você sabe que algum módulo cumpre suas obrigações, conforme especificado na interface, não precisa saber mais nada sobre ele. Isso evita que as alterações no módulo em que você está trabalhando afetem outros módulos.

Eu gostaria que houvesse algum "diagrama de arquitetura" onde eu pudesse ver como as coisas são feitas

O uso de peças padrão pode ajudar nesse sentido. O C ++ fornece partes padrão na forma da Biblioteca de modelos padrão, e o uso dessas partes, quando apropriado, permite trabalhar em um nível mais alto de abstração. Se você escreveu seu próprio código para gerenciar estruturas de dados como listas, você e os que seguem a seguir terão que ler constantemente a fonte para descobrir o que está acontecendo. Se você usar peças padrão fornecidas pelo STL, qualquer programador C ++ poderá rapidamente dizer o que seu código está fazendo sem se aprofundar nas rotinas de gerenciamento de dados.

Outro tipo de peça padrão vem dos padrões de design. Eles são conceitos padrão que podem ser usados ​​como uma abreviação para explicar como funciona o relacionamento entre dois objetos.


Obrigado pela resposta. É claro que eu uso o STL há muitos anos, mas a sequência de etapas que meu programa executa para realizar algum cálculo artificial às vezes é difícil de imaginar na íntegra, mesmo com seu uso. O mesmo vale para os módulos. Eu não quis dizer que mudar um quebra o outro, mas sim que mudar algo em algum lugar causa uma falha, por exemplo, quando um usuário faz algo fora do padrão na GUI, em que uma sequência complicada é ainda mais complicada pela ordem imprevisível de etapas que eles tomam para concluí-lo.
Neuviemeporte

5

Sou um desenvolvedor profissional apenas por um curto período de tempo e lutei bastante com como fazer isso quando comecei. Eu fui autodidata, mesmo através da Universidade. Felizmente para mim, as pessoas com quem trabalhei têm muita experiência e foram capazes de me educar sobre as maneiras de gerenciar e trabalhar em grandes projetos.

Uma das primeiras coisas que me fizeram foi sentar e ler um código limpo . Que é um livro fantástico que me ajudou a entender como escrever código que eu conseguia entender quando voltei a ele ou que outra pessoa podia entender.

A segunda coisa foi escrever testes de boa qualidade, Unidade, Integração, Aceitação. Se seu código for bem testado, você saberá rapidamente quando quebrou alguma coisa e poderá diagnosticar rapidamente o problema. Existem muitos recursos de teste disponíveis na Internet, e não tenho certeza de quais são os melhores para sugerir a você.

Meus pontos principais são Teste e Código Limpo.


Obrigado pela sugestão, não deixe de conferir o livro (mesmo que o "ágil" na legenda pareça indicar que é mais relevante para essa metodologia). Eu tenho testes e depois de ler muitos livros sobre estilo de codificação (por exemplo, Programador Pragmático), sempre me esforço para criar interfaces limpas e bem separadas, mas para um teste automatizado é difícil para a parte da GUI do meu aplicativo e ainda não tenho um maneira de fazer um bom design geral em uma escala maior, que vai além da implementação de práticas "limpas" em pedaços de código relativamente pequenos.
Neuviemeporte

2

Aqui estão algumas idéias de alto nível para organizar grandes sistemas de software. A maior parte da minha experiência é em sistemas de Internet, mas acho que essas idéias se aplicam ao software de engenharia.

  • Separe a funcionalidade em blocos modulares relativamente isolados. Por exemplo, você pode ter um módulo para cada família de cálculos fornecidos pelo seu software.
  • Aplique o padrão de design MVC para a interface com o usuário, se houver um. Mantenha a interface e o modelo separados com limites bem definidos.
  • Considere usar camadas para agrupar módulos. Em um aplicativo que usa camadas de abstração, cada camada depende apenas da camada abaixo dela.
  • Ao escrever a documentação, suponha que você esqueça todos os detalhes da implementação. Você escreverá muita documentação sob essa suposição - talvez até metade do seu código seja comentários, mas você ficará muito menos confuso depois.
  • Testes automatizados de unidade, integração e aceitação são ótimos em alguns espaços, mas os desenvolvedores de C ++ parecem ter sentimentos contraditórios sobre eles.
  • Desenhe fortemente nos padrões de design . Além de geralmente serem boas idéias, os padrões de design fornecem um vocabulário comum em engenharia de software. Chamar uma classe de WidgetFactory é uma maneira concisa de comunicar que é uma classe que existe para criar widgets.

Faz muito tempo desde que trabalhei com software de engenharia, portanto, sua milhagem pode variar com base nessas sugestões. Boa sorte!


1

A resposta é engenharia de software.

Ou seja, para grandes projetos, você segue uma sequência definida de coleta de requisitos, definição de processo, especificação etc. muito antes de qualquer codificação real ser concluída.

Existem várias metodologias usadas, dependendo do ambiente e da cultura. Os negócios do tipo corporativo tendem a seguir o " Rational Unified Process " ou similar, e as startups de tecnologia geralmente costumam variar no Agile , departamentos governamentais e alguma metodologia sobrecarregada do Waterfall .

Em todos os casos, o processo ajuda a definir exatamente o que você está fazendo e, no final do projeto, permite provar que você o fez.


Supondo que os requisitos não mudem (uma suposição irrealista em muitos casos, eu sei), é realmente possível especificar tudo antes da codificação e criar um software de trabalho a partir da especificação sem grandes alterações ao longo do caminho? Eu simplesmente não consigo imaginar. Eu tenho que começar a codificar para entrar na sensação. ajustar um pouco, ajustar um pouco mais etc ...
neuviemeporte

Isso pode funcionar para pequenos projetos, mas para grandes projetos você precisa entender os requisitos primeiro. Também uma parte vital do RUP é modelar o sistema proposto com diagramas UML e Sequence. É muito mais fácil ajustar e refatorar um modelo do que o código real.
James Anderson

@neuviemeporte: Depende. Às vezes, os requisitos mudam ou novos requisitos são descobertos durante o desenvolvimento. Às vezes, os requisitos são bem claros desde o início e apenas alguns detalhes menores são alterados durante o desenvolvimento, mas a arquitetura geral permanece a mesma.
Giorgio

1

Eu recomendo que você ponha as mãos no Enterprise Architect , que embora não seja gratuito, oferece preços acadêmicos. É uma excelente ferramenta para esquematizar projetos em nível macro e micro. Ele também pode fazer a engenharia reversa de seus arquivos de origem em diagramas de classes, o que provavelmente seria um bom começo para você documentar e reorganizar o modo como seu aplicativo funciona.

Eu também recomendaria as recomendações de @ Klee. Não se deixe levar pelas supostas ferramentas "ágeis", pois elas são realmente apenas itens de práticas recomendadas que também são úteis (se não obrigatórios) se você estiver seguindo um processo ágil. Mas a integração contínua (por exemplo) é valiosa, independentemente da sua metodologia. Além disso, os testes de unidade (cppUnit?) São seus amigos. Os testes de unidade devem ser muito viáveis ​​se você testar as classes lógicas chamadas pela sua interface do usuário, em vez de testar diretamente a interface do usuário. Também existem ferramentas que podem ajudá-lo a automatizar o teste da interface do usuário, mas eu tentaria reunir as coisas de back-end primeiro.

Boa sorte!


1

Eu acredito que seu problema tem três dimensões

  1. Orientado a programadores
  2. Orientado ao programa
  3. Manutenção de Programas - Orientada

Em relação ao primeiro problema, você pode ter programadores que não entendem o conceito do que o programa faz (isso geralmente acontece nas configurações corporativas). Mas, seguindo a sua pergunta e o domínio em que você se encontra, parece que você e sua equipe estão no controle do que o programa faz, mas simplesmente não podem traduzi-lo em um programa de trabalho em um curto espaço de tempo (para citar um exemplo, ouvi falar de pessoas tendo pós-doutorado em Física com problemas para entender os ponteiros da programação e tenho certeza de que a Física é muito mais difícil que o C ++). Se for esse o caso, seu problema é principalmente centrado no programa (você deve se sentir com sorte o suficiente para que as pessoas ao seu redor possam entender o que seu programa está fazendo e apreciá-lo).

No caso de problemas centrados no programa, uma das minhas sugestões ultrajantes seria passar para um nível de abstração mais alto que o C ++, como aprender uma nova linguagem como Python ou Haskell (o Python é muito fácil de aprender e, se você tiver bons matemáticos, Haskell é ótimo). Mover para um nível mais alto de abstração manteria o tamanho do seu código baixo, fácil de entender e manter a longo prazo e efetuar alterações rapidamente. Portanto, você pode ter 10 linhas de código no lugar das 50 linhas de código originais. Além disso, ter alguém com experiência em programação de computadores certamente ajudaria. Por estar em uma universidade, você também pode envolver alguns alunos na GUI e nas interfaces para poder se concentrar mais na funcionalidade. Também recomendo o livro Design de software C ++ em larga escala de John Lakos(É um livro bastante grande, você pode se tornar um programador experiente em Python no tempo que levou para ler o livro)

Se você classificar as 2 primeiras dimensões do seu problema, a terceira será resolvida automaticamente. Como acredito que você esteja trabalhando em um único projeto grande, qualquer software decente de gerenciamento de projetos que você o obtenha. Planejamento antecipado é necessário. Se você começar a codificar imediatamente, poderá se envolver demais no programa para esquecer o quadro geral. Manter as coisas em mente não funcionaria para um grande projeto. Coloque tudo no papel (ou no computador). Use um wiki para compartilhar informações. Em relação às metodologias, prefiro a metodologia ágil (simplesmente, ágil é um nome elegante para o desenvolvimento incremental de software). Sugiro também a contratação de alguém com experiência nessa área para que ele cuide deles para que você possa se concentrar em seu programa principal. O ponto principal aqui é que todas as metodologias de gerenciamento de projetos são apenas uma maneira de garantir o sucesso do programa; para que você possa escolher qualquer pessoa que combina com você e sua equipe, em vez de selecionar algo que alguém recomenda melhor. Além disso, o software a seguir também pode ajudá-lo

  • Free Mind - software de mapeamento mental
  • Trac - Programa de erros de software rápido e fácil e um wiki
  • MoinMoin - Wiki rápido para permitir o compartilhamento de conhecimentos sobre o programa

Embora as dicas acima levem alguma curva de aprendizado, vale a pena a longo prazo. E, finalmente, a programação é mais fácil do que a Engenharia Fotônica (embora não a Programação C ++)


0

Como sua pergunta, qualquer resposta que seja útil para você será muito longa e vaga - mas a resposta curta é "Engenharia de software"

Sugiro que você reserve algum tempo livre, tanto quanto possível, se você for sério sobre uma carreira de desenvolvimento de software, e comece visitando o site de Steve McConnells . A programação é fácil e pode ser ministrada em um semestre, a Engenharia de Software é uma ordem de magnitude mais complexa e precisa de muito mais tempo para aprender.

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.