Conceito do Padrão Estratégia
Em aplicações empresariais, regras de negócio frequentemente exigem flexibilidade. Considere o cálculo de frete: diferentes transportadoras, destinos ou pesos podem gerar variações complexas. Implementar essas variações com condicionais encadeados leva a código frágil e difícil de manter. O padrão estratégia resolve isso ao encapsular algoritmos intercambiáveis, permitindo alterar o comportamento sem modificar o código do cliente.
Aplicação no Odoo: Lógica de Negócio Configurável
No Odoo, o padrão estratégia é implementado de forma adaptada, frequentemente através de sobrecarga de métodos e configurações dinâmicas. Abaixo, exploramos dois cenários comuns.
Caso 1: Cálculo de Disopnibilidade de Produto
No módulo de estoque, a quantidade disponível de um produto pode ser calculada de divresas formas. O contexto é o modelo product.product, e as estratégias definem como combinar estoque físico, previsões de entrada e saída, ou considerar estoques de segurança.
# Estratégia base (módulo stock)
class Product(models.Model):
_inherit = 'product.product'
def calculate_availability(self):
# Algoritmo padrão: combina estoque atual e movimentos previstos
base_data = self._get_base_availability_data()
for prod in self:
prod.available_qty = base_data[prod.id]['on_hand'] + base_data[prod.id]['incoming'] - base_data[prod.id]['outgoing']
# Estratégia personalizada (módulo custom_stock)
class ProductWithThreshold(models.Model):
_inherit = 'product.product'
safety_threshold = fields.Float('Limite de Segurança')
def calculate_availability(self):
# Primeiro, executa a estratégia original
super(ProductWithThreshold, self).calculate_availability()
# Ajusta o resultado com base na nova regra
for prod in self:
if prod.safety_threshold:
prod.available_qty -= prod.safety_threshold
A instalação de módulos atlernativos altera a estratégia usada transparentemente, mantendo a interface consistente.
Caso 2: Política de Faturamento em Pedidos de Venda
Em pedidos de venda (sale.order), a geração de faturas pode seguir regras distintas. O campo billing_policy determina o algoritmo a ser aplicado:
# Pseudocódigo simplificado da geração de faturas
def generate_invoice_for_order(order):
if order.billing_policy == 'delivery_based':
# Estratégia A: faturar apenas itens já entregues
invoice_lines = order._build_lines_for_delivered_items()
else: # order.billing_policy == 'order_based'
# Estratégia B: faturar o valor total do pedido
invoice_lines = order._build_lines_for_full_order()
return _create_invoice(invoice_lines)
Aqui, cada método auxiliar encapsula uma estratégia concreta, e o método principal atua como contexto, selecionando a estratégia com base na configuração.
Distinção com o Padrão de Cadeia de Responsabilidade
Embora ambos os padrões envolvam delegação, suas intenções diferem. A cadeia de responsabilidade enfatiza o processamento sequencial de uma requisição por múltiplos handlers, cada um contribuindo parcialmente. Já o padrão estratégia foca na seleção de um único algoritmo entre opções equivalentes para completar uma tarefa.
Benefícios e Quando Utilizar
O padrão estratégia elimina estruturas condicionais complexas, adere ao princípio aberto/fechado e promove reuso de algoritmos. No desenvolvimento Odoo, considere aplicá-lo quando:
- Uma operação de negócio possui múltiplas implementações que podem ser trocadas em tempo de execução.
- Novas implementações precisam ser adicionadas sem alterar o código cliente.
- É necessário desacoplar a lógica específica de algoritmos da funcionalidade principal.