Strategy

Solução Proposta

Permite que um algoritmo varie independentemente dos clientes que o utilizam. As estratégias podem fornecer diferentes implementações do mesmo comportamento. 

Vantagens

Desvantagens

Exemplo

O processo de fabricação de carros exige a execução de etapas como produção da carroceria, pintura e montagem dos equipamentos, que resultam em um carro pronto para ser dirigido. Para certos tipos de carro,  algumas dessas etapas exigem implementações específicas: em modelos Hatch, a carroceria é dividia em dois volumes: um para o motor e um para os passageiros e porta-malas, enquanto em modelos Sedan a carroceria é dividida em três volumes: um para o motor, um para os passageiros e um para o porta-malas. Isso significa que uma mesma implementação é irreplicável para ambos os casos. Uma interface Assembler possui as assinaturas dos métodos que realizam a construção de um carro (buildCarBodyWork, paintCar e mountCarParts) enquanto as classes SedanCar e HatchCar implementam Assembler e definem as implementações das operações. Quando é necessário construir, por exemplo, um carro Sedan, a classe Car mantém uma referência para uma instância de SedanCar e dentro do método manufacture executa os métodos de construção.
 

Diagrama de Classe

Strategy - Diagrama

Participantes

  • Strategy (Assembler) Define uma interface comum para os possíveis algoritmos, sendo usado por Context para chamar o algoritmo definido em uma instância concreta.

  • ConcreteStrategy (SedanCar, HatchCar) Implementa os algoritmos definidos pela interface Strategy.

  • Context (Car) Mantém uma referência para um objeto Strategy.

Código

package strategy;

public class SedanCar implements Assembler {

    // Atributos de Car que serão modificados durante as etapas do algoritmo.
    private String color;
    private int bodyWorkVolumesNumber;
    private String engineType;
    private String tireType;
    private String starterMotorType;

    // Implementações específicas para cada etapa do algoritmo que constrói um carro Hatch
    public void buildCarBodyWork(){
        this.bodyWorkVolumesNumber = 3;
    }

    public void paintCar() {
        this.color = "black";
    }

    public void mountCarParts(){
        this.engineType = "W type";
        this.tireType = "Summer";
        this.starterMotorType = "Planetary Gear";
    }

    public String getCarInfo(){
        return "Number of bodywork volumes: " + this.bodyWorkVolumesNumber
             + "\nCar color: " + this.color
             + "\nEngine type: " + this.engineType
             + "\nTire type: " + this.tireType
             + "\nStarter motor type: " + this.starterMotorType;
    }

}
package strategy;

public class Client {
    public static void main(String[] args) {

        Car car = new Car();

        //Instancia uma classe para a execução de um algoritmo SedanCar e passa essa instância para a instância de Car.
        SedanCar sedanCar = new SedanCar();
        car.setCarAssembler(sedanCar);

        car.manufacture();
    
        System.out.println("Car info:");
        System.out.println(sedanCar.getCarInfo());
    }
}
package strategy;

public class Car {

    private Assembler carAssembler;

    //Método que executa as etapas de Strategy
    public void manufacture(){
        carAssembler.buildCarBodyWork();
        carAssembler.paintCar();
        carAssembler.mountCarParts();
    }

    public void setCarAssembler(Assembler carAssembler) {
        this.carAssembler = carAssembler;
    }
}
package strategy;

public interface Assembler {
    //Definição das operações abstratas executáveis pelo algoritmo
    public abstract void buildCarBodyWork();
    public  abstract void paintCar();
    public abstract void mountCarParts();
}
package strategy;

public class HatchCar implements Assembler {

    // Atributos de Car que serão modificados durante as etapas do algoritmo.
    private String color;
    private int bodyWorkVolumesNumber;
    private String engineType;
    private String tireType;
    private String starterMotorType;

    // Implementações específicas para cada etapa do algoritmo que constrói um carro Hatch
    public void buildCarBodyWork(){
        this.bodyWorkVolumesNumber = 2;
    }

    public void paintCar() {
        this.color = "blue";
    }

    public void mountCarParts(){
        this.engineType = "V type";
        this.tireType = "All Season";
        this.starterMotorType = "Direct Drive";
    }

    public String getCarInfo(){
        return "Number of bodywork volumes: " + this.bodyWorkVolumesNumber
             + "\nCar color: " + this.color
             + "\nEngine type: " + this.engineType
             + "\nTire type: " + this.tireType
             + "\nStarter motor type: " + this.starterMotorType;
    }
}
Clique aqui para fazer o download do código completo de implementação deste Design Pattern.

Padrões Relacionados