Acho que tem um detalhe que vc não entendeu: usar if é uma das formas de implementar esses patterns. Um design pattern só descreve de forma geral (teórica, genérica) o que é pra fazer. Mas como isso será feito fica a cargo de quem for implementar. Vc pode fazer com if, switch, polimorfismo, ponteiro de função ou seja lá o que for que a linguagem que está usando disponibiliza.

Isso não faz o menor sentido. Design patterns é, e sempre será sobre orientação a objetos. Só porque eu uso if/switch não significa que estou usando o design pattern.

E daí? E se eu estiver usando uma linguagem que não é orientada a objetos? No link que indiquei, ao final, tem vários links para artigos com implementações dos patterns em C (o exemplo acima foi adaptado deste).

Ele apenas demonstra como "implementar" o pattern em C, não que usar if/switch é o design pattern. Não é só porque dá para "implementar" em C que significa que seja algo universal.

Se eu usar if/switch, cada alteração nas categorias implica em ter que revisar o código de todas essas funções.

Você está 'otimizando' para um cenário absurdo, em que terá trocentas funções. Além disso você superestima o esforço gasto pra adicionar uma nova categoria na versão com if/switch.

Já se usar o segundo código, eu não preciso alterar as funções calcularPreco e maximoParcelas (e nem todas as outras trocentas funções que mencionei).

Mas se precisar adicionar uma função calcularFrete(categoria) em que cada categoria tem um cálculo de frete diferente, você vai precisar alterar em todas as classes. E no caso do if/switch, é só adicionar a nova função de frete.

Design patterns é, e sempre será sobre orientação a objetos

Não é, tanto que em outro comentário indiquei este link: Non-OOP Design Patterns?. E novamente eu destaco o primeiro comentário que tem lá:

I think the biggest disservice the popular design pattern books did was create a whole slew of people that believed the patterns only apply to object oriented languages.

Em tradução livre (com ênfase minha):

Acho que o maior desserviço dos livros que popularizaram os design patterns foi que eles fizeram uma quantidade enorme de pessoas acreditarem que os patterns só se aplicam a linguagens orientadas a objeto.

Que parece ser exatamente o que está acontecendo aqui :-)

E pra quem negativou, sugiro dar uma olhada também aqui e aqui pra entender que design pattern não é sobre orientação a objeto.


Quanto ao restante, é sempre um trade-off que deve ser avaliado caso a caso. Se o sistema for relativamente simples, não justifica a complexidade de ter classes e toda aquela parafernalha, por exemplo.

Tanto que há muitos que defendem - e eu concordo - que as vantagens da orientação a objeto só aparecem em projetos complexos, com bases de código bem grandes. Se não é o seu caso, se acha que não precisa, então não use. Eu já precisei refatorar um código que começou simples (if/switch atendia bem), mas foi ficando complexo e viu-se vantagem em mudar pra algo como o exemplo acima (a manutenção nos anos seguintes ficou bem mais fácil).

Mas se precisar adicionar uma função calcularFrete(categoria) em que cada categoria tem um cálculo de frete diferente, você vai precisar alterar em todas as classes. E no caso do if/switch, é só adicionar a nova função de frete.

Não necessariamente. Por exemplo, se o frete só é diferenciado pra categoria ouro, e pro resto é igual, eu só preciso criar na classe base (com o valor padrão) e na classe ouro (com o valor diferente).

E mesmo que tenha que adicionar em todas as classes, será feito apenas uma vez. Depois, se o frete mudar para alguma categoria, ou se eu criar uma categoria nova ou remover uma existente, não preciso mais mexer na função (se fosse com if, eu teria que mexer sempre nela).

Mas como já disse, cada caso é um caso. Se as regras não mudam tanto assim, aí tanto faz. Ninguém disse que é obrigatório usar DP. Mas eles podem ser úteis se souber quando e como usar.