DRY é o inimigo do gerenciamento de projetos de software?


83

Um dos princípios mais básicos e amplamente aceitos do desenvolvimento de software é o DRY (não se repita). Também está claro que a maioria dos projetos de software requer algum tipo de gerenciamento.

Agora, quais são as tarefas fáceis de gerenciar (estimativa, cronograma, controle)? Certo, tarefas repetitivas, exatamente as tarefas que devem ser evitadas de acordo com o DRY.

Portanto, do ponto de vista do gerenciamento de projetos, é ótimo resolver uma tarefa, copiando algum código existente 100 vezes e fazendo algumas pequenas adaptações em cada cópia, conforme necessário. Em todo o momento, você sabe exatamente quanto trabalho fez e quanto resta. Todos os gerentes vão amar você.

Se, em vez disso, você aplicar o princípio DRY e tentar encontrar uma abstração que elimine mais ou menos o código duplicado, as coisas serão diferentes. Geralmente existem muitas possibilidades, você precisa tomar decisões, pesquisar, ser criativo. Você pode encontrar uma solução melhor em menos tempo, mas também pode falhar. Na maioria das vezes, você não pode realmente dizer quanto trabalho resta. Você é o pior pesadelo de um gerente de projetos.

Claro que estou exagerando, mas obviamente há um dilema. Minhas perguntas são: Quais são os critérios para decidir se um desenvolvedor está exagerando no DRY? Como podemos encontrar um bom compromisso? Ou existe uma maneira de superar completamente esse dilema, não apenas encontrando um compromisso?

Nota: Esta pergunta é baseada na mesma idéia que a anterior, Quantidade de trabalho de rotina no desenvolvimento de software e seu efeito na estimativa , mas acho que isso torna meu argumento mais claro, desculpe-me por me repetir :).


96
Deixe-nos saber como estão as suas costeletas de gerenciamento de projetos quando chegar a hora de caçar, alterar e testar algo em todas as 100 instâncias de copiar e colar. E não se esqueça do tempo adicional que será gasto para descobrir por que ele acaba danificado porque apenas 98 deles foram alterados.
Blrfl

16
@Blrfl, por outro lado, a secagem prematura do código antes que uma boa abstração seja clara também pode prejudicar a produtividade, pois uma abstração compartilhada é uma dependência compartilhada. Não estou discordando, apenas apontando que há definitivamente um equilíbrio a ser encontrado.
GoatInTheMachine

16
O princípio que impede DRY de ficar fora de controle é o princípio YAGNI (você não vai precisar dele) .
Philipp

88
Não há dilema. Se o gerente de projeto quiser que você faça muito trabalho manual supérfluo, porque é fácil estimar, a solução óbvia é acionar o gerente de projeto.
precisa saber é o seguinte

10
Se você se repetir, ainda precisará fazer todo esse trabalho difícil de estimar , além de algum trabalho extra inútil. Então, como isso ajuda o projeto?
user253751

Respostas:


134

Você parece assumir que o objetivo principal do gerenciamento de projetos é produzir estimativas exatas. Este não é o caso. O objetivo principal do gerenciamento de projetos é o mesmo dos desenvolvedores: agregar valor ao proprietário do produto.

Um produto que utiliza muitos processos manuais lentos em vez de automação pode, em teoria, ser mais fácil de estimar (embora eu duvide), mas não fornece valor ao dinheiro ao cliente, por isso é simplesmente um mau gerenciamento de projetos. Não há dilema.

É sabido que a estimativa de projetos de software é difícil, e vários livros foram escritos e vários processos foram desenvolvidos para gerenciá-lo.

Se o único objetivo do PM fosse produzir estimativas exatas, seria fácil. Apenas reduza as estimativas para 10X e deixe os desenvolvedores jogarem pelo resto se terminarem mais cedo. Isso seria realmente melhor do que sua sugestão de usar o trabalho copiar-colar para diminuir o tempo, pois jogar não reduzirá a manutenção do produto.

Mas, na realidade, o proprietário do produto deseja estimativas úteis e um produto de qualidade entregue o mais rápido e barato possível. Essas são as restrições reais que um PM terá para navegar.

De qualquer forma, discuto sua suposição de que o trabalho manual repetitivo é mais previsível do que automatizado. Toda a experiência mostra que o trabalho manual repetitivo é mais propenso a erros. E se um bug for descoberto no código copiado e colado? De repente, o custo de consertar um bug é multiplicado pela quantidade de repetição, o que faz a incerteza explodir.


21
Concordo plenamente com suas afirmações aqui, mas acho que é preciso observar que existem muitos gerentes de projetos por aí que realmente preferem a previsibilidade à velocidade ou à qualidade. Muitas pessoas que não têm treinamento em gerenciamento de projetos aprendem o que sabem sobre o que viram e minha experiência é que os gerentes de projetos que conseguem lidar com a incerteza de uma maneira racional e calma são poucos e distantes.
precisa saber é o seguinte

5
@FrankPuffer Estive lá. Quanto tempo vai demorar? Uma opção aqui é fornecer um intervalo. Leia o PERT especificamente sobre estimativas de 3 pontos, porque eles já devem saber disso. Porcentagem concluída? Este é o mais irritante. Tente ignorá-lo, mas se você não se lembrar que é tempo percentual, não percentual de linhas codificadas ou o que seja. O que eles realmente querem saber é Quando será concluído? Desde o início, faça previsões conservadoras sobre cada tarefa e refine-o à medida que avança. Esperar até o último minuto para lhe dizer mais tempo deixará as pessoas loucas.
JimmyJames

11
Quanto tempo vai demorar? Tenho 60% de certeza de que podemos terminá-lo por x, mas há uma chance de 10% de levar cinco vezes mais.
David

18
@ David: Esta provavelmente conduzir o PM louco, porque ele sabe por experiência que esta chance de 10% actuall acontece 80% das vezes :)
Frank soprador

7
A realidade é que muitos lugares gostariam de acompanhar um projeto e, em seguida, ter sucesso inesperado. Os PMs são frequentemente recompensados ​​por terem projeções precisas, de modo a terem incentivos perversos. Esse é o problema do agente principal .
Sled

39

Você está certo - copiar e colar funciona muito bem e o DRY não faz sentido em que sua tarefa é produzir um programa para o qual o modelo copiado ou a cópia não precisarão ser mantidos ou evoluídos no futuro. Quando esses dois componentes de software têm um ciclo de vida completamente diferente, acoplá-los ao refatorar o código comum em uma lib comum que está em desenvolvimento pesado pode de fato ter efeitos imprevisíveis para o esforço. Por outro lado, ao copiar seções de código dentro de um programa ou sistema de programa, todas essas partes normalmente terão o mesmo ciclo de vida. Ilustrarei abaixo o que isso significa para DRY e gerenciamento de projetos.

Sério, existem muitos programas por aí: por exemplo, a indústria de jogos de computador produz muitos programas que precisam ser mantidos por um curto período de alguns meses ou um ano no máximo, e quando esse tempo termina, copiar e colar código antigo de um jogo anterior em que o período de manutenção é excedido, a base de código de um novo jogo é perfeitamente adequada e pode acelerar as coisas.

Infelizmente, o ciclo de vida da maioria dos programas com os quais tive que lidar nos últimos anos é muito diferente disso. 98% dos requisitos ou solicitações de correção de erros que me chegaram foram solicitações de alteraçãopara programas existentes. E sempre que você precisar alterar algo em um software existente, "gerenciamento de projetos" ou planejamento funcionará melhor quando seus esforços de teste e depuração forem muito baixos - o que não será o caso se você alterar algo em um só lugar, mas devido à cópia lógica de negócios bem planejada, você esquece facilmente que também precisa mudar uma dúzia de outros lugares na base de código. E mesmo que você consiga encontrar todos esses lugares, o tempo para alterá-los todos (e testar as alterações) provavelmente é muito maior, como se você tivesse apenas um lugar para trocar. Assim, mesmo você pode fazer uma estimativa precisa da mudança, tendo os custos uma dúzia de vezes mais altos do que o necessário, podendo facilmente colidir com o orçamento do projeto.

TLDR - sempre que você desenvolver um programa em que não haja necessidade ou responsabilidade pela correção de erros e manutenção do original ou da cópia, fique à vontade para copiar. Mas se você, sua equipe ou sua empresa for ou puder se tornar responsável, aplique DRY sempre que puder.

Exemplo

Como adendo, deixe-me explicar o que significa "correção e manutenção de bugs" e como isso leva a imprevisibilidade no planejamento, especialmente dentro de um produto, por um exemplo do mundo real. Eu realmente vi esse tipo de coisa acontecer na realidade, provavelmente não com 100 instâncias, mas os problemas podem começar quando você tem apenas uma instância duplicada.

A tarefa: criar 100 relatórios diferentes para um aplicativo, cada relatório parecendo muito semelhante, algumas diferenças de requisitos entre os relatórios, alguma lógica diferente, mas, no geral, poucas diferenças.

O desenvolvedor que obtém essa tarefa cria a primeira (digamos que leva três dias). Após algumas alterações ou pequenas correções de erros devido ao controle de qualidade e à inspeção do cliente, parece que está funcionando bem. Então ele começou a criar o próximo relatório copiando e colando a coisa toda, depois o próximo, e para cada novo relatório ele precisa de aproximadamente 1 dia em média. Muito previsível, à primeira vista ...

Agora, depois que os 100 relatórios estiverem "prontos", o programa será produzido de maneira real e ocorrerão alguns problemas que foram ignorados durante o controle de qualidade. Talvez haja problemas de desempenho, talvez os relatórios falhem regularmente, talvez outras coisas não funcionem conforme o esperado. Agora, quando o princípio DRY foi aplicado, 90% desses problemas poderiam ser resolvidos alterando a base de código em um único local. Mas, devido à abordagem de copiar e colar, o problema deve ser resolvido 100 vezes em vez de uma vez. E devido às alterações já aplicadas de um relatório para outro, o desenvolvedor não pode copiar e colar rapidamente a correção do primeiro relatório para o outro 99. Ele deve examinar todos os 100 relatórios, lê-los, traduzir a alteração para o modificado relatório, teste e talvez depure cada um individualmente. Para o PM, isso começa a ficar muito difícil - ele pode, naturalmente, dedicar um tempo para uma correção de erro "regular" (digamos, 3 horas) e multiplicar por 100, mas, na verdade, essa é provavelmente uma estimativa incorreta, algumas das correções podem ser mais fácil de fazer do que outros, outros podem ser mais difíceis. E mesmo que essa estimativa esteja correta, o custo da depuração 100 vezes mais alto do que era necessário custará muito dinheiro à empresa.

O mesmo acontecerá na próxima vez em que o cliente solicitar a alteração da cor do emblema da empresa em todos esses relatórios, para tornar o tamanho da página configurável ou por algum outro novo requisito que afete todos os relatórios de maneira semelhante. Portanto, se isso acontecer, você pode fazer uma estimativa dos custos e cobrar do cliente 100 vezes o preço que ele teria que pagar quando o código estivesse SECO. No entanto, tente isso algumas vezes e, em seguida, o cliente cancelará o projeto porque provavelmente não estará disposto a pagar seus custos exorbitantes de desenvolvimento. E talvez nesse momento alguém faça a pergunta por que isso aconteceu e aponte com o dedo a pessoa que tomou a decisão para esta programação de copiar e colar.

O que quero dizer é: quando você produz software para terceiros, sempre tem pelo menos por um curto período de tempo a responsabilidade de fazer a coisa funcionar, corrigir bugs, adaptar o programa às mudanças de requisitos etc. Mesmo em um projeto de campo verde, essas as peças podem adicionar rapidamente muito mais do que o esforço de desenvolvimento planejado inicialmente. E especialmente quando todo o seu código copiado e colado está dentro de um produto, o período de responsabilidade é o mesmo para todas as partes, o que é bastante diferente da situação em que você copiou um código antigo de um projeto morto que não é mais sob manutenção ativa.


4
Provavelmente uma boa resposta, mas muito detalhada em comparação com outras boas respostas.
Vince O'Sullivan

4
Você pode ignorar o DRY quando "a cópia não precisar ser mantida ou evoluída no futuro", mas o código que nunca será usado novamente muitas vezes acaba sendo usado novamente de qualquer maneira.
Andy Lester

"copiar e colar funciona muito bem ..." - discordo! Mesmo que o programa seja único e com garantia de nunca evoluir além da versão inicial, o código copiar e colar ainda torna muito mais trabalhoso e arriscado corrigir os erros encontrados durante o desenvolvimento da versão inicial do programa. A menos que você nunca cometa erros, nesse caso você é um Deus.
precisa saber é o seguinte

11
@ JacquesB: você deve ler minha resposta com mais cuidado, eu não escrevi algo diferente.
Doc Brown

A programação de computadores é apenas diferente de construir máquinas idênticas com uma linha de montagem. Hã. Quem teria pensado nisso? Talvez devêssemos ter programadores trabalhando como PMs. Mas então precisaríamos de programadores como gerentes. Programadores como acionistas. Programadores como clientes ... Atire, apenas ensine a todos como programar e pronto. (Em outras palavras: não especialistas nunca vai entender as vicissitudes conhecidas por especialistas.)

19

Portanto, do ponto de vista do gerenciamento de projetos, é ótimo resolver uma tarefa, copiando algum código existente 100 vezes e fazendo algumas pequenas adaptações em cada cópia, conforme necessário. Em todo o momento, você sabe exatamente quanto trabalho fez e quanto resta. Todos os gerentes vão amar você.

Sua afirmação básica está incorreta.

O que diferencia o software de outras profissões é que você está criando algo novo todos os dias. Afinal, nenhum cliente pagará para você construir algo que outra pessoa já fez. Os gerentes de projeto podem gostar de previsibilidade, mas seus chefes gostam de valor . Se você é apenas copiar e colar código com pequenas variações, não está fornecendo muito valor para a empresa.

Eventualmente, a empresa perceberá que pode fazer o mesmo trabalho em uma fração do tempo contratando um bom programador. E se não o fizerem, seus concorrentes o farão.


2
Eu diria que a maioria das profissões de engenharia é sobre "fazer algo novo todos os dias"
BlueRaja - Danny Pflughoeft 16/08/16

12
@ BlueRaja-DannyPflughoeft: Na verdade não. Tendo trabalhado como engenheiro eletrônico / elétrico, posso testemunhar que a maioria das profissões de engenharia de grande escala (aqueles projetos que exigem comissionamento, como construir navios e usinas) é sobre garantir que as pessoas que fazem algo testado e testado o façam corretamente. É isso que os negócios consideram "engenharia". Fazer algo novo é "P&D"
slebetman 17/08/16

3
@slebetman Talvez você não tenha notado todo o trabalho que sua gerência estava fazendo; mesmo quando você está fazendo a mesma coisa repetidamente, o ambiente muda toda vez - você não tem um modelo de usina que pode ser entregue a um cliente e pronto, é necessário realizar pesquisas, descobrir como abastecer a fábrica com matérias-primas e transportar o produto de volta, gerenciar todas as matérias-primas para a construção e lidar com problemas de suprimentos e escassez de trabalho e um milhão de outras coisas. Ele parece como o trabalho de modelo (como muitos esforços de software fazem), mas realmente não é.
Luaan 17/08/16

11
@Luaan: Sim, mas nada disso está fazendo algo novo. Todos eles estão "fazendo algo que sabemos fazer". O desenvolvimento de software é diferente. Principalmente porque no software, diferentemente dos projetos de engenharia física, tendemos a encapsular o que já sabemos fazer nas bibliotecas, para que não tenhamos que "fazer a pesquisa" manualmente etc. Apenas importamos uma biblioteca para isso e a usamos .
Slebetman 17/08/16

2
@slebetman Quase todo o software que está sendo escrito é "algo que sabemos fazer". As bibliotecas também vivem em um ambiente que sempre muda. E você não tem 100% de conhecimento e experiência com toda a biblioteca, e todas as dependências dessa biblioteca e de outras dependências, e existem muitas configurações estranhas de sistemas e hardware que simplesmente se recusam a funcionar da maneira que um sistema razoável deve trabalhos. O encapsulamento é ótimo, mas ainda é caro como o inferno e precisa de toneladas de pesquisas. E engenharia tem encapsulamento também - blocos pré-fabricados, ICs etc.
Luaan

12

A programação recortar e colar eventualmente leva ao software abandonado. Eu era um contratado em um sistema para solicitar serviços de telefonia fixa de uma companhia telefônica muito grande. O sistema foi recortado e colado ad nauseum porque todos os testes eram manuais e eles não queriam alterar nenhum código de trabalho. O menor aprimoramento pode resultar em uma nova cópia de centenas de linhas de código. Originalmente, o aplicativo foi escrito para lidar com contas de até doze linhas físicas. Obviamente, essa limitação foi feita em centenas de locais no código. Após cerca de quatro anos, os negócios perguntaram à equipe o que seria necessário para lidar com contas maiores. Eles estimaram cerca de US $ 18 milhões. Nesse ponto, o projeto foi entregue a uma equipe offshore para manutenção mínima. A equipe existente foi demitida.

Organizações que pensam assim estão sendo esmagadas por empresas com melhor tecnologia.


Ele pensa que é melhor cérebro, em vez de melhor tecnologia. A tecnologia vem do cérebro, certo? O que aconteceu com "Pense mais esperto, não mais"?

10

Uma máxima frequentemente esquecida que se aplica aqui é a regra de 3 . Ele afirma que não há problema em copiar o código uma vez, mas além disso deve ser substituído pelo código genérico.

3 pode parecer um número arbitrário, mas um cenário comum é onde dados e lógica são duplicados em um aplicativo e banco de dados. Um exemplo frequentemente citado é o local em que há uma tabela de pesquisa no banco de dados e um lado do cliente de enumeração. A diferença de paradigmas não permite que isso seja prontamente armazenado em um único local e, portanto, as informações geralmente aparecem nos dois locais.

Embora seja bom ter código DRY, pode haver momentos em que a lógica de negócios dita uma exceção e, portanto, você deve criar dois ou mais bits de código a partir da fonte que era genérica antes.

Então o que fazer? Código para o status quo (afinal, YAGNI ). Embora o código deva ser escrito para facilitar a modificação, escrever uma série de sinos e assobios para algo que pode não ser necessário é apenas incendiar o dinheiro.


6
Observe que isso significa que você deve comentar que copiou o código (nos dois lugares) para saber se está prestes a copiá-lo novamente, não deve!
Mark Hurd

3
Fiz isso em um caso em que duas classes precisavam do mesmo método, mas eram pouco relacionadas - como primos distantes. Eu teria que adicionar dependências a quase uma dúzia de classes para que elas realmente compartilhassem o código. Então, gostei do que Mark sugeriu - copiou e colou o método e também deixou um comentário grande e óbvio, que apontou o outro local para esse método.
Jeutnarg 17/08/16

@MarkHurd Yep - great point ...
Robbie Dee

8

Na sua pergunta, você lista apenas três funções do gerenciamento de projetos - estimativa, cronograma e controle. O gerenciamento de projetos visa atingir metas dentro das restrições do projeto. Os métodos usados ​​para atingir objetivos dentro das restrições de um projeto são diferentes para projetos de software que muitos outros tipos de projetos. Por exemplo, você deseja que os processos de fabricação sejam altamente repetíveis e bem compreendidos. No entanto, o desenvolvimento de software é principalmente trabalho de conhecimento- não é rotineiro e requer pensar, em vez de seguir instruções e procedimentos rígidos. As técnicas usadas para iniciar, planejar, executar, monitorar e controlar e fechar um projeto de software precisarão levar em consideração o tipo de trabalho que precisa ser feito em um projeto de software - especificamente, trabalho não rotineiro que não pode ser realizado instruções e procedimentos específicos.

Acho que o outro problema é que você está usando o DRY, um conceito relacionado à repetição de informações, e tentando aplicá-lo ao gerenciamento de tarefas. DRY simplesmente diz que você deve ter apenas uma representação autorizada de informações. Os gerentes de projeto devem estar adotando isso, pois significa que todos saberão para onde buscar as informações, a comunicação de mudanças será fácil e as mudanças poderão ser controladas e gerenciadas bem. O DRY, através de peças reutilizáveis, ajuda a manter baixos os custos a longo prazo, ajuda a manter cronogramas a longo prazo e a melhorar a qualidade - três peças para o Triângulo de Gerenciamento de Projetos . É preciso haver algum investimento de tempo e dinheiro gasto para efetivamente tornar as coisas SECA, mas o trabalho do gerente de projeto é compensar tempo, custo, cronograma e qualidade.


Certamente, desenvolvimento de software é trabalho de conhecimento. Na verdade, eu nem consideraria meu primeiro exemplo (copiar / colar) um desenvolvimento de software em sentido estrito. Ainda assim, gerenciar esse tipo de trabalho é muito mais difícil; portanto, o gerente de projetos, mesmo que tenha experiência em desenvolvimento e saiba tudo isso, em seu papel de gerente de equipe, ele tende a ignorá-lo. (Eu não digo que isso é uma coisa boa, é exatamente o que eu observei muitas vezes. Também não acho que esses PMs sejam estúpidos ou incompetentes. É mais como o papel às vezes os força a agir dessa maneira. )
Frank soprador

3
@FrankPuffer Não concordo que o papel de gerente de projetos force a pessoa a tomar decisões específicas. É mais provável que seja uma força educacional ou organizacional. Pelo que vi, a maior parte da educação em gerenciamento de projetos se concentra nas técnicas mais tradicionais de gerenciamento de projetos (provavelmente porque são mais aplicáveis ​​a mais projetos) do que nas técnicas de gerenciamento de projetos de software. Isso pode ocorrer em organizações que esperam isso e não procuram outras técnicas para gerenciar projetos de trabalho com conhecimento, como desenvolvimento de software.
Thomas Owens

2
@FrankPuffer Claro que é mais difícil, mas oferece mais valor. Se o chefe do seu chefe for inteligente o suficiente, ele se livrará do gerente que tenta "facilitar as coisas para si" e encontrará alguém que possa realmente fazer seu trabalho. Não me interpretem mal, se tornar as coisas mais fáceis agrega valor, vá em frente - mas no que você descreve, isso é quase certamente em detrimento do valor final.
Luaan 17/08/16

4

Escrever novo código é apenas uma pequena parte da tarefa

Sua sugestão facilitaria a estimativa da parte da escrita inicial do novo código. No entanto, para realmente trazer algo novo (não importa se é um sistema totalmente novo, uma adição de recurso ou uma alteração de funcionalidade), isso não é suficiente e é apenas uma minoria de trabalho - as estimativas vistas na literatura dizem que, na prática, parte é algo como 20% -40% do trabalho total.

Portanto, a maior parte do trabalho (que inclui a adaptação do seu desenvolvimento inicial ao que realmente era necessário, integração, teste, reescrita e re-teste) não fica mais fácil de estimar; ao contrário, evitar intencionalmente o DRY apenas tornou essa parte muito maior, mais difícil e com estimativas mais variáveis ​​- esse bug ou necessidade de mudança que requer a alteração de todas as partes clonadas pode não acontecer, mas se acontecer, suas estimativas vai estar totalmente errado.

Você não obtém melhores estimativas melhorando sua qualidade de estimativa de uma pequena parte do trabalho, mas piorando em grande parte do trabalho; portanto, não é realmente uma troca, mas uma situação de perda e perda em que você obtém uma produtividade pior, mas também estimativas piores.


Este é um bom ponto. No entanto, os princípios DRY ou similares também se aplicam a outras tarefas, como teste ou integração. A maioria das coisas pode ser feita de maneira mecânica, sem muito pensamento ou de maneiras mais inteligentes. As soluções inteligentes costumam ser muito mais rápidas, mas envolvem um risco de falha. Além disso, você precisa colocar uma quantidade considerável de trabalho neles antes de obter qualquer resultado.
Frank soprador

Não há "risco de falha", há uma certeza de falha. Tudo falhará mais cedo ou mais tarde. Você está apenas escolhendo o quanto o carro fúnebre é caro e a velocidade com que dirige.

4

O DRY é útil, mas também é superestimado. Algumas pessoas podem levar isso muito longe. O que muitos desenvolvedores não conseguem perceber é que sempre que você implementa o DRY para usar o mesmo método para duas finalidades (ligeiramente) diferentes, você está introduzindo um tipo de acoplamento muito rígido entre os diferentes usos. Agora, toda vez que você altera o código para o primeiro caso de uso, também é necessário verificar se ele regride o segundo caso de uso. Se esses são casos de uso amplamente independentes, é muito questionável se eles devem ser fortemente acoplados - provavelmente não deveriam ser.

O uso excessivo de DRY também pode levar a métodos de Deus que explodem em complexidade para lidar com todos os diferentes casos de uso em que são colocados, quando métodos atômicos geralmente menores que replicam algum código seriam muito mais sustentáveis.

No entanto, eu sugeriria que a pergunta não é realmente relevante no nível de gerenciamento de projetos. Um gerente de projeto realmente não vai querer se preocupar com esse nível de detalhe da implementação. Se são, provavelmente é microgerenciamento. Realmente ... como as coisas são implementadas é mais responsabilidade do desenvolvedor e líder técnico. O gerenciamento de projetos está mais preocupado com o que é feito e quando .

EDIT: por comentário, eu concordo no entanto que, na medida em que facilita a estimativa do tempo de desenvolvimento, evitar o DRY às vezes pode reduzir a quantidade de incerteza. Mas acredito que essa é uma questão insignificante em relação às questões mais prementes de (1) quanto tempo até que os requisitos de negócios sejam atendidos, (2) qual dívida técnica é levada em conta no processo e (3) riscos para o custo total de a propriedade das escolhas arquitetônicas feitas - ficar seco ou não em muitos casos é uma escolha de design que deve se basear mais em risco / recompensa a esses fatores do que em tornar um pouco mais fácil fornecer aos gerentes de projeto informações mais precisas .


Obviamente, o gerente de projetos não deve lidar com os detalhes da implementação. Esse não é o meu ponto. O que quero dizer é que, dependendo da maneira como um desenvolvedor implementa algo, ele é mais ou menos capaz de fornecer as informações necessárias para o gerenciamento de projetos.
Frank soprador

Não faz sentido para mim danificar / restringir o produto ou aumentar a dívida técnica simplesmente para poder relatá-lo melhor. O valor do relatório certamente deve ser de magnitude inferior ao valor do trabalho de qualidade. Mas YMMV
Brad Thomas

Talvez os programadores devam receber ordens de magnitude superiores aos gerentes?

2

Eu acho que você está entendendo mal DRY.

Vamos usar um exemplo:

public Class A
{
    public int Multiply(int x, int y)
    {
        return x * y;
    }
}

public Class B
{
    public int Multiply(int x, int y)
    {
        return x * y;
    }

    public int Add(int x, int y)
    {
        return x + y;
    }
}

vs.

public Class C : A
{
    public int Add(int x, int y)
    {
        return x + y;
    }
}

Substituindo a classe B por C, seguimos o princípio DRY e reduzimos a duplicação de código. Mas não aumentamos as incógnitas ou os riscos para o projeto (a menos que você nunca tenha herdado antes).

Acho que o que você quer dizer quando fala sobre DRY é algo mais parecido com uma tarefa de design. Ou seja:

public Class A
{
    public int Multiply(int x, int y)
    {
        return x * y;
    }
}

!!! Nova exigência! Alguns clientes precisam ser capazes de multiplicar duplos !!

// Use class B for new clients!!
public Class B
{
    public int Multiply(double x, double y)
    {
        return x * y;
    }
}

vs.

public Class A // Version 2
{
    public int Multiply(int x, int y)
    {
        return Multiply(x as double, y as double);
    }

    public int Multiply(double x, double y)
    {
        return x * y;
    }
}

Aqui (supondo que funcione), projetamos uma solução que pode lidar tanto com o antigo quanto com o novo requisito, essencialmente tentando criar um modelo matemático do problema da vida real ou das regras de negócios. Na vida real, o sistema que estamos modelando será obviamente muito mais complicado, nosso modelo não se encaixará exatamente e os casos extremos e resultados inesperados levarão tempo para encontrar e corrigir.

Então, devemos usar a versão B ou A 2 neste caso?

  • B será mais específico para a alteração real solicitada com menos efeitos colaterais e será mais fácil de estimar e mais rápido.

  • Uma versão 2 resultará em menos código geral no futuro e será a solução mais elegante

Mais uma vez, vou dizer que tudo se resume à qualidade da especificação e dos requisitos.

Se tivermos especificações muito claras que abrangem os casos extremos e a compatibilidade com versões anteriores, podemos ter certeza de que entendemos o sistema suficientemente bem para refatorar o modelo sem produzir bugs.

Se tivermos uma solicitação de emergência para um único cliente, onde o único requisito é que o comportamento mude para esse cliente sem considerar o sistema geral; depois 'aperfeiçoar' o modelo refatorando A traz um risco substancial. Tanto para quebrar outros clientes quanto para ultrapassar o prazo devido ao tempo extra desconhecido necessário para projetar e testar a solução.


7
Eu não concordo Herança não é algo que você faz uma vez e depois domina. Existem muitas armadilhas. Há razões pelas quais a composição deve ser preferida à herança. Então, temos que tomar uma decisão: herança? Composição? Algo mais? Essa decisão provavelmente será difícil no mundo real. No segundo exemplo, há também muitas alternativas. E os genéricos / modelos? Ou talvez alguma abordagem funcional usando lambdas? Novamente: Muitas possibilidades, cada uma das quais terá implicações específicas.
31816 Frank Puffer

4
O ponto é que, no primeiro exemplo, você literalmente remove código duplicado por qualquer método. mas o mesmo código é executado de qualquer maneira. Portanto, não há alteração de funcionalidade. No segundo exemplo, você alterar a abordagem a algo que você espera é functionaly eqivilant mas é actualy código diferente
Ewan

11
Eu estava em uma situação em que seu "pedido de emergência" era a norma. A empresa em que trabalhei criou sistemas de dados personalizados para muitos clientes diferentes. No início, eles criaram um sistema com a Cobol e depois o copiaram para o próximo cliente, etc., até que tivessem 100 clientes. Agora eles tinham um trabalho em suas mãos tentando fazer melhorias e atualizações sistemáticas. Eu estava trabalhando em um sistema que poderia replicar o comportamento da maioria desses sistemas, usando um único conjunto de código-fonte, mas personalizações armazenadas nos dados de configuração. Não podíamos fazer tudo, e algumas coisas não puderam ser adicionadas.

1

Parágrafo por parágrafo

Um dos princípios mais básicos e amplamente aceitos do desenvolvimento de software é o DRY (não se repita). Também está claro que a maioria dos projetos de software requer algum tipo de gerenciamento.

Corrigir.

Agora, quais são as tarefas fáceis de gerenciar (estimativa, cronograma, controle)? Certo, tarefas repetitivas, exatamente as tarefas que devem ser evitadas de acordo com o DRY.

Tarefas repetitivas devem ser automatizadas, obrigatórias . Eles são chatos, propensos a erros, quando feitos à mão.

Portanto, do ponto de vista do gerenciamento de projetos, é ótimo resolver uma tarefa, copiando algum código existente 100 vezes e fazendo algumas pequenas adaptações em cada cópia, conforme necessário. Em todo o momento, você sabe exatamente quanto trabalho fez e quanto resta. Todos os gerentes vão amar você.

Eu acho que você pode mudar a palavra "adaptação" com "configuração". Considere que você tem um bug neste pedaço de código que deve ser copiado. Um erro que aparece sob condições específicas. Se não estiver corrigido na fonte original e for copiado, haverá muitos locais a serem corrigidos. Isso pode ser ruim, mas alguém precisa:

  • primeiro corrija o código na fonte original;
  • corrija o código em qualquer outro lugar;
  • certifique-se de que esses eram todos os lugares. Quando você diz que isso tinha que ser feito com o gerente, ele provavelmente odeia pelo menos alguém.

Se, em vez disso, você aplicar o princípio DRY e tentar encontrar uma abstração que elimine mais ou menos o código duplicado, as coisas serão diferentes. Geralmente existem muitas possibilidades, você precisa tomar decisões, pesquisar, ser criativo. Você pode encontrar uma solução melhor em menos tempo, mas também pode falhar. Na maioria das vezes, você não pode realmente dizer quanto trabalho resta. Você é o pior pesadelo de um gerente de projetos.

A remoção de duplicações leva ao ponto único de falha. Se algo falhar, você pode ter certeza de onde isso acontece. Os padrões SOLID e Design estão lá para ajudar a corrigir exatamente esse problema. Prazos muito curtos tendem a provocar um estilo processual de "codificação". Mais tempo investido em um projeto para criar algo reutilizável significa que deve haver uma quantidade mínima de tempo gasto no próximo projeto em que o recurso será reutilizado, mas deve ser configurável em primeiro lugar.

Claro que estou exagerando, mas obviamente há um dilema. Minhas perguntas são: Quais são os critérios para decidir se um desenvolvedor está exagerando no DRY? Como podemos encontrar um bom compromisso? Ou existe uma maneira de superar completamente esse dilema, não apenas encontrando um compromisso?

Muitas pessoas apontaram que não há dilema aqui. Sim e não.

Se você tem algo altamente experimental que nunca foi feito antes - não há dilema. Caso contrário, se você precisar fazer algo novamente, como o novo sistema de reservas, você já possui abstrações, depende apenas do que você precisa.

Eu acho que o dilema é - devemos implementar algo em um recurso, se é improvável que seja solicitado. Implemente algo quando solicitado. Ninguém precisa de uma infraestrutura enorme que não será usada.


Implemente algo da maneira mais simples e rápida agora, porque isso foi solicitado. Mais tarde, quando uma maneira complexa é necessária, o esforço original é por nada, tem que começar de novo. O gerente não gosta disso. Como se você dissesse: "O tempo gasto dirigindo para o oeste seria inútil se agora precisamos ir para o leste". Mas percorrer todo o mundo pela primeira vez, só para que pudéssemos ir para o leste o tempo todo também é perda de tempo.

1

não se trata de projetar para reutilização futura ou sobre o princípio YAGNI. Trata-se de repetir o código no pacote de trabalho atual.

É absolutamente sobre design. Talvez não reutilize por si só, mas mesmo assim projete.

Quais são os critérios para decidir se um desenvolvedor está exagerando no DRY?

Experiência e seu ambiente / situação existente. Para um determinado problema, você terá uma forte noção do Princípio do Prado ao tentar obter maiores graus de SECA. Então, de repente, as considerações de gerenciamento vêm à tona. Tempo, objetivos, cliente, gerenciamento de código de longo prazo (alguém disse dívida técnica ) etc. informarão seu plano de ataque.

Como podemos encontrar um bom compromisso?

Uh ... design? Refatorar é design, bem deveria ser. O escopo do DRYing pode se expandir facilmente como uma super nova do loop, para o método, para as classes. Estive lá, fiz isso. Mas você realmente não pode saber até estudar o problema - isso é design.

Como não pode ser um problema de design? Você deve considerar o problema mais amplamente do que o código duplicado imediato em questão. Esta é uma atividade de design, seja um código existente ou uma folha em branco; seja "método de extração" ou criando novas classes e módulos.

Epílogo

... a pergunta referida e suas respostas não cobrem o aspecto de gerenciamento de projetos.

Gerenciamento típico, ignorando o tempo de design. Idealmente, teríamos projetado a repetitividade supérflua redundante antes da codificação. Em vez disso, a gerência pensa que o desenvolvimento (e correções de bugs) é um único evento olímpico - codificação - quando na verdade é um decatlo. E medem 1/1000 de segundo porque pensam que é tudo analógico.

Se, em vez disso, você aplicar o princípio DRY e tentar encontrar uma abstração que elimine mais ou menos o código duplicado, as coisas serão diferentes.

Eu tive essa experiência: "Passei dois dias escrevendo esta linha (de um formulário da GUI) e duas horas escrevendo o restante do formulário". Quero dizer que dediquei tempo para identificar classes reutilizáveis ​​- DRY sendo um efeito colateral natural - a linha de formulário da GUI e com algumas outras. Uma vez depurados, eles eram usados, individualmente e em composição, em todo o formulário que agora codificava muito rápido e o teste era excepcionalmente rápido, apesar da complexidade da construção. E também passou por testes formais com uma taxa de erros incrivelmente baixa.

Na maioria das vezes, você não pode realmente dizer quanto trabalho resta. Você é o pior pesadelo de um gerente de projetos.

Eu também não sabia, mas acreditava que o esforço inicial de design valeria a pena. Todos dizemos isso, mas a gerência em particular não confia. A gerência pensaria que eu estava brincando. "Dois dias e você nem tem 2% do código ainda!"

Em um caso, mantivemos o controle quando a administração disse "você está gastando muito tempo em design, vá em frente". E colegas de trabalho dizendo "são muitas aulas". Bem, um subprojeto muito menos complexo deveria levar cerca de 1 mês (eu pensei que era bom palpite), mas levou 5 meses. Três meses disso foram testados / corrigidos porque era um POS. "Mas não tivemos tempo para projetar!". Eles realmente disseram isso.

Minhas perguntas são: Quais são os critérios para decidir se um desenvolvedor está exagerando no DRY? Como podemos encontrar um bom compromisso? Ou existe uma maneira de superar completamente esse dilema, não apenas encontrando um compromisso?

Mostre à gerência como ela funciona. Capture alguns dados. Compare com outro trabalho, especialmente o de seus colegas de trabalho que fazem o trabalho rápido e rápido. Essa pilha de falhas sempre parece perder a corrida, ficando paralisada nos testes e depois do lançamento, repetidas vezes para corrigir mais bugs.


"Meça com um micrômetro, marque com giz, corte com um machado."
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.