Os padrões de projetos nos ajudam estruturar nossos programas de maneiras mais flexíveis, fáceis de entender e manter. Através deles sistemas são construídos com boas qualidades de design orientado à objetos(OO). Eles nos fornecem soluções gerais para problemas de projeto. Esse artigo explica o padrão strategy mostrando seu uso e estrutura aplicada no contexto de um programa de relatório.

O padrão strategy pode ser utilizado na aplicação quando um determinado objeto especializado pode ter comportamentos diferentes para executar uma ação.

Para desacoplar o tipo de comportamento e permitir flexibilidade para modificar um determinado comportamento ou adicionar novos, a super classe (classe geral) delega essa responsabilidade para outra classe e compõe em seu atributo uma interface para representar um determinado comportamento que pode variar.

Para exemplificar, vamos considerar relatórios de departamentos diferentes de uma empresa: Contabilidade, Comercial e Recursos Humanos. Supondo que cada relatório pode utilizar uma impressora para realizar a impressão, temos a seguinte classificação:

Relatório é a classe abstrata para todos os outros relatórios (Contabilidade, Comercial e Recursos Humanos) enquanto Impressora é uma interface que todas as impressoras implementam. Assim, todos os relatórios e impressoras reais são classes concretas. Para trocar uma impressora, cada relatório de departamento chama o método setImpressora(), que é definida na super classe Relatório.

Código da classe Relatorio:

package com.programacao4devs.strategy.relatorio;

import com.programacao4devs.strategy.impressora.Impressora;

public abstract class Relatorio {

	// Interface Impressora
	protected Impressora impressora;
	
	public abstract void geraRelatorio();
	
	public void imprime() {
		this.impressora.imprime();
	}
	
	public void setImpressora(Impressora impressora) {
		this.impressora = impressora;
	}
}

Código da classe RelatorioContabil:

package com.programacao4devs.strategy.relatorio.impl;

import com.programacao4devs.strategy.impressora.impl.ImpressoraLaser;
import com.programacao4devs.strategy.relatorio.Relatorio;

public class RelatorioContabil extends Relatorio {

	
	public RelatorioContabil() {
		impressora = new ImpressoraLaser();
	}
	
	@Override
	public void geraRelatorio() {
		System.out.println("Gerando relatório de contabilidade ...");
	}

}

Código da interface Impressora:

package com.programacao4devs.strategy.impressora;

public interface Impressora {
	
	public void imprime();

}

Código da classe ImpressoraLaser:

package com.programacao4devs.strategy.impressora.impl;

import com.programacao4devs.strategy.impressora.Impressora;

public class ImpressoraLaser implements Impressora {

	@Override
	public void imprime() {
		System.out.println("Imprimindo relatório com a impressora Laser");
	}

}

Download do código completo em: https://github.com/programacao4devs/strategy

Os fundamentos de orientação a objetos utilizados no padrão strategy são:

  • Abstração;
  • Polimorfismo;
  • Herança.

Os princípios OO são:

  • Encapsule o que varia;
  • Dê prioridade à composição em relação à herança;
  • Programa para interface, não para implementação.

Inscreva-se!

Inscreva seu nome e email na Programacao4Devs para receber atualizações de novos artigos, tutoriais e dicas.

Paulo Henrique de Morais

Mestre em Ciências da Computação pela Universidade Federal de Santa Catarina e atua no mercado de programação desde 2015.