O padrão de estratégia funciona bem para evitar enormes construções de if ... else e facilita a adição ou substituição de funcionalidades. No entanto, ainda deixa uma falha na minha opinião. Parece que em todas as implementações ainda precisa haver uma construção de ramificação. Pode ser uma fábrica ou um arquivo de dados. Como exemplo, considere um sistema de pedidos.
Fábrica:
// All of these classes implement OrderStrategy
switch (orderType) {
case NEW_ORDER: return new NewOrder();
case CANCELLATION: return new Cancellation();
case RETURN: return new Return();
}
O código depois disso não precisa se preocupar, e há apenas um lugar para adicionar um novo tipo de pedido agora, mas esta seção do código ainda não é extensível. Colocá-lo em um arquivo de dados ajuda a facilitar a leitura (discutível, eu sei):
<strategies>
<order type="NEW_ORDER">com.company.NewOrder</order>
<order type="CANCELLATION">com.company.Cancellation</order>
<order type="RETURN">com.company.Return</order>
</strategies>
Mas isso ainda adiciona código padrão para processar o código de dados concedido, mais facilmente testável por unidade e relativamente estável, mas com complexidade adicional.
Além disso, esse tipo de construção não faz um teste de integração bem. Cada estratégia individual pode ser mais fácil de testar agora, mas cada nova estratégia adicionada é uma complexidade adicional a ser testada. É menos do que você faria se não tivesse usado o padrão, mas ainda está lá.
Existe uma maneira de implementar o padrão de estratégia que mitiga essa complexidade? Ou isso é tão simples quanto parece, e tentar ir além adicionaria outra camada de abstração com pouco ou nenhum benefício?
eval
... pode não funcionar em Java, mas talvez em outras linguagens?