Espero que isso não seja uma pergunta muito geral; Eu realmente poderia usar alguns conselhos experientes.
Sou recém-contratado como o único "Engenheiro de SW" em uma pequena loja de cientistas que passaram os últimos 10 a 20 anos construindo uma vasta base de códigos. (Foi escrito em uma linguagem praticamente obsoleta: G2 - pense em Pascal com gráficos). O programa em si é um modelo físico de uma planta de processamento químico complexo; a equipe que o escreveu possui um conhecimento de domínio incrivelmente profundo, mas pouco ou nenhum treinamento formal em fundamentos de programação. Recentemente, eles aprenderam algumas lições difíceis sobre as consequências do gerenciamento de configurações inexistentes. Seus esforços de manutenção também são bastante prejudicados pelo grande acúmulo de "lodo" não documentado no próprio código. Vou poupar-lhe a "política" da situação ( sempre há política!), mas basta dizer que não há um consenso de opinião sobre o que é necessário para o caminho a seguir.
Eles me pediram para começar a apresentar à equipe alguns dos princípios do desenvolvimento moderno de software. Eles querem que eu apresente algumas das práticas e estratégias padrão do setor em relação às convenções de codificação, gerenciamento do ciclo de vida, padrões de design de alto nível e controle de origem. Francamente, é uma tarefa bastante assustadora e não sei por onde começar.
Inicialmente, estou inclinado a ensiná-los em alguns dos conceitos centrais de The Pragmatic Programmer , ou Fowler's Refactoring ("Code Smells", etc). Também espero introduzir várias metodologias ágeis. Mas, finalmente, para ser eficaz, acho que vou precisar aprimorar os 5-7 princípios básicos; em outras palavras, quais são os princípios ou práticas mais importantes que eles podem começar a implementar realisticamente e que darão a eles o maior retorno possível.
Portanto, essa é a minha pergunta: o que você incluiria em sua lista das estratégias mais eficazes para ajudar a endireitar o espaguete (e evitá-lo no futuro)?
Respostas:
Prefácio
Esta é realmente uma tarefa assustadora, e há muito o que abordar. Portanto, estou humildemente sugerindo isso como um guia abrangente para sua equipe, com dicas para ferramentas e materiais educacionais apropriados.
Lembre-se: são diretrizes e, como tal, devem ser adotadas, adaptadas ou descartadas com base nas circunstâncias.
Cuidado: despejar tudo isso em uma equipe ao mesmo tempo provavelmente falhará. Você deve tentar escolher elementos que dariam o melhor retorno possível e apresentá-los lentamente, um de cada vez.
Nota: nem tudo isso se aplica diretamente a sistemas de programação visual como o G2. Para detalhes mais específicos sobre como lidar com eles, consulte a seção Adendo no final.
Resumo Executivo para o Impaciente
Agora, para a versão longa ... Cuidado, preparem-se!
A rigidez é (geralmente) boa
Esta é uma opinião controversa, pois a rigidez é frequentemente vista como uma força que trabalha contra você. É verdade para algumas fases de alguns projetos. Mas uma vez que você o vê como um suporte estrutural, uma estrutura que elimina as suposições, reduz bastante a quantidade de tempo e esforço desperdiçados. Faça com que funcione para você, não contra você.
Rigidez = Processo / Procedimento .
O desenvolvimento de software precisa de bons processos e procedimentos pelas mesmas razões pelas quais as fábricas ou fábricas de produtos químicos possuem manuais, procedimentos, exercícios e diretrizes de emergência: prevenção de maus resultados, aumento da previsibilidade, maximização da produtividade ...
A rigidez vem com moderação!
Rigidez da estrutura do projeto
Se cada projeto vem com sua própria estrutura, você (e os novatos) estão perdidos e precisam começar do zero toda vez que os abrir. Você não quer isso em uma loja de software profissional e também não quer isso em um laboratório.
Rigidez dos sistemas de construção
Se cada projeto parecer diferente, há uma boa chance de que eles também sejam construídos de maneira diferente . Uma construção não deve exigir muita pesquisa ou muita adivinhação. Você quer ser capaz de fazer a coisa canônica e não precisa se preocupar com detalhes:
configure; make install
,ant
,mvn install
, etc ...A reutilização do mesmo sistema de compilação e a sua evolução ao longo do tempo também garantem um nível consistente de qualidade.
Você precisa
README
apontar rapidamente as especificidades do projeto e orientar normalmente o usuário / desenvolvedor / pesquisador, se houver.Isso também facilita muito outras partes da sua infraestrutura de construção, a saber:
Portanto, mantenha sua compilação (como seus projetos) atualizada, mas torne-a mais rígida ao longo do tempo e mais eficiente na denúncia de violações e práticas inadequadas.
Não reinvente a roda e reutilize o que você já fez.
Leitura recomendada:
Rigidez na escolha das linguagens de programação
Você não pode esperar, especialmente em um ambiente de pesquisa, que todas as equipes (e menos ainda todos os desenvolvedores) usem a mesma pilha de linguagem e tecnologia. No entanto, você pode identificar um conjunto de ferramentas "oficialmente suportadas" e incentivar o uso delas. O resto, sem uma boa justificativa, não deve ser permitido (além da prototipagem).
Mantenha sua pilha de tecnologia simples e a manutenção e a amplitude das habilidades necessárias ao mínimo: um núcleo forte.
Rigidez das convenções e diretrizes de codificação
As convenções e diretrizes de codificação são o que permitem desenvolver uma identidade em equipe e uma linguagem compartilhada . Você não deseja errar no terra incognita toda vez que abrir um arquivo de origem.
Regras absurdas que tornam a vida mais difícil ou proíbem ações explicitamente na medida em que os commits são recusados com base em violações simples e simples são um fardo. Contudo:
um conjunto de regras básicas bem pensado retira grande parte dos gemidos e pensamentos: ninguém deve quebrar sob nenhuma circunstância;
e um conjunto de regras recomendadas fornece orientações adicionais.
Alguns idiomas ainda impõem isso por design:
A estrutura de blocos do Python por recuo é outra ideia nesse sentido.
Vá, com sua
gofmt
ferramenta, que elimina completamente qualquer debate e esforço ( e ego !! ) inerentes ao estilo: corragofmt
antes de se comprometer.Verifique se a podridão do código não pode passar despercebida. Convenções de código , integração contínua e inspeção contínua , programação de pares e revisões de código são o seu arsenal contra esse demônio.
Além disso, como você verá abaixo, o código é a documentação , e isso é uma outra área onde convenções incentivar a legibilidade e clareza.
Rigidez da documentação
A documentação anda de mãos dadas com o código. O próprio código é documentação. Mas deve haver instruções claras sobre como construir, usar e manter as coisas.
Usar um único ponto de controle para documentação (como um WikiWiki ou DMS) é uma coisa boa. Crie espaços para projetos, espaços para brincadeiras e experiências mais aleatórias. Todos os espaços reutilizam regras e convenções comuns. Tente fazer parte do espírito de equipe.
A maioria dos conselhos aplicáveis ao código e ferramentas também se aplica à documentação.
Rigidez nos comentários do código
Comentários de código, como mencionado acima, também são documentação. Os desenvolvedores gostam de expressar seus sentimentos sobre o código (principalmente orgulho e frustração, se você me perguntar). Portanto, não é incomum que eles os expressem em termos não duvidosos nos comentários (ou mesmo no código), quando um pedaço de texto mais formal poderia ter transmitido o mesmo significado com menos palavrões ou drama. Não há problema em deixar passar alguns por motivos divertidos e históricos: também faz parte do desenvolvimento de uma cultura de equipe . Mas é muito importante que todos saibam o que é aceitável e o que não é, e esse ruído de comentário é exatamente isso: ruído .
Rigidez nos logs de consolidação
Os registros de confirmação não são uma "etapa" irritante e inútil do ciclo de vida do seu SCM: você não o pula para chegar em casa a tempo ou prosseguir com a próxima tarefa, ou para conversar com os amigos que foram almoçar. Eles são importantes e, como (a maioria) bom vinho, quanto mais o tempo passa, mais valiosos eles se tornam. Então faça-os direito. Fico espantado quando vejo colegas de trabalho escrevendo uma linha para commits gigantes ou para hacks não óbvios.
As confirmações são feitas por um motivo, e esse motivo nem sempre é expresso claramente pelo seu código e pela única linha do log de confirmação que você inseriu. Há mais do que isso.
Cada linha de código tem uma história e uma história . Os diffs podem contar sua história, mas você deve escrever sua história.
Não é minha escolha de SCM e também pode não ser a melhor para o seu laboratório; mas
Git
faz isso direito e tenta forçá-lo a escrever bons logs mais do que a maioria dos outros sistemas SCMs, usandoshort logs
elong logs
. Vincule o ID da tarefa (sim, você precisa de um) e deixe um resumo genérico parashortlog
e expanda no log longo: escreva a história do conjunto de alterações .É um log: está aqui para acompanhar e registrar as atualizações.
Projetos, documentação e código estão vivos
Mantenha-os sincronizados, caso contrário eles não formarão mais essa entidade simbiótica. Faz maravilhas quando você tem:
O código e a documentação precisam ser coesos .
Rigidez nos testes
Obviamente, eles precisam:
Eles também são documentação e ajudam a delinear o contrato do seu código. Especialmente se você usar TDD . Mesmo se não, você precisa deles para sua paz de espírito. Eles são sua rede de segurança quando você incorpora um novo código (manutenção ou recurso) e sua torre de vigia para se proteger contra a podridão do código e falhas ambientais.
Obviamente, você deve ir além e fazer testes de integração e testes de regressão para cada bug reproduzível corrigido.
Rigidez no uso das ferramentas
Não há problema em um desenvolvedor / cientista ocasional querer experimentar algum novo verificador estático na fonte, gerar um gráfico ou modelo usando outro ou implementar um novo módulo usando uma DSL. Mas é melhor se houver um conjunto canônico de ferramentas que todos os membros da equipe devem conhecer e usar.
Além disso, permita que os membros usem o que querem, desde que sejam TODOS:
Se não for esse o caso, imponha que eles retornem aos padrões.
Rigidez versus Versatilidade, Adaptabilidade, Prototipagem e Emergências
Flexibilidade pode ser boa. Permitir que alguém ocasionalmente use um hack, uma abordagem rápida e suja ou uma ferramenta favorita para realizar o trabalho é bom. NUNCA deixe que isso se torne um hábito e NUNCA deixe que esse código se torne a base de código real a ser suportada.
Questões de espírito de equipe
Desenvolva um senso de orgulho em sua base de código
Evite Jogos de Culpa
É sobre o código, não sobre os desenvolvedores
Torne os desenvolvedores conscientes da qualidade de seu código, MAS faça com que eles vejam o código como uma entidade independente e não como uma extensão de si mesmos, que não pode ser criticada.
É um paradoxo: você precisa incentivar a programação sem ego para um ambiente de trabalho saudável, mas confiar no ego para fins motivacionais.
De cientista a programador
Pessoas que não valorizam e se orgulham do código não produzem um bom código. Para que essa propriedade surja, eles precisam descobrir o quão valioso e divertido pode ser. Simples profissionalismo e desejo de fazer o bem não são suficientes: é preciso paixão. Então você precisa transformar seus cientistas em programadores (no sentido amplo).
Alguém argumentou nos comentários que, após 10 a 20 anos em um projeto e seu código, qualquer um se sentiria apegado. Talvez eu esteja errado, mas presumo que eles tenham orgulho dos resultados do código e do trabalho e seu legado, não do código em si ou do ato de escrevê-lo.
Por experiência, a maioria dos pesquisadores considera a codificação uma necessidade ou, na melhor das hipóteses, uma distração divertida. Eles só querem que funcione. Os que já são bastante versados e têm interesse em programação são muito mais fáceis de persuadir a adotar as melhores práticas e a alternar tecnologias. Você precisa levá-los até a metade do caminho.
Manutenção de código faz parte do trabalho de pesquisa
Ninguém lê documentos de pesquisa ruins. É por isso que eles são revisados por pares, revisados, refinados, reescritos e aprovados repetidamente até que estejam prontos para publicação. O mesmo se aplica a uma tese e a uma base de código!
Deixe claro que a constante refatoração e atualização de uma base de código evita a podridão do código e reduz a dívida técnica, além de facilitar a reutilização e adaptação futura do trabalho para outros projetos.
Por que tudo isso??!
Por que nos preocupamos com tudo isso? Para a qualidade do código . Ou é um código de qualidade ...?
Essas diretrizes visam direcionar sua equipe para esse objetivo. Alguns aspectos fazem isso simplesmente mostrando-lhes o caminho e deixando-os fazer (o que é muito melhor) e outros os pegam pela mão (mas é assim que você educa as pessoas e desenvolve hábitos).
Como você sabe quando a meta está ao seu alcance?
Qualidade é Mensurável
Nem sempre é quantitativa, mas é mensurável . Como mencionado, você precisa desenvolver um senso de orgulho em sua equipe, e mostrar progresso e bons resultados é essencial. Avalie a qualidade do código regularmente e mostre o progresso entre os intervalos e como isso é importante. Faça retrospectivas para refletir sobre o que foi feito e como isso tornou as coisas melhores ou piores.
Existem ótimas ferramentas para inspeção contínua . O sonar é popular no mundo Java, mas pode se adaptar a qualquer tecnologia; E há muitos outros. Mantenha seu código sob o microscópio e procure esses insetos e micróbios irritantes e irritantes.
Mas e se o meu código já for uma porcaria?
Todas as opções acima são divertidas e fofas como uma viagem a Never Land, mas não é tão fácil de fazer quando você já tem um monte de porcaria (cheia de vapor e fedorento) e uma equipe relutante em mudar.
Aqui está o segredo: você precisa começar em algum lugar .
Nota: Novamente, a rigidez precisa ser abalada para abrir espaço para coisas novas e melhores. Na minha anedota, nosso departamento de TI está parcialmente certo ao tentar impor algumas coisas sobre nós e errado para outras. Ou talvez eles estivessem certos . As coisas mudam. Prove que são as melhores maneiras de aumentar sua produtividade. Testes e protótipos estão aqui para isso.
O ciclo de refatoração de código de espaguete incremental super secreto para uma qualidade incrível
Depois de ter algumas ferramentas de qualidade no seu cinto de ferramentas:
Analise seu código com verificadores de qualidade de código.
Linters, analisadores estáticos ou o que você tem.
Identifique seus pontos críticos e frutas baixas .
As violações têm níveis de severidade, e classes grandes com um grande número de de alta severidade são uma grande bandeira vermelha: assim, elas aparecem como "pontos de acesso" nos tipos de visualizações do radiador / mapa de calor.
Corrija os pontos de acesso primeiro.
Maximiza seu impacto em um curto espaço de tempo, pois eles têm o maior valor comercial. Idealmente, as violações críticas devem ser tratadas assim que aparecerem, pois são possíveis vulnerabilidades de segurança ou causas de travamento e apresentam um alto risco de induzir uma responsabilidade (e, no seu caso, mau desempenho para o laboratório).
Limpe as violações de baixo nível com varreduras automatizadas de base de código .
Ele melhora a relação sinal / ruído para que você possa ver violações significativas no seu radar à medida que elas aparecem. Geralmente, há um grande exército de pequenas violações no início, se elas nunca foram resolvidas e sua base de código foi deixada solta na natureza. Eles não apresentam um "risco" real, mas prejudicam a legibilidade e a manutenção do código. Corrija-os conforme você os encontra durante o trabalho em uma tarefa ou em grandes tarefas de limpeza com varreduras de código automatizadas, se possível. Tenha cuidado com grandes varreduras automáticas, se você não tiver um bom conjunto de testes e sistema de integração. Certifique-se de concordar com os colegas de trabalho o momento certo para executá-los para minimizar o aborrecimento.
Repita até ficar satisfeito.
O que, idealmente, você nunca deveria ser, se este ainda for um produto ativo: continuará evoluindo.
Dicas rápidas para uma boa manutenção da casa
Quando no modo de hotfix , com base em uma solicitação de suporte ao cliente:
Mas para todos os outros casos , se você abrir um arquivo, tenha o dever de:
Apenas não se desvie para passar uma semana de um arquivo para outro e acabar com um maciço conjunto de milhares de correções, abrangendo vários recursos e módulos - isso dificulta o rastreamento futuro. Um problema no código = um ticket no seu rastreador. Às vezes, um conjunto de alterações pode afetar vários tickets; mas se isso acontecer com muita frequência, provavelmente você está fazendo algo errado.
Adendo: Gerenciando ambientes de programação visual
Os jardins murados dos sistemas de programação sob medida
Vários sistemas de programação, como o G2 do OP, são bestas diferentes ...
Sem código "fonte"
Frequentemente, eles não dão acesso a uma representação textual do seu "código" fonte: ele pode ser armazenado em um formato binário proprietário ou talvez ele armazene coisas no formato de texto, mas as oculte de você. Os sistemas de programação gráfica sob medida não são incomuns nos laboratórios de pesquisa, pois simplificam a automação de fluxos de trabalho repetitivos de processamento de dados.
Sem ferramentas
Além de seus próprios, é isso. Você geralmente é limitado pelo ambiente de programação, pelo próprio depurador, pelo intérprete, pelas ferramentas e formatos de documentação. São jardins murados , exceto se, eventualmente, capturarem o interesse de alguém motivado o suficiente para fazer engenharia reversa de seus formatos e criar ferramentas externas - se a licença permitir.
Falta de documentação
Muitas vezes, esses são sistemas de programação de nicho, usados em ambientes bastante fechados. As pessoas que os usam frequentemente assinam NDAs e nunca falam sobre o que fazem. As comunidades de programação para eles são raras. Portanto, os recursos são escassos. Você está preso à sua referência oficial, e é isso.
A parte irônica (e muitas vezes frustrante) é que todas as coisas que esses sistemas fazem poderiam obviamente ser alcançadas usando linguagens de programação de uso geral e geral, e provavelmente muito mais eficientemente. Mas isso requer um conhecimento mais profundo da programação, enquanto você não pode esperar que seu biólogo, químico ou físico (para citar alguns) saiba o suficiente sobre programação e muito menos tenha tempo (e desejo) para implementar (e manter) sistemas complexos, que podem ou não durar muito. Pela mesma razão que usamos DSLs, temos esses sistemas de programação sob medida.
Ótimo, estamos condenados! - O que fazemos sobre isso?
Bem, no final, todas as opções acima ainda são válidas. Se você não pode extrair a maior parte da programação deste sistema para usar mais ferramentas e linguagens convencionais, "apenas" precisa adaptá-lo às restrições do seu sistema.
Sobre controle de versão e armazenamento
No final, você quase sempre pode fazer a versão das coisas, mesmo com o ambiente mais restrito e murado. Na maioria das vezes, esses sistemas ainda vêm com suas próprias versões (o que, infelizmente, é bastante básico, e oferece apenas reverter para versões anteriores sem muita visibilidade, mantendo apenas os instantâneos anteriores). Não está exatamente usando conjuntos de alterações diferenciais como o seu SCM de escolha, e provavelmente não é adequado para vários usuários que enviam alterações simultaneamente.
Mas, ainda assim, se eles fornecem essa funcionalidade, talvez a sua solução seja seguir nossas amadas diretrizes padrão da indústria acima e transpor essas para este sistema de programação !!
Se o sistema de armazenamento for um banco de dados, provavelmente expõe as funcionalidades de exportação ou pode ser feito backup no nível do sistema de arquivos. Se estiver usando um formato binário personalizado, talvez você possa simplesmente tentar fazer a versão com um VCS que tenha um bom suporte para dados binários. Você não terá controle refinado, mas pelo menos terá as costas protegidas contra catástrofes e terá um certo grau de conformidade com a recuperação de desastres.
Sobre o teste
Implemente seus testes na própria plataforma e use ferramentas externas e tarefas em segundo plano para configurar backups regulares. Muito provavelmente, você inicia esses testes da mesma maneira que iniciaria os programas desenvolvidos com esse sistema de programação.
Claro, é um trabalho de hacker e definitivamente não está de acordo com o que é comum na programação "normal", mas a idéia é se adaptar ao sistema enquanto tenta manter uma aparência de processo profissional de desenvolvimento de software.
A estrada é longa e íngreme ...
Como sempre em ambientes de nicho e sistemas de programação sob medida, e conforme exposto acima, você lida com formatos estranhos, apenas um conjunto limitado (ou totalmente inexistente) de ferramentas possivelmente desajeitadas e um vazio no lugar de uma comunidade.
A recomendação: tente implementar as diretrizes acima fora do seu sistema de programação sob medida, o máximo possível. Isso garante que você possa confiar em ferramentas "comuns", que possuem suporte adequado e motivação da comunidade.
A solução alternativa: quando essa não for uma opção, tente adaptar essa estrutura global à sua "caixa". A idéia é sobrepor esse modelo de boas práticas padrão do setor sobre o seu sistema de programação e fazer o melhor possível. O conselho ainda se aplica: defina a estrutura e as melhores práticas, incentive a conformidade.
Infelizmente, isso implica que você pode precisar mergulhar e fazer uma tremenda quantidade de trabalho nas pernas. Assim...
Últimas palavras famosas e pedidos humildes:
Ao fazer tudo isso, você irá:
Quem sabe, você poderia estar no início de uma nova comunidade vibrante de Obscure Idioma X . Se não houver, inicie um!
Talvez seja bonito por dentro , mas ninguém tem idéia até agora, então ajude a derrubar essa parede feia e deixe os outros dar uma espiada!
fonte
O primeiro passo seria a introdução de um sistema de controle de versão (SVN, Git, Mercurial, TFS, etc.). Isso é necessário para um projeto que terá re-fatoração.
Editar: referente ao VSC - Todo pacote de controle de origem pode gerenciar binários, embora com algumas limitações. A maioria das ferramentas do mercado tem a capacidade de usar um visualizador e editor de diferença personalizado, use esse recurso. Arquivos de origem binários não são uma desculpa para não usar o controle de versão.
Há um post semelhante sobre como lidar com o código herdado , pode ser uma boa referência a seguir - Conselhos sobre como trabalhar com o código herdado
fonte
Quando tenho que trabalhar com código espaguete, a primeira coisa em que trabalho é a modularização . Encontre lugares onde você pode desenhar linhas e extrair (mais ou menos) partes independentes da base de código. Eles provavelmente não serão muito pequenos, devido a um alto grau de interconectividade e acoplamento, mas algumas linhas de módulos surgirão se você procurá-las.
Depois de ter os módulos, você não fica mais com a difícil tarefa de limpar todo um programa bagunçado. Agora, em vez disso, você tem vários módulos desarrumados independentes menores para limpar. Agora escolha um módulo e repita em uma escala menor. Encontre lugares onde você pode extrair grandes funções em funções menores ou mesmo em classes (se o G2 as suportar).
Tudo isso é muito mais fácil se o idioma tiver um sistema de tipos suficientemente forte, porque você pode fazer com que o compilador faça muito trabalho pesado para você. Você faz uma alteração em algum lugar que (intencionalmente) quebra a compatibilidade e tenta compilar. Os erros de compilação levarão você diretamente aos locais que precisam ser alterados e, quando você parar de obtê-los, encontrará tudo. Em seguida, execute o programa e teste tudo! O teste contínuo é de importância crucial ao refatorar.
fonte
Não sei se isso é uma opção para você, mas começaria a convencê-los a contratar mais desenvolvedores profissionais . Dessa forma, eles poderiam se concentrar em problemas de domínio (tenho certeza que eles têm o suficiente lá).
Acredito que sejam pessoas muito inteligentes, mas tornar-se um bom desenvolvedor exige muito tempo. Eles estão prontos para gastar tanto tempo em uma atividade que não é o principal negócio? IMHO, este não é o caminho para alcançar os melhores resultados.
fonte
Uau. Parece que você tem um grande desafio pela frente! Eu faria algo ao longo das seguintes linhas:
fonte
Eles dizem que o primeiro passo para resolver um problema é admitir que você tem um. Com isso em mente, você pode começar gerando um gráfico de dependência que ilustra o vasto emaranhado que é sua base de código atual. Boa ferramenta para gerar diagrama de dependência? tem alguns anos, mas contém alguns indicadores para ferramentas que podem ajudar a criar esses gráficos. Eu usaria um gráfico grande e feio que mostra o máximo possível para levar o ponto para casa. Fale sobre os problemas que resultam de muitas interdependências e talvez jogue uma linha do Buckaroo Banzai :
A partir daí, apresente um plano para começar a arrumar a bagunça. Divida o código em módulos que sejam o mais independentes possível. Esteja aberto a sugestões de como fazer isso - as pessoas com quem você está conversando conhecem melhor o histórico e a funcionalidade do código. O objetivo, no entanto, é pegar um grande problema e transformá-lo em um número menor de problemas que você pode priorizar e começar a limpar.
Algumas coisas para focar:
Crie interfaces limpas entre os módulos e comece a usá-los. O código antigo pode, necessariamente, continuar a não usar essas novas e agradáveis interfaces por um tempo - esse é o problema que você está começando a resolver. Mas faça com que todos concordem em usar apenas as novas interfaces daqui para frente. Se houver algo que eles precisam que não esteja nas interfaces, corrija as interfaces, não as rodeie.
Procure casos em que a mesma funcionalidade foi repetida. Trabalhe em prol da unificação.
Lembre a todos de tempos em tempos que essas mudanças visam tornar a vida mais fácil, não mais difícil. A transição pode ser dolorosa, mas é para um bom propósito, e quanto mais todos estiverem a bordo, mais rapidamente os benefícios virão.
fonte
Depois de analisar um pouco o Gensym G2 , parece que a maneira de abordar esse problema será altamente dependente de quanto da base de código se parece com isso:
ou isto:
contra isso, cortesia de 99 garrafas de cerveja :
No caso deste último, você está trabalhando com código-fonte que é efetivamente uma quantidade conhecida e algumas das outras respostas oferecem conselhos muito sábios para lidar com isso.
Se a maior parte da base de código for a última, ou mesmo uma parte considerável, você estará enfrentando o problema interessante de ter código que provavelmente não pode ser refatorado por ser extremamente especializado ou, pior ainda, algo que parece pode ser removível, mas, a menos que esteja devidamente documentado, você não sabe se está removendo o código crítico (pense em algo semelhante ao de uma operação de scram ) que não parece ser tão à primeira vista.
Embora, obviamente, sua primeira prioridade seja obter algum tipo de controle de versão on-line, como apontado ElYusubov , e parece que o controle de versão é suportado desde a versão 8.3 . Como o G2 é uma combinação de duas metodologias de linguagem diferentes, você provavelmente achará mais eficaz usar o controle de versão que é fornecido com ele, em vez de tentar encontrar outra coisa e fazê-lo funcionar.
Em seguida, embora alguns provavelmente defendam que você comece a refatorar, sou um forte defensor de garantir que você entenda completamente o sistema com o qual está trabalhando antes de começar a tocar em qualquer código, especialmente ao lidar com códigos e diagramas visuais desenvolvidos por desenvolvedores sem treinamento formal (ou experiência) em metodologias de engenharia de software. O motivo disso é várias vezes, mas o motivo mais óbvio é que você está trabalhando com um aplicativo que potencialmente tem mais de 100 pessoas / ano de trabalho nele e realmente precisa ter certeza de que sabe o que está fazendo e quanto documentação que existe nele. Como você não disse em qual setor o sistema está implantado, com base no que tenho lido sobre o G2, parece seguro presumir que é provavelmente um aplicativo de missão crítica que pode até ter o potencial de também ter implicações na segurança da vida. Assim, entender exatamente o que está fazendo será muito importante. Existe um código que não está documentado e trabalha com os outros membros da equipe para garantir que a documentação seja colocada no lugar para garantir que as pessoas possam determinar o que o código faz.
Em seguida, comece a agrupar os testes de unidade com o máximo de diagramas visuais e de base de código possível. Devo admitir alguma ignorância em relação a como fazer isso com o G2, mas pode quase valer a pena criar sua própria estrutura de teste para colocar isso em prática. Esse também é o momento ideal para começar a apresentar os outros membros da equipe para que eles sejam usados em algumas das práticas de engenharia mais rigorosas envolvidas com a qualidade do código (ou seja, todo código deve ter testes de unidade e documentação).
Depois de realizar testes de unidade em uma quantidade razoável de código, você pode começar a abordar a refatoração de maneira como a sugerida pela haylem ; no entanto, lembre-se de que você está lidando com algo destinado ao desenvolvimento de sistemas especializados e refatorá-lo pode ser uma batalha difícil. Este é realmente um ambiente em que há algo a ser dito para não escrever código extremamente genérico às vezes.
Por fim, preste muita atenção ao que os outros membros da equipe dizem, apenas porque a qualidade do código e do diagrama não é a melhor não necessariamente reflete mal sobre eles. Por fim, é provável que, por enquanto, eles saibam mais sobre o que o aplicativo faz, e é por isso que é mais importante que você se sente e certifique-se de entender o que ele faz antes de fazer mudanças radicais também.
fonte
Geralmente, as reclamações que você ouve de imediato não têm nada a ver com os problemas importantes. Afinal, é totalmente normal ouvir essas reclamações em qualquer projeto de software.
Difícil de entender código? Verifica. Base de código maciça? Verifica.
O verdadeiro problema é que as pessoas saem e, quando a nova pessoa entra na organização, ocorre uma desorientação típica. Além disso, há um problema de expectativas irrealistas e problemas de qualidade de código.
Aqui está o que eu abordaria, a fim de:
fonte
Perguntas como essas são toda a razão pela qual o projeto Software Carpentry existe.
Nos últimos 14 anos, ensinamos aos cientistas e engenheiros habilidades básicas de desenvolvimento de software: controle de versão, testes, como modularizar código e assim por diante. Todos os nossos materiais estão disponíveis gratuitamente sob uma licença Creative Commons, e realizamos algumas dúzias de workshops gratuitos de dois dias por ano para ajudar as pessoas a começar.
Com base nisso, acho que o melhor ponto de partida é provavelmente o excelente (pequeno) livro de Robert Glass, Facts and Fallacies of Software Engineering : sua abordagem baseada em evidências é uma boa maneira de convencer os cientistas de que o que estamos dizendo a eles sobre boas práticas de programação é mais do que apenas opinião.
Quanto às práticas específicas, as duas que as pessoas mais desejam adotar são controle de versão e teste de unidade; uma vez implementados, eles podem enfrentar o tipo de refatoração sistemática que Michael Feathers descreve em Trabalhando efetivamente com o código legado .
Não recomendo The Pragmatic Programmer (muita exortação, difícil para os iniciantes colocarem em prática) e acho que o Código Completo de McConnell é demais para começar (embora seja ótimo dar a eles seis meses ou um ano, depois que eles dominam o básico).
Eu também recomendaria altamente o excelente artigo de Paul Dubois, "Mantendo a correção nos programas científicos" ( Computing in Science & Engineering , maio-junho de 2005), que descreve uma abordagem de "defesa em profundidade" que combina uma dúzia de práticas diferentes de uma maneira lógica e coerente. maneira.
fonte
Acho que, antes de tudo, você precisa resolver sua situação. O que eles querem de você?
Eu acho que o requisito básico aqui é "salvar o conhecimento no sistema", então você precisa ir e escavá-lo!
A primeira tarefa é escrever uma documentação.
Analise a estrutura e os requisitos como se isso fosse uma nova tarefa, mas com a ajuda de um sistema existente. Eles ficarão satisfeitos porque você PERGUNTA, em vez de ENSINAR primeiro - e rapidamente obterá conhecimento suficiente, mas mais organizado, do ponto de vista de um programador: "o que está acontecendo aqui?" Os documentos (estrutura estática do sistema, fluxo de trabalho, componentes, problemas) serão imediatamente valiosos para eles e talvez mostrem informações mais relevantes para eles do que para você (alguns dos caras podem ter "AHA!") E começar a corrigir alguns códigos imediatamente ) ...
Você deve então começar a perguntar para onde eles querem ir?
Se eles estão prontos para se afastar do G2, que sistema eles desejam ver (plataforma, idioma, interface, estrutura geral)? Você pode começar a escrever um invólucro externo ao redor do sistema, se possível, tendo a estrutura de destino, mas mantendo os componentes originais, iniciando lentamente um tipo de estrutura que permite que novos componentes sejam implementados nesse ambiente de destino. Você precisa encontrar os serviços principais (conexões de dados persistentes e "kits de ferramentas": cálculo básico, desenho, ... bibliotecas) e fornecer a eles um ambiente familiar em uma nova plataforma e linguagem, que permita a transição por você ou eles: pegue os códigos antigos um por um, reimplemente (e LIMPE!) no novo ambiente. Quando estiver pronto, eles conhecem o novo idioma; e a camada de serviço (feita principalmente por você, desculpe) está pronta para hospedar os novos componentes.
Se eles não se moverem , você deve aprender G2 e criar a estrutura modular lá, na qual você ou eles devem mover os componentes (com limpeza). Enfim, a linguagem é apenas uma serialização de dados e árvore de algoritmos ...
Ao analisar e escrever os documentos, leia, use e anuncie os padrões do GoF Design! :-)
... meus 2 centavos
fonte
Acabei de fazer uma série de apresentações sobre os princípios SOLID de Robert Martin para meus colegas de trabalho. Não sei até que ponto esses princípios se traduzem no G2, mas como você está procurando de 5 a 7 fundamentos básicos, parece um conjunto bem estabelecido para começar. Se você quiser arredondar para 7, você pode começar com DRY e lançar Fail-Fast.
fonte
O único problema de produção parece um problema de gerenciamento de alterações. Se esse for o caso, e o software o executar de outra maneira, o primeiro conselho que daria é resistir ao desejo de fazer muito rapidamente.
Controle de fonte, refatoração, desenvolvedores mais treinados são todas boas sugestões, mas se esta é a primeira vez que você lida com esse tipo de problema, movendo-se lentamente e fazendo alterações controladas não pode ser enfatizado o suficiente.
Às vezes, o desejo de destruir a bagunça será grande, mas até que você faça a engenharia reversa o suficiente para saber que pode testar sua versão de substituição adequadamente, você precisa ter muito cuidado.
fonte
Os princípios mais importantes para trabalhar em tal situação são:
Seja paciente. Um buraco que levou 20 anos para cavar não será preenchido em poucas semanas.
Seja positivo. Resista à tentação de reclamar e resmungar.
Seja pragmático. Observe uma mudança positiva que você pode realizar em um dia e faça isso hoje. Já possui um sistema de controle de versão? Implementá-lo e treinar pessoas. Então veja e veja se você pode automatizar o teste (teste de unidade ou algo semelhante). Enxágüe. Repetir.
Seja um modelo. Mostre (não diga apenas) às pessoas como o ágil funciona sendo ágil. Os três primeiros pontos acima são as chaves para ser um Cara Bonzinho, que é o antecessor de um cara Ágil eficaz. Na minha opinião, as pessoas que são admiráveis desenvolvedores não são apenas inteligentes, também são boas, modelam funcionários e colegas.
Mapeie seu território. Eu tenho uma técnica para mapear bases de código herdadas gigantes. Clono o repositório, faço uma cópia de trabalho e tento mudar alguma coisa, e vejo o que mais quebra. Investigando o acoplamento (via estado global, ou APIs quebradas, ou a falta de API consistente ou quaisquer abstrações ou interfaces com as quais programar) e lendo o código que quebra quando eu mudo as coisas, descubro o problema, faço perguntas que levam a percepções do resto da equipe (acrescentamos que, porque o chefe X há 5 anos exigiu isso, nunca funcionou!). Com o tempo, você obterá um mapa mental do território. Depois de saber o tamanho, você saberá o suficiente para fazer seu mapa e chegar em casa. Incentive outras pessoas a mapear o território da sua base de código gigante e desenvolver o conhecimento técnico da equipe. Algumas pessoas se recusam a "documentação" porque não é ágil. Tanto faz. Também trabalho em ambientes científicos, e a documentação é essencial para mim, que manifestos ágeis sejam condenados.
Crie pequenos aplicativos. Ao trabalhar com uma base de código herdada, percebo que estou no limite. Recupero meu espírito criando pequenos aplicativos auxiliares. Talvez esses aplicativos o ajudem a ler, entender e modificar essa gigantesca base de código G2. Talvez você possa criar uma mini IDE ou ferramenta de análise que o ajudarão a trabalhar em seu ambiente. Existem muitos casos em que a metaprogramação e a criação de ferramentas não apenas o ajudam a romper com os impasses gigantes que as bases de código herdadas impõem a você, mas também dão ao seu cérebro a capacidade de voar sem restrições pela sua linguagem G2. Escreva suas ferramentas e auxiliares em qualquer idioma em que você possa fazê-los mais rapidamente e melhor. Para mim, essas linguagens incluem Python e Delphi. Se você é do tipo Perl ou gosta de programar em C ++ ou C #, escreva suas ferramentas auxiliares nessa linguagem.
fonte
Controle de revisão : mostre aos especialistas em domínio o benefício de poder reverter, ver quem mudou o quê etc. (Isso é mais difícil com arquivos binários, mas se o conteúdo é realmente código, certamente há algum tipo de G2 para conversor de texto que pode ativar as diferenças.)
Integração e teste contínuos : envolva os especialistas em domínio na criação de testes de ponta a ponta (mais fácil, pois eles já devem ter entradas e saídas esperadas em algum lugar) e testes de unidade pequena (mais difícil, porque o código espaguete provavelmente envolve muitas variáveis globais) que abrangem quase todas as funcionalidades e casos de uso.
Refatorar o código comum em rotinas e componentes reutilizáveis. Pessoas que não são de software e sem controle de revisão provavelmente copiam e colam centenas de linhas por vez para fazer rotinas. Encontre-os e refatore-os, mostrando que todos os testes passam e o código ficou mais curto. Isso também ajudará você a aprender sua arquitetura. Se você tiver sorte no momento em que tiver que começar a tomar decisões difíceis de arquitetura, poderá estar abaixo de 100KLOC.
Politicamente , se você encontrar resistência dos veteranos nesse processo, contrate um consultor para entrar e falar sobre uma boa metodologia de software. Certifique-se de encontrar uma boa pessoa com as opiniões com as quais concorda e de que a gerência compre a necessidade do consultor, mesmo que os especialistas em domínio não o façam. (Eles deveriam concordar - afinal, eles o contrataram, então, evidentemente, eles percebem que precisam de conhecimento em engenharia de software.) É um truque para desperdiçar dinheiro, é claro, mas a razão é que se você - o novo programador jovem e experiente - disser eles precisam fazer algo, eles podem ignorá-lo. Mas se a gerência pagar a um consultor US $ 5.000 para entrar e dizer a eles o que eles precisam fazer, eles confiarão mais nisso.Pontos bônus: peça ao consultor para aconselhar o dobro da alteração que realmente deseja, para que você possa ser o "cara legal" e ficar do lado dos especialistas em domínio, comprometendo-se a alterar apenas metade da quantidade sugerida pelo consultor.
fonte
Assumindo que o objetivo principal do seu software é simular (talvez otimizar, executar estimativas de parâmetros) uma planta química complexa , ou partes de uma ... então eu gostaria de lançar uma sugestão bastante diferente:
Convém considerar o uso de linguagem de modelagem matemática de alto nível para extrair a essência, os principais modelos matemáticos, de software codificado manualmente.
O que uma linguagem de modelagem faz é separar a descrição do problema dos algoritmos usados para resolvê-lo. Esses algoritmos são geralmente aplicáveis à maioria das simulações / otimizações de uma determinada classe (por exemplo, processos químicos); nesse caso, eles realmente não devem ser reinventados e mantidos internamente.
Três pacotes comerciais amplamente utilizados em seu setor são: gPROMS, Aspen Custom Modeller e (se seus modelos não incluem fenômenos distribuídos por domínios espaciais), existem pacotes de software baseados em Modelica, como o Dymola.
Todos esses pacotes suportam "extensões" de uma maneira ou de outra, de modo que, se você tem partes de seus modelos que requerem programação personalizada, elas podem ser encapsuladas em um objeto (por exemplo, uma .DLL) que pode ser referenciado pelas equações no modelo. Enquanto isso, a maior parte do seu modelo permanece sucinta, descrita de uma forma facilmente legível pelos cientistas diretamente. Essa é uma maneira muito melhor de capturar o conhecimento e o IP da sua empresa.
A maioria desses programas também deve permitir que você 'inicie pequenas' e transforme pequenas partes (submodelos) do seu código monolítico em seu formato, sendo chamadas externamente. Essa pode ser uma boa maneira de manter um sistema em funcionamento e validá-lo uma peça por vez.
Isenção de responsabilidade total: trabalhei como engenheiro de software na empresa por trás do gPROMS por 8 anos. Naquele tempo, vi (e ocasionalmente incorporei) exemplos de software personalizado (por exemplo, provenientes da academia), que tinham começado pequenos e arrumados, implementando alguma solução ou algoritmo inteligente, mas depois explodiram ao longo dos anos com extensões e modificações - sem a orientação útil de um engenheiro de software para mantê-lo limpo. (Eu sou um grande fã de equipes multidisciplinares.)
Então, posso dizer com alguma experiência que certas escolhas importantes feitas mal no início do desenvolvimento de um software (como uma linguagem ou biblioteca de chaves) tendem a permanecer e causar dor por um longo tempo ... Eles já 'moldaram' o software em torno deles. Parece-me que você pode estar enfrentando muitos anos de pura limpeza de código aqui. (Estou hesitante em usar números, mas estou pensando em mais de 10 anos, talvez muito mais, se você não conseguir transferir o código do G2 para algo que ofereça suporte a boas ferramentas de refatoração automatizada, como o Eclipse / Java quick-smart.)
Embora meu status padrão seja "refatorar e manter um sistema operacional", também acho que quando um problema fica "muito grande", uma mudança / reescrita mais radical se torna mais rápida em geral. (E, possivelmente, traz benefícios adicionais, como passar para uma tecnologia mais moderna.) Digo que, com alguma experiência em migrar para uma nova plataforma de software, mas pelo que entendi, é ainda mais dramático com uma porta para um pacote de modelagem matemática.
Para dar uma perspectiva, você pode se surpreender com a redução de tamanho. Por exemplo, os 200.000 LoC poderiam realmente ser representados em algo como 5.000 linhas de equações (OK, estou supondo aqui, mas poderia tentar obter um depoimento real de amigos da empresa); além de alguns módulos de função relativamente pequenos, escritos em algo como C (por exemplo, cálculos de propriedades físicas - embora possam existir novamente pacotes prontos para uso, dependendo do seu processo químico). Isso ocorre porque você simplesmente joga fora o código da solução algorítmica e deixa uma "pilha" de uso geral de solucionadores matemáticos fazer o trabalho duro. Depois de executar as simulações, você pode fazer muito mais com elas, como otimizar o processo - sem alterar uma linha de código.
Finalmente, eu diria: se a única documentação confiável dos vários modelos matemáticos (e algoritmos) for o próprio código, você precisará da ajuda dos cientistas e dos autores originais para ajudar a extrair esses modelos, o mais rápido possível, não anos depois, quando alguns deles podem ter se mudado. Eles devem achar que uma linguagem de modelagem matemática é uma maneira muito natural de capturar esses modelos - eles podem até (horror de choque) gostar de (re) escrever.
Finalmente, como minha resposta pode estar errada, gostaria de adicionar mais um livro à lista de bons livros já mencionados aqui: Clean Code, de Robert Martin. Cheio de dicas simples (e justificadas), fáceis de aprender e aplicar, mas que podem fazer muita diferença para as pessoas que desenvolvem novo código em sua empresa.
fonte
Eu descartaria o seguinte:
Há um programador aqui. Dane-se a política. Eles conhecem o seu ofício. Você conhece o seu. Marque esse território mesmo que você precise mijar nele. Eles são cientistas. Eles podem respeitar esse tipo de coisa ou devem, uma vez que estão constantemente fazendo o mesmo. Por qualquer meio que puder, marque os limites agora. É isso que eu vou consertar. É por isso que não posso ser responsável.
Os cientistas escrevem / testam os algoritmos. Os cientistas que desejam podem escrever seus próprios algoritmos em 1 a 3 idiomas em que todos podem concordar com a conversão para o código principal. Isso coloca o teste deles neles. Além disso, eles terão que ajudá-lo a isolar as coisas importantes da ciência versus o bom Deus sabe o que eles fizeram pela arquitetura. A base de código é mangueira. Há muitas barras e queimaduras que precisam ser feitas. Dê a eles opções para entregar a você versões de trabalho de coisas que empregam o que sabem melhor para que você possa fazer o que faz de melhor. Coloque seus conhecimentos em uma caixa pela qual eles são responsáveis, mas com os quais você pode trabalhar.
Use uma linguagem orientada a eventos com funções de primeira classe, se puder. Quando tudo mais falhar, acionar um evento ou lançar um retorno de chamada para algum objeto com uma interface e um mecanismo de estado que realmente faça sentido pode economizar muito tempo quando você estiver envolvido em um código que não faz muito sentido e possivelmente nunca vai. Os cientistas parecem gostar de Python. Não é difícil colar coisas C intensivas em matemática de nível inferior com isso. Apenas dizendo'
Procure alguém que tenha resolvido esse ou um problema semelhante. Passe algum tempo sério pesquisando. Esses caras ouviram falar do G2 de alguém.
Padrões de design. Adaptadores. Use-os. Use-os muito em situações como esta.
Aprenda o que puder da ciência. Quanto mais você souber, melhor poderá determinar a intenção no código.
fonte
Faça a análise primeiro.
Eu faria algumas análises antes de decidir o que ensinar. Descobrir onde estão os maiores pontos problemáticos. Use-os para priorizar quais práticas serão adotadas.
Introduzir apenas algumas alterações de cada vez (em uma situação semelhante, eu fiz 2-3 práticas a cada 2 semanas) .
Eu limitaria as práticas a ~ 3, dependendo do nível de mudança, para o estilo de programação do SDLC; até que eles comecem a se sentir confortáveis com eles (eu insistiria em introduzir uma nova alteração a cada ~ 1-2 semanas, à medida que se sentissem mais à vontade com a idéia de aprender novas abordagens). Também é uma boa idéia identificar quais são os critérios para o sucesso. O que a prática deve realizar (mesmo que seja um objetivo moderado, como o moral da equipe). Dessa forma, você pode mostrar se é eficaz ou não.
Mesmo se você presumir que essas pessoas desejam ser melhores programadores e estão abertas ao aprendizado, há limites para quanto e com que rapidez as pessoas podem aprender novos conceitos e aplicá-los; especialmente se eles não tiverem o CS Foundation ou tiverem participado de um ciclo de vida de desenvolvimento de software anteriormente.
Adicione uma reunião semanal de encerramento para discutir como as práticas os afetaram.
A reunião deve ser usada para discutir o que correu bem e o que precisa funcionar. Permita que eles tenham voz e sejam colaborativos. Discuta e faça planos para resolver os problemas que estão enfrentando e para visualizar as próximas mudanças que estão por vir. Mantenha a reunião focada nas práticas e sua aplicação. Evangelize um pouco sobre os benefícios que eles devem começar a ver com a aplicação das práticas.
Certas práticas têm precedência.
O uso adequado de um sistema de controle de versão (IMO) supera todo o resto. Logo atrás estão as lições de modularização, acoplamento / coesão e rastreamento de recurso / bug.
Remova práticas que não funcionam.
Não tenha medo de se livrar de práticas que não funcionam. Se houver um custo alto e pouco ou nenhum benefício, remova a prática.
Melhoria é um processo.
Transmitir que a melhoria sustentada e consistente é um processo. Identifique os maiores pontos problemáticos, aplique uma solução, aguarde / treine e repita. Inicialmente, parecerá agonizante e lento até você criar algum impulso. Mantenha todos focados nas melhorias que estão chegando e nas que já são bem-sucedidas.
fonte
Parece que o primeiro passo é vender à equipe a necessidade de investir em uma nova metodologia de software. De acordo com sua declaração, não há consenso na equipe e você precisará dela para avançar com uma "atualização" lenta do código.
Eu (se puder) pessoalmente pegaria as lições aprendidas e apresentaria cada um dos principais conceitos que você deseja como a solução para o problema na indústria de software.
Por exemplo, dois desenvolvedores tiveram cópias diferentes e acabaram implantando uma versão híbrida não testada -> Introduzir controle de versão, ramificação e teste.
Alguém removeu algumas linhas de código que não entendiam e causou uma interrupção -> introduziu o DDD.
Se as lições difíceis não estiverem sendo compartilhadas com você em detalhes suficientes, apenas mostre seus próprios exemplos de como as coisas deram errado quando essa disciplina não foi cumprida.
fonte
O controle do código-fonte é a etapa 1, como já foi dito várias vezes. Embora as pessoas com quem você trabalha não sejam desenvolvedores profissionais e não respondam a muitas empresas ou jumbo agile. Eles também não são macacos de código de baixo nível e tentar tratá-los dessa maneira, forçando-os a fazer as coisas 'do seu jeito' não voará.
Você tem que pesquisar o que está lá fora. Se eles não usaram o controle do código-fonte, basta identificar as versões corretas do código (se possível) e o que todas as entregas possíveis levarão muito tempo. Então, você terá a tarefa de ensinar seus colegas a usar o controle do código-fonte e convencê-los de que vale a pena. Comece com os benefícios!
Enquanto estiver fazendo isso, encontre outras frutas baixas e corrija esses problemas.
Acima de tudo, ouça o que eles têm a dizer e trabalhe para melhorar sua situação. Não se preocupe em tentar colocar sua marca no que eles fazem.
Boa sorte!
fonte