Como "Você não vai precisar" e "Agora é melhor do que nunca" tocam juntos?

17

Muitas vezes me vejo abraçando "agora é melhor do que nunca" quando estou avançando no DRYness de um design. Normalmente, acho que preciso cultivar uma compreensão do Local Autoritário Único para um pedaço de conhecimento no contexto de um sistema de outros pedaços de conhecimento. Assim, tendo a projetar o sistema 'agora'.

Por outro lado, essa prática me leva a construir com bastante antecedência, apesar de uma chance razoável de que não vou precisar.

Como esses dois padrões se encaixam?

Quais práticas você usa para garantir que elas sejam boas?

Como você os ensina juntos sem criar confusão?

Justin Myles Holmes
fonte
2
Olhe antes de pular. Mas quem hesita está perdido.
mmyers

Respostas:

26

Eu tento pensar muito à frente também, mas geralmente não no código. Faço um brainstorming e tomo notas, espero organizando as coisas bem o suficiente para que eu possa me referir a elas.

Eu me inclino mais para "você não vai precisar" com relação ao código, mas "agora é melhor do que nunca" com o design.

Ao começar a construir um novo sistema, é tentador querer construir tudo agora, mas também pode minar seu ímpeto e moral. Costumo pensar no design geral e tentar traçar uma linha direta através dele - criar uma arquitetura esquelética de ponta a ponta e construir essa primeira, aplicando princípios de design sólidos para que eu possa evoluí-la mais tarde e refatorá-la para trazer em novos recursos.

Crie a representação de ponta a ponta mais simples do sistema que possa funcionar; faça isso primeiro, e então você terá algo para refletir. Isso tende a ajudar a cristalizar todas as vagas perguntas do tipo "e se" e a ajudar a definir o que você precisa construir a seguir.

samplebias
fonte
3
Marcar com +1 um local para algo no design não significa que você precisa criar muito dele inicialmente. MUITAS pessoas tomam uma decisão absolutista de que nada deve ser considerado antes da solicitação e se deixam em uma situação muito pior do que se tivessem construído a coisa toda sem a contribuição do cliente.
Bill
9

YAGNI significa que as coisas são feitas quando precisam ser feitas e não antes. Isso não significa que eles nunca terminem, a menos que nunca sejam necessários. Isso significa que você só faz o que dá ao cliente valor comercial imediato . O que significa valor comercial imediato é subjetivo a todo cliente e todo projeto.

Em ambos os casos, você não pode perder nada com o YAGNI.

No outro caso, você perde tempo escrevendo código que nunca é usado e escrevendo testes para código que nunca é usado, e escrevendo documentação para código que nunca é usado e manutenção de código que nunca é usado, as pessoas se perguntando o que esse código faz. e, se alguma vez for usado, ad nauseum.

Exemplo

Se estou trabalhando em um protótipo / prova de conceito ou na versão 1.0 de um aplicativo, não preciso de um design para dimensionar o nível do Facebook. Inferno, não preciso de um design para escalar para o nível do Facebook, até começar a ver que tenho esse tipo de tráfego.

Você acha que Zuckerberg projetou a primeira versão do Facebook para atingir 500 milhões de usuários? Não, ele o projetou e construiu para fazer apenas o necessário e não mais. Se ele tivesse tentado alterar o design para 500 milhões de usuários desde o primeiro dia, o Facebook provavelmente nunca teria sido lançado.

A maneira prática de fazer as coisas é como ele fez isso. Ele começou com PHP e MySQL, e redesenhou e reescreveu, conforme necessário, com base no valor comercial , escalar para milhões de usuários era de enorme valor comercial, mas não no dia 0. No dia 0, apenas o lançamento de algo era um tremendo valor comercial.

Ele planejou redesenhar e reescrever. O que é uma mentalidade diferente do que o planejado para a pia da cozinha e nunca realmente desenvolve ou entrega algo útil que esteja completo.

Planejar no final da vida útil de uma base de código e reescrever é uma solução ágil e futura. Tentar chegar a um objetivo indefinido de "flexível" acaba sempre em fracasso. Você está projetando sem nenhuma necessidade e desperdiçando tempo, poderia estar desenvolvendo o que é de valor comercial, em vez de sonhar com recursos que nunca serão usados.


fonte
2
Se o seu design for ruim (por exemplo, inflexível), você poderá perder muito com o YAGNI.
precisa saber é o seguinte
1
@EricSchaefer - não se ele atingir os objetivos e agregar valor aos negócios e você não tiver muito tempo investido, você apenas desperdiçará menos que perderá o fornecimento de seu sistema mágico infinitamente flexível que nunca estará completo e será enviado e se o fizer, será um pesadelo de configuração.
6

A maneira Zen do Python diz:

Agora é melhor do que nunca. Embora nunca seja melhor do que agora.

A idéia é que não é porque você pode definir algo agora que deveria. Você precisa agora?

  • Sim: faça agora!
  • Não: não faça isso! Aguarde a necessidade! YAGNI!

Os casos em que isso é menos óbvio são em casos de refatoração. Devo aplicar DRY toda vez que posso? A resposta não é clara porque há momentos em que a aplicação de DRY custa mais (no tempo gasto) do que a duplicação. No entanto, a longo prazo, aplicar DRY até que você tenha razões técnicas / de desempenho nem sempre é bom.

Então, YAGNI até você, então faça-o agora. Não espere!

Klaim
fonte
3

Eu não acho que eles tocam juntos. Eu acho que você se inclina de um jeito ou de outro. E eu me inclino para YAGNI.

Mas, pelo que vale, não concordo com a segunda proposta: "Agora é melhor do que nunca". Se um requisito é importante, terá que ser realizado. Então "nunca" não é uma possibilidade. Se não é importante, então "agora" não é melhor - "nunca" é melhor.

Apenas meus dois centavos.

MJB
fonte
E agora a pergunta de um milhão de dólares: O que significa "importante"?
precisa saber é o seguinte
1
"Importante" significa que é um teste de aceitação.
Kindall
importante significa que o cliente grita quando não está lá.
Paul Nathan
2
Importante significa que o cliente não paga se não estiver lá.
Christopher Mahan
@Christopher, isso poderia ser interpretado como encorajador de não profissionalismo. Por exemplo, proteger contra injeção de SQL é importante, mesmo que o cliente não saiba o que é e certamente não o testará antes de pagar.
Peter Taylor
2

Como esses dois padrões se encaixam?

Eles são ortogonais e não têm nada a ver um com o outro.

Quais práticas você usa para garantir que elas sejam boas?

Hum. Os dois? O que mais pode haver?

Como você os ensina juntos sem criar confusão?

YAGNI descreve os recursos como vistos pelos usuários. Você não precisa de fantasia.

Agora é melhor do que nunca descreve o processo. Escreva testes agora. Escreva o código agora. Não perca o tempo pensando em alternativas de design. Construa algo em vez de falar sobre construir algo.

S.Lott
fonte
2

Se "nunca" é a implicação de "agora não", seu design é defeituoso.

As decisões locais que você toma devem ser transparentes para o resto de um sistema.
Por exemplo, se você tiver um componente CookieSourceque exija CookieFactorya CookieRecipesconversão Cookies, com base em alguns parâmetros de entrada, CookieSourcenão precisa e, portanto, não deve depender de como CookieFactoryé implementado e como CookieRecipesé representado.
Se o CookieFactoryé de fato um Bakery, isso pode levar a um Recipeacordo Pastry, não importa. E, a menos que você precise dessa funcionalidade, não há necessidade de implementá-la. E não há nenhuma razão no mundo para que você não possa adicioná-lo posteriormente, exceto se não houver uma barreira clara de abstração entre CookieSourcee os serviços que ele usa.

Ao criar um software, adicione funcionalidade conforme necessário e tente não se prender a nenhuma decisão tomada. Em vez disso, bloqueie a decisão em uma abstração adequada .

back2dos
fonte
1

A solução mais simples que encontrei é esperar alterações ao escrever código antecipadamente. Quando estou passando algum bool para uma função, normalmente o altero o mais rápido possível para um sinalizador / enumerações, para que fique a) mais legível eb) fácil de estender. Da mesma forma, se eu perceber que estou passando vários parâmetros em torno de onde cheira como se eu precisasse de mais um, normalmente crio uma estrutura especial. A esperança é que YAGNI, mas se você o fizer em algum momento, ele não quebrará todos os usuários de maneira horrível imediatamente e o "trabalho pesado" já está feito. Freqüentemente, você também pode adicionar algum comentário como / * adições futuras podem ser acessadas aqui * / ou então é claro que ainda não foi implementado, mas aqui é o lugar para adicioná-lo. Isso geralmente ajuda mais, pois achei que a refatoração de interface mais tarde consumia mais tempo.

Anteru
fonte
Gosto dessa filosofia em princípio, mas, na prática, acho que as migrações são dolorosas o suficiente para me fazer pensar duas vezes. Você já achou que a migração de seus modelos atrapalha a expectativa de mudanças?
23711 Justin Myles Holmes
O lado bom dessa abordagem é que as mudanças são menos dolorosas; ainda há muito trabalho envolvido. Eu não tenho certeza do que você quer dizer com a migração de modelos - Estou definitivamente no lado do YAGNI, mas preparar para o pior :)
Anteru
0

Projete com futuras extensões em mente, mas não as implemente até que você precise delas.

O exemplo que vem à mente é que, quando o Netflix foi iniciado, você só podia ter uma fila associada a cada conta. Mais tarde, eles invadiram o suporte para várias filas. Como não foi projetado dessa maneira desde o início, tornou-se cada vez mais difícil de manter, então eles decidiram interromper esse recurso. Depois de um tumulto do cliente, eles morderam a bala e fizeram um redesenho para integrar corretamente várias filas.

Se alguém no início tivesse permitido a possibilidade de querer várias filas mais tarde, poderia ter poupado muita dor de longo prazo por muito pouco esforço adicional de curto prazo. Eles não precisaram realmente implementar várias filas imediatamente, apenas certifique-se de que, se alguma vez o fizessem, não seria necessário uma reescrita maciça ou um hack impossível de manter.

Aparentemente, parece que seria necessário uma habilidade parecida com o adivinho para prever requisitos futuros, mas, na prática, coisas desse tipo tendem a se destacar em um bom programador quando ele percebe que está codificando alguma coisa ou que uma tabela de banco de dados está coletando muitas colunas apenas vagamente relacionadas.

Karl Bielefeldt
fonte