Existe um paradigma de programação que promove tornar as dependências extremamente óbvias para outros programadores?


26

Trabalho em um Data Warehouse que origina vários sistemas através de muitos fluxos e camadas com dependências semelhantes a labirintos que vinculam vários artefatos. Praticamente todos os dias eu me deparo com situações como essa: eu corro algo, não funciona, passo por um monte de código, mas horas depois percebo que consegui conceituar o mapa do processo de uma pequena parte do que agora sei mais tarde, é necessário, portanto, pergunto a alguém e eles me dizem que esse outro fluxo deve ser executado primeiro e que, se eu verifiquei aqui (indicando alguma parte aparentemente arbitrária de uma pilha enorme de outras dependências codificadas), eu teria visto isso. É incrivelmente frustrante.

Se eu pudesse sugerir à equipe que talvez fosse uma boa idéia fazer mais para tornar as dependências entre os objetos mais visíveis e óbvias, em vez de incorporá-las profundamente em níveis recursivos de código ou mesmo nos dados que precisa estar presente devido ao fato de ser preenchido por outro fluxo, talvez referindo-se a um paradigma de software conhecido, experimentado e testado - para que eu possa tornar meu trabalho e todos os demais muito mais simples.

É meio difícil explicar os benefícios disso para minha equipe. Eles tendem a aceitar as coisas do jeito que são e não 'pensam grande' em termos de ver os benefícios de poder conceituar todo o sistema de uma nova maneira - eles realmente não vêem isso se você puder modelar um sistema enorme com eficiência, torna menos provável que você encontre ineficiências de memória, interrompa o fluxo de restrições exclusivas e chaves duplicadas, dados sem sentido, porque é muito mais fácil projetá-lo de acordo com a visão original e você não encontrará mais tarde todos esses problemas que agora estamos experimentando, o que eu sei ser incomum em empregos passados, mas que eles parecem pensar como inevitável.

Então, alguém conhece um paradigma de software que enfatiza dependências e também promove um modelo conceitual comum de um sistema, com o objetivo de garantir a adesão a longo prazo a um ideal? No momento, praticamente temos uma bagunça gigante e a solução que todo sprint parece ser "apenas adicione algo aqui e aqui e aqui" e eu sou o único preocupado com o fato de as coisas realmente começarem a desmoronar.


2
Você poderia esclarecer que tipo de "dependências semelhantes a labirintos vinculando vários artefatos" são essas? Eles são dependências de compilação que podem ser resolvidas com uma ferramenta de compilação como o Maven? São dependências de entrada, onde um desses artefatos depende de alguma entrada que não é óbvia ou clara? Eles são dependências importantes entre tabelas de banco de dados?
FrustratedWithFormsDesigner

O sistema é PLSQL, Unix bash, OWB, etc., portanto existem todos os tipos de dependências. Às vezes, os dados são requeridos de um determinado formato, em um determinado local, em um determinado momento, por um determinado módulo, mas não são remotamente óbvios a partir do código e só podem ser discernidos de duas maneiras: atravessando a montanha de códigos, levando talvez dias, para descobrir que alguns dados tinham um ponto-e-vírgula delimitador em uma parte do sistema que você nem sabia que estava sendo referenciada, pois estava enterrada em 10 camadas de código recursivamente chamado, ou perguntando a alguém, todos os tempo, toda vez. Não promove independência.
precisa saber é o seguinte

4
Literalmente todos eles
Miles Rout

3
Pouco tangente: como Haskell é preguiçoso, você não especifica efetivamente a ordem das operações ao escrever código. Você especifica apenas dependências. A função C depende dos resultados das funções A e B. Portanto, A e B precisam ser executados antes de C, mas pode funcionar igualmente bem se A for executado primeiro ou se B for executado primeiro. Eu apenas pensei que isso era interessante.
precisa saber é o seguinte

1
Existe um livro chamado Design patterns (o livro é péssimo, mas a maior parte do que diz é boa, exceto a parte sobre singleton). Possui várias seções sobre gerenciamento de dependências.
Ctrl-alt-delor

Respostas:


19

Descoberta

Sua ausência atormenta muitas organizações. Onde está a ferramenta que Fred construiu novamente? No repositório Git, com certeza. Onde?

O padrão de software que vem à mente é Model-View-ViewModel. Para os não iniciados, esse padrão é um completo mistério. Expliquei a minha esposa como "cinco widgets flutuando acima da mesa conversando entre si por alguma força misteriosa". Entenda o padrão e você entende o software.

Muitos sistemas de software falham em documentar sua arquitetura porque eles assumem que ela é auto-explicativa ou emerge naturalmente do código. Não é, e não é. A menos que você esteja usando uma arquitetura bem definida, novas pessoas se perderão. Se não estiver documentado (ou conhecido), novas pessoas se perderão. E os veteranos também se perderão, depois de ficarem longe do código por alguns meses.

É responsabilidade da equipe criar uma arquitetura organizacional sensata e documentá-la. Isso inclui coisas como

  • Organização da pasta
  • Referências do projeto
  • Documentação de classe (o que é, o que faz, por que existe, como é usado)
  • Projeto, módulo, montagem, qualquer documentação.

É responsabilidade da equipe tornar as coisas organizadas e descobertas para que a equipe não reinvente constantemente a roda.

A propósito, a noção de que "o código deve ser auto-documentado" está apenas parcialmente correta. Embora seja verdade que seu código deve ser claro o suficiente para que você não precise explicar cada linha de código com um comentário, os relacionamentos entre artefatos como classes, projetos, montagens, interfaces e similares são não óbvios e ainda assim precisa ser documentado.


3
Claro, mas as pessoas que se apegam demais aos padrões de design fazem parte do problema. Eles são os que escrevem o código sem nenhuma documentação, assumindo que todos os outros entenderão o que diabos eles fizeram apenas olhando o código. Além disso, os padrões de design de software não são arquitetura (na maior parte).
Robert Harvey

1
Onde está a ferramenta que Fred construiu novamente? No repositório Git, com certeza. Onde? - Exatamente! O padrão MVC é muito específico para o desenvolvimento de front-end (eu acho), e os padrões são úteis apenas se todos da equipe os conhecerem, então isso muda o problema das dependências não óbvias para as óbvias SE todos souberem encontrar eles. Mas o problema pressupõe que esse não seja o caso. Como tal, espero que exista algo que promova uma maneira realmente óbvia de explicar dependências que não exijam outra estrutura conceitual aprendida para você usar.
precisa saber é o seguinte

7
É chamado de "documentação". Além disso, você precisa de uma estrutura de dependência sensata que todos suportem. Infelizmente, não há um modelo padrão que você possa inserir no seu projeto; a estrutura organizacional do software é algo que sua equipe cria, com a ajuda de uma arquitetura sensata.
Robert Harvey

5
@RobertHarvey: Ouvimos recentemente: "Nós escrevemos código que não precisa de documentação". Errado. Você está escrevendo código sem documentação.
gnasher729

3
Algumas coisas boas aqui. Nota: existe uma diferença entre escrever código que não requer comentários e escrever documentação de suporte.
Robbie Dee

10

A melhor maneira de abordar esses tipos de problemas é incrementalmente. Não fique frustrado e proponha mudanças arquitetônicas amplas e abrangentes. Essas nunca serão aprovadas e o código nunca melhorará. Isso pressupõe que você possa determinar as mudanças arquitetônicas amplas e abrangentes corretas a serem feitas, o que é improvável.

O que é provável é que você pode determinar uma mudança menor que teria ajudado com o problema específico que você acabou de resolver. Talvez invertendo algumas dependências, acrescentando alguma documentação, criando uma interface, escrevendo um script que avisa de uma dependência em falta, etc. Então, proponho que a mudança menor em seu lugar. Ainda melhor, dependendo da cultura da sua empresa, eles podem tolerar ou até esperar que você faça melhorias como essa como parte de sua tarefa original.

Quando você faz essas alterações menores uma parte regular do seu trabalho e, pelo seu exemplo, incentiva outras pessoas a fazerem isso, elas realmente aumentam com o tempo. Muito mais eficaz do que reclamar de mudanças maiores que você não tem permissão para fazer.


2
Eu concordo com a ideia de mudanças incrementais. O problema é que, sem alguns princípios organizacionais já existentes, você pode estar criando mais caos. Considere o efeito de mover apenas um único projeto, classe ou outro artefato (no qual outros módulos dependem) para um local mais sensível.
Robert Harvey

1
Coisas boas. Minhas dores de parto foram muitas vezes menos árduas por algumas almas diligentes, que têm o desejo de adicionar uma ferramenta / widget aqui e ali para criar ordem a partir do caos. Embora eu não seja um fã de resmas e resmas de documentação, uma folha de dicas ou uma lista de dicas / recursos bem escritos pode ajudar bastante.
Robbie Dee

+1 por propor pequenas alterações que provavelmente serão aprovadas. Eu experimentei isso e isso me ajudou a me tornar alguém com mais influência, e então minhas propostas tiveram mais impacto.
precisa saber é o seguinte

2

Arquitetura.

Não existe um princípio ou prática único, específico e universal que resolva os problemas de descoberta e manutenção que se aplicam a todos os aspectos de todo software. Mas, o termo amplo para as coisas que tornam um projeto são é arquitetura.

Sua arquitetura é todo o corpo de decisões em torno de cada ponto de confusão potencial (ou histórica) - incluindo a designação de como as decisões arquitetônicas são tomadas e documentadas. Tudo relacionado ao processo de desenvolvimento, estrutura de pastas, qualidade do código, padrões de design etc. são coisas que podem entrar na sua arquitetura, mas nenhuma delas é uma arquitetura.

Idealmente, essas regras são unificadas por uma singularidade da mente.

Uma equipe pequena certamente pode criar arquitetura de forma colaborativa. Mas, com opiniões variadas, isso pode levar rapidamente a uma arquitetura muito esquizofrênica que não serve para manter sua sanidade. A maneira mais simples de garantir que sua arquitetura, e os muitos TLAs e padrões nela, sirvam ao sucesso da equipe com uma singularidade de mente é tornar uma única mente responsável por eles.

Agora, isso não requer necessariamente um "arquiteto" para pontificar . E, embora algumas equipes possam querer que uma pessoa experiente tome essas decisões, o ponto principal é que alguém precisa possuir a arquitetura, especialmente à medida que a equipe cresce. Alguém mantém o dedo no pulso da equipe, modera discussões arquitetônicas, documenta decisões e monitora decisões e trabalha no futuro para conformidade com a arquitetura e seu espírito.

Eu não sou um grande fã de qualquer pessoa tomando todas as decisões; mas identificar um "arquiteto" ou "proprietário técnico do produto", responsável por moderar as discussões sobre arquitetura e documentar decisões, combate um mal maior: a difusão da responsabilidade que não leva a nenhuma arquitetura discernível.


Você está absolutamente correto ao identificar a difusão de responsabilidade como sendo responsável por nenhuma arquitetura discernível. Recentemente, foram tomadas decisões para corrigir esse problema. Eu sempre acho que uma boa solução para isso seria criar um sistema distribuído inteiro através de outro sistema de software que funcione como um tipo de equipamento, onde você decide o que entra no sistema, mas decide onde, de acordo com a programação do arquiteto. Você teria um ponto de vista em vários sistemas e tecnologias diferentes e seria navegá-los através de algum diagrama de arquitetura do sistema ...
Christs_Chin

Acho que o seu ponto nesta resposta é a melhor maneira de combater / impedir o tipo de coisa sobre a qual o OP está falando. Aplica-se mesmo a herdar uma bagunça como o OP.
GWR

1

Bem-vindo à engenharia de software (nos dois sentidos);) Essa é uma boa pergunta, mas realmente não há respostas fáceis, como tenho certeza de que você está ciente. É realmente um caso de evoluir para melhores práticas ao longo do tempo, treinando as pessoas para serem mais hábeis (por definição, a maioria das pessoas na indústria tem competência medíocre) ...

A engenharia de software como disciplina sofre por construí-la primeiro e projetar a mentalidade conforme o uso, parte por conveniência e parte por necessidade. É apenas a natureza da besta. E, é claro, os hacks são construídos com o passar do tempo, à medida que os codificadores mencionados anteriormente implementam soluções funcionais rapidamente que resolvem as necessidades de curto prazo, muitas vezes à custa da introdução de dívidas técnicas.

O paradigma que você precisa usar é essencialmente melhorar as pessoas, treinar as pessoas que você tem bem e enfatizar a importância de dedicar tempo ao planejamento e à arquitetura. Não se pode facilmente ser tão "ágil" quando se trabalha com um sistema monolítico. Pode ser necessário um planejamento considerável para implementar até pequenas mudanças. A implantação de um excelente processo de documentação de alto nível também ajudará as pessoas-chave a entender o código mais rapidamente.

As idéias nas quais você poderia se concentrar seriam (com o tempo, gradualmente) isolar e refatorar partes-chave do sistema de uma maneira que as torne mais modulares e dissociadas, legíveis e mantidas. O truque é trabalhar para atender aos requisitos comerciais existentes, para que a redução da dívida técnica possa ser feita simultaneamente com a entrega de valor comercial visível. Portanto, a solução é parte de melhorar práticas e habilidades e parte de tentar avançar mais em direção ao pensamento arquitetônico de longo prazo, como posso dizer que você já o é.

Observe que eu respondi a essa pergunta da perspectiva da metodologia de desenvolvimento de software, e não da perspectiva da técnica de codificação, porque esse é realmente um problema muito maior que os detalhes da codificação ou mesmo do estilo arquitetural. É realmente uma questão de como você planeja a mudança.


6
Eu ouvi o que você está dizendo, mas sua resposta é, no final das contas, insatisfatória e francamente um pouco ofensiva. É um problema maior do que apenas contratar pessoas melhores; mesmo na pequena loja em que trabalho, lutamos com isso e acho que é mais do que apenas um problema de pessoas; Eu acho que tem alguns pontos técnicos específicos.
Robert Harvey

1
Concordo que existem aspectos técnicos, mas acho que esses são relativamente menores se comparados à ênfase em uma metodologia mais forte para planejar mudanças. Não vejo isso como padrões de design, mas como uma mudança cultural para mais planejamento e análise, planejamento e análise anteriores e melhor planejamento e análise.
Brad Thomas

Tudo bem, vou postar minha própria resposta como uma comparação. Eu não acho que tenha algo a ver com padrões de software.
Robert Harvey

Brad, obrigado pela resposta. Sua resposta é apreciada, pois sei que não estou sozinha em saber desse problema. Parece assim na minha equipe. Também concordo com Robert Harvey, no sentido de que esse problema é generalizado e não quero desistir da crença de que existe uma solução, seja em um novo tipo de software ou em uma nova prática de trabalho.
precisa saber é o seguinte

2
Exatamente minha experiência: você deve fazer com que os membros da sua equipe entendam o que estão fazendo. Eu vejo pessoas misturando MVVM e MVC, outras usando controles WPF de uma maneira normal com o Windows Forms (ou melhor: VB6), pessoas programando em C # sem um entendimento básico de orientação a objetos ... Ensine-as. Ensine-os novamente. Seja frustrado. Ensine-os novamente ... Muitas vezes, pensando em desistir. E ensinando-lhes de novo ...
Bernhard Hiller

1

Gosto da ideia de convenções de RobertHarvey e acho que elas ajudam. Eu também gosto da idéia de @ KarlBielefeldt de "documentar conforme você avança" e sei que isso é essencial, porque essa é a única maneira de manter a documentação atualizada. Mas acho que a ideia abrangente é que é importante documentar como encontrar todas as partes do seu código, compilar e implantá-las!

Recentemente, enviei um e-mail para um projeto de código-fonte aberto significativo que tinha alguma configuração XML que gerava código totalmente sem documentos. Perguntei ao mantenedor: "Onde está documentado esse processo de geração de código XML? Onde está documentada a instalação do banco de dados de teste?" e ele disse: "Não é". É basicamente um projeto de colaborador único e agora eu sei o porquê.

Olha, se você é essa pessoa e está lendo isso, eu realmente aprecio o que você está fazendo. Eu praticamente adoro os frutos de seus trabalhos! Mas se você passou uma hora documentando como suas coisas realmente criativas são reunidas, eu poderia passar alguns dias codificando novos recursos que poderiam ajudá-lo. Quando confrontados com a parede de tijolos da "falta de documentação não é um problema", eu nem vou tentar.

Em uma empresa, a falta de documentação é um enorme desperdício de tempo e energia. Projetos como esse costumam ser direcionados a consultores que custam ainda mais, apenas para descobrir coisas básicas como "onde estão todas as peças e como elas se encaixam".

Em conclusão

O que é necessário não é tanto uma tecnologia ou metodologia, mas uma mudança de cultura; uma crença compartilhada de que documentar como as coisas são construídas e por que é importante. Deveria fazer parte das revisões de código, um requisito para mudar para a produção, vinculado a aumentos. Quando todos acreditam nisso e agem de acordo, as coisas mudam. Caso contrário, será como minha falha na contribuição de código aberto.


2
Suspeito que parte do problema cultural esteja na crença do Agile de que "se não faz parte de uma história de usuário (ou seja, não contribui diretamente para o valor das partes interessadas), não é importante". Hogwash. Conversa relacionada aqui: No ágil, como as tarefas básicas de infraestrutura no início de um projeto são planejadas e alocadas?
Robert Harvey

@RobertHarvey Sim. Todos na minha equipe são incrivelmente brilhantes e muito fáceis de lidar. Os mestres do scrum e os gerentes de projeto são bem-intencionados e motivados, e as práticas são as mais ágeis nas quais trabalhei. Mas a documentação está faltando, provavelmente pela mesma razão que você sugere. Além disso, quando a documentação é criada, uma outra camada de aleatoriedade na eficácia da comunicação é introduzida na capacidade da pessoa de identificar conceitos pertinentes e também de explicá-los, sem mencionar sua atitude em relação a ter que realizar tal tarefa. Normalmente é apenas "Pergunte somone"
Christs_Chin

@GlenPeterson Sim, eu concordo que isso seria útil. Mas deve ser especificado não apenas que ele deve ser construído, mas também como e o que qualifica como documentação. Por exemplo, como um exemplo recente aqui, alguém incluiu uma lista de novos números que nosso sistema identificará. É isso aí. Não houve menção de como esses números entram no sistema, onde, por que, por quem, com que frequência ou algo útil, apenas o que eles fazem. Em nenhum momento me perguntei quais números nosso sistema identificaria como relevantes. Mas sempre me perguntei onde eles entram, para onde vão e o que acontece no caminho. Ainda é um mistério.
precisa saber é o seguinte

1
@ Chris_Chin Muita comunicação é baseada no contexto. Sem esse contexto, a maioria das comunicações é quase sem sentido. Eu sinto sua dor. Mas acho que é difícil escrever (em inglês) para que outras pessoas possam entender você. Às vezes, as especificações iniciais de um sistema têm o contexto que você precisa para entendê-lo, mesmo que estejam terrivelmente desatualizadas, o contexto geralmente ajuda.
GlenPeterson

1

Para responder à pergunta como ela é colocada (em vez de aconselhá-lo para sua situação específica):

O paradigma de programação conhecido como programação funcional pura requer que tudo que afeta a saída de uma função seja especificado nos parâmetros de entrada. Não há dependências ocultas ou variáveis ​​globais ou outras forças misteriosas agindo invisivelmente na base de código. Não há "você precisa fazer isso primeiro" acoplamento temporal.


0

Cada armazém de dados é diferente, mas há muito o que você pode fazer para facilitar as coisas para si.

Para começar, cada linha no banco de dados tinha um DATE_ADDED e DATA_UPDATED coluna para que pudéssemos ver quando ele foi adicionado ao banco de dados e quando foi alterado. Também tínhamos uma coluna SOURCE_CODE para poder rastrear onde cada bit de dados entrava no sistema.

Em seguida, tínhamos ferramentas comuns que funcionavam em todos os nossos data warehouses, como classificações, correspondências de tabelas, segmentações e segmentações, etc.

O código sob medida foi mantido no mínimo absoluto e, mesmo assim, ele teve que confirmar vários estilos de codificação e relatório.

Eu vou assumir que você já está familiarizado com as suítes ETL . Hoje em dia, existem muitas funcionalidades que você obtém de graça que não estavam presentes quando eu estava no jogo cerca de uma década atrás.

Você também pode consultar os data marts para apresentar uma versão mais amigável e higienizada do seu data warehouse. Obviamente, não é uma bala de prata, mas poderia ajudar com certos problemas, em vez de ter que reconstruir / corrigir seu data warehouse.


obrigado pela resposta. Sim, usamos todos esses campos, mas eles realmente ajudam na identificação de uma única linha, não nas dependências entre fluxos, camadas e sistemas. Você está certo sobre os pacotes ETL - estávamos no processo de atualizar para uma ferramenta ETL conhecida de uma que estava ficando sem suporte, mas acabou voltando ao PLSQL. É bom codificar, mas para manter e entender o sistema como um todo, é absolutamente terrível.
precisa saber é o seguinte

1
O ideal é que você possa rastrear dados de ponta a ponta, seja por meio de tabelas temporárias ou arquivos simples, mas se você não tiver isso, ficará com o código de acesso.
Robbie Dee

0

Não sei o quanto é relevante para o seu caso, existem algumas estratégias para tornar as dependências mais visíveis e a manutenção geral de códigos.

  • Evite variáveis ​​globais, use parâmetros. Isso também se aplica a chamadas em vários idiomas.
  • Evite alterar / alterar os valores das variáveis, tanto quanto possível. Faça uma nova variável e use, quando precisar alterar o valor, se possível.
  • Faça o código modular. Se não for possível descrever o que a parte (não como) está realmente fazendo em uma frase simples, divida-a em módulos que satisfaçam a condição.
  • Nomeie as partes do código corretamente. Quando você pode realmente descrever o que uma parte do código está fazendo em termos simples, esses termos se tornam o nome da parte. Assim, o código se torna auto-documentado por meio de nomes de módulos / classes / funções / procedimentos / métodos etc.
  • Teste seu código. Teste se as entidades no seu código justificam seus nomes, discutidas no ponto anterior.
  • Registre eventos no código. Mantenha pelo menos dois níveis de log. O primeiro é sempre ativado (mesmo em produção) e registra apenas eventos críticos. E use o outro para registrar basicamente tudo, mas pode ser ativado ou desativado.
  • Encontre e use ferramentas adequadas para navegar, manter e desenvolver sua base de código. Mesmo uma simples opção "Pesquisar tudo" do Visual Studio Code facilitou muito minha vida em certos casos.
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.