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.