Strategy: diferenças entre revisões

Conteúdo apagado Conteúdo adicionado
PauloSJR (discussão | contribs)
Reversão. Trechos copiados de [di.uern.br/sebastiao/wp-content/uploads/2010/04/Strategy.pdf]
Linha 1:
'''Strategy''' é um [[Padrões de projeto de software|padrão de projeto de software]] (do [[língua inglesa|inglês]] ''design pattern''). O objetivo é representar uma operação a ser realizada sobre os elementos de uma estrutura de [[objeto|objetos]]. O padrão [[Strategy]] permite definir novas operações sem alterar as classes dos elementos sobre os quais opera. Definir uma família de [[algoritmo]]s e encapsular cada algoritmo como uma [[classe (programação)|classe]], permitindo assim que elas possam ter trocados entre si. Este padrão permite que o algoritmo possa variar independentemente dos clientes que o utilizam.
 
== IntroduçãoAplicação ==
PadrãoUtilizar deo Projetopadrão Strategy - Design Pattern Strategyquando:
 
•um objeto deve ser parametrizado com um de vários algoritmos, os quais podem ser encapsulados e representados por uma única [[interface]].
Padrão de projeto strategy foi descoberto ao tentar resolver problema em que encontramos um algoritmo comum (que definimos com comportamento) à muitas classes, mas que tem variadas implementações, se este problema fosse em uma herança em que os herdeiros sobrescrevem o algoritmo, teríamos o problema de ter que rescrever o código, mesmo se tivermos herdeiros que utilizem o mesmo algoritmo, se este algoritmo for diferente do que foi herdado.
Outra solução para este problema seria então criar uma função contendo condicionais que por determinado valor executariam a solução, porém estes métodos não são nada práticos, ferem o conceito de orientado a objeto e tornam o código mais complexo. Se o problema se repetir com um novo algoritmo teríamos o mesmo problema, além de que, se escolhermos a solução de sobrescrever ela só poderá ser feita em tempo de design. Com o padrão strategy verifica-se o algoritmo que se torna variável, classifica-o como comportamento e cria-se uma classe para cada variação deste algoritmo e então o agregamos ao objeto, por meio de ''[[Composição de objetos]]'', e usamos ''[[Polimorfismo]]''s através de interface tornando os comportamentos dos objetos dinâmicos (eles podem ser mudados em tempo de execução do aplicativo).
 
{{esboço-programação}}
== Strategy ==
Os textos da sessão Strategy foi retirado de: <ref>http://www.deinf.ufma.br/~vidal/Topicos/strategy.pdf</ref>.
=== Classificação: ===
# Propósito: Comportamental
# Escopo: Objetos
=== Intenção: ===
* define uma família de algoritmos, encapsula cada algoritmo e os torna intercambiáveis, permitindo que o algoritmo varie independente dos clientes que o utilizam.
=== Motivação: ===
* clientes que necessitam de diferentes algoritmos se tornam mais complexos se os incluírem em seu código;
* diferentes algoritmos são adequados em diferentes situações na resolução de um mesmo problema;
=== Aplicabilidade: ===
* muitas classes relacionadas diferem somente no seu comportamento;
* você necessita de variantes de um algoritmo;
* um algoritmo usa dados sobre os quais o cliente não precisa ter conhecimento;
* comandos condicionais relacionados para escolher entre muitos comportamentos de uma classe podem ser movidos para sua própria classe Strategy
=== Estrutura: ===
[[imagem:Strategy-structure.jpg |estilo|alinhamento|dimensão|Estrura básica do padrão Strategy]]
 
Segue um exemplo em [[Java (linguagem de programação)|Java]] onde o valor de comissão difere de acordo com o cargo do funcionario.
<ref>http://waltercunha.com/blog/index.php/2009/07/11/padroes-de-projeto-parte-3-de-3/</ref>.
 
 
=== Participantes: ===
====Strategy:====
*define uma interface comum para todos os algoritmos suportados;
====ConcreteStrategy: ====
*implementa o algoritmo usando a interface de Strategy;
==== Context: ====
* é configurado com um objeto ConcreteStrategy;
* mantém uma referência para um objeto Strategy;
* pode definir uma interface que permite a Strategy acessar seus dados.
 
=== Colaborações: ===
* Strategy e Context interagem para implementar o algoritmo escolhido;
* os clientes usualmente criam e passam um objeto ConcreteStrategy para o contexto e passam a interagir diretamente com o contexto;
 
=== Consequências: ===
* famílias de algoritmos relacionados;
* uma alternativa ao uso de subclasses;
* estratégias eliminam comandos condicionais da linguagem de programação;
* possibilidade de escolha de implementações;
* os clientes devem conhecer diferentes estratégias;
* custo de comunicação entre Strategy e Context;
* aumento do número de objetos.
 
=== Implementação (aspectos) ===
* definindo as interfaces de Strategy e Context;
* estratégias e parâmetros template;
* tornando os objetos Strategy opcionais.
 
 
== Estrutura de Diagrama de Classe do Codigo Fonte: ==
[[imagem:Strategy.png |estilo|alinhamento|600px|Estrura básica do padrão Strategy]]
 
== Exemplo de Código Fonte ==
 
Segue um exemplo em [[Java (linguagem de programação)|Java]] onde temos uma classe DUCK ao qual temos suas variações, e para cada variação temos um novo algortimo (comportamento) Fly() e Quack(), assim utilizamos o padrão strategy para criar dois comportamentos FlyBehavior e QuackBehavior e o mudamos de acordo com a necessidade.
 
 
 
=== Explicação Classe Duck: ===
A classe abstrata Duck é usada como superclasse para as demais classes que a herdarem por isso ela tem os objetos quackBehavior e flyBehavior, essas duas variáveis usam interface como meio para o ''[[Polimorfismo]]''. Com o ''[[Polimorfismo]]'' podemos fazer a mudança de comportamento a qualquer momento durante a execução do aplicativo.
A função performaceQuack(), utiliza o objeto quackBehavior, chamando assim a sua função Quack, o objeto quackBehavior é do tipo QuackBehavior que é uma interface comum para todos as classes que a implementarem, esta interface tem o método Quack().
Como todas as classes que se responsabilizarem por executar uma variante do comportamento Quack, tem uma implementação da interface QuackBehavior, todas tem o método Quack(), e é só isso que importa para o cliente, pois ele não precisa saber como foi implementado o método Quack(), só precisa saber que ele exista.
A mesma ideia é aplicada para o comportamento Fly();
O código foi retirado de <ref>FREEMAN, Eric; FREEMAN Elisabeth. Use a Cabeça (head first) Padrões de Projeto. – Rio de Janeiro : Alta Books, 2007.</ref>.
<source lang="java">
package simduck;
 
/**
* Enumeration de cargos.
*
* */
public enum Cargo {
*/
ATENDENTE,
public abstract class Duck {
VENDEDOR,
public QuackBehavior quackBehavior;/*Comportamento Quack do tipo interface QuackBehavior*/
GERENTE;
public FlyBehavior flyBehavior; /*Comportamendo Fly do tipo interface FlyBehavior*/
 
public Duck(){/*Construtor vasio da classe Duck*/
 
}
public void performaceQuack(){/* Esta função serve para executar o comportamento atual
Quack através da variável quackBehavior*/
quackBehavior.Quack();
}
public void performaceFly(){/* Esta função serve para executar o comportamento atual
Fly através da variável flyBehavior*/
flyBehavior.Fly();
}
 
public void Swim(){/* Este é um algortimo ainda não trabalhado pelo padrao Strategy, pois todo pato nada, mais de forma diferente*/
System.out.println("All ducks float, even decoys!");
}
 
public void SetFlyBehavior(FlyBehavior FB){
flyBehavior = FB;
}
 
public void SestQuackBehavior(QuackBehavior QB){
quackBehavior = QB;
}
 
public abstract void Display();
}
</source>
<br />
 
=== Explicação FlyBehavior ===
Como foi identificado o comportamento Fly, entedemos que todo pato voa mas não da mesma forma, logo temos um comportamento e todo comportamento precisa de uma interface pois assim obrigamos a todo comportamento ter um método Fly(); e cada comportamento que herda essa interface, fica responsável por implementar o método Fly();, como todos vão ter a interface FlyBehavior em comum na herança, isso permite o ''[[Polimorfismo]]'', necessário para trocar o comportamento em tempo de execução.
O código foi retirado de <ref>FREEMAN, Eric; FREEMAN Elisabeth. Use a Cabeça (head first) Padrões de Projeto. – Rio de Janeiro : Alta Books, 2007.</ref>.
 
<source lang="java">
 
package simduck;
 
/**
*
*
*/
public interface FlyBehavior {
void Fly();
}
</source>
<br />
 
=== Explicação FlyWithWings ===
FlyWithWings é um comportamento, ele é uma variante do comportamento fly, logo implementa a interface FlyBehavior e tem como obrigação implementar o método Fly(), de acordo com a necessidade definida pelo programador.
O código foi retirado de <ref>FREEMAN, Eric; FREEMAN Elisabeth. Use a Cabeça (head first) Padrões de Projeto. – Rio de Janeiro : Alta Books, 2007.</ref>.
 
<source lang="java">
package simduck;
 
/**
*
*
*/
public class FlyWithWings implements FlyBehavior{
 
public void Fly() {
System.out.println("Voando como um passaro!");
}
 
}
</source>
<br />
 
=== Explicação FlyasRocketPower ===
FlyasRocketPower é um comportamento, ele é uma variante do comportamento fly, logo implementa a interface FlyBehavior e tem como obrigação implementar o método Fly(), de acordo com a necessidade definida pelo programador.
O código foi retirado de <ref>FREEMAN, Eric; FREEMAN Elisabeth. Use a Cabeça (head first) Padrões de Projeto. – Rio de Janeiro : Alta Books, 2007.</ref>.
 
<source lang="java">
package simduck;
 
/**
*
*
*/
public class FlyasRocketPower implements FlyBehavior{
public void Fly(){
System.out.println("Fling as ROCKET!");
}
}
</source>
<br />
 
=== Explicação Main ===
A classe Main tem como função simplesmente demostrar um exemplo de execução e troca de comportamento de objetos em tempo de execução pelo padrão de projeto Strategy.
O código foi retirado de <ref>FREEMAN, Eric; FREEMAN Elisabeth. Use a Cabeça (head first) Padrões de Projeto. – Rio de Janeiro : Alta Books, 2007.</ref>.
 
<source lang="java">
package simduck;
 
/**
*
*
*/
public class Main {
 
/**
* Dados do funcionario.
* @param args the command line arguments
*/
public staticclass void main(String[] args)Funcionario {
//private TODOlong code application logic hereid;
MallarDuckprivate concrectMallarDuckenum cargo;
// Construtor, getters e setters
concrectMallarDuck = new MallarDuck();
ModelDuck. concrectModelDuck;. .
concrectModelDuck = new ModelDuck();
System.out.println("Um concrete MallarDuck:");
concrectMallarDuck.performaceFly();
concrectMallarDuck.performaceQuack();
System.out.println("Um concrete ModelDuck:");
System.out.println("Comportamento fly do MallarDuck foi mudado em tempo de execução,");
concrectMallarDuck.SetFlyBehavior(new NoFly());
System.out.println("para o comportamento NoFly.");
concrectMallarDuck.performaceFly();
System.out.println("Comportamento quack do MallarDuck foi mudado em tempo de execução,");
concrectMallarDuck.SestQuackBehavior(new Squeak());
System.out.println("para o comportamento Squeak.");
concrectMallarDuck.performaceQuack();
 
System.out.println();
System.out.println();
System.out.println("Um concrete ModelDuck:");
concrectModelDuck.performaceFly();
concrectModelDuck.performaceQuack();
System.out.println("Um concrete ModelDuck:");
System.out.println("Comportamento fly do ModelDuck foi mudado em tempo de execução,");
concrectModelDuck.SetFlyBehavior(new FlyasRocketPower());
System.out.println("para o comportamento FlyasRockerPower.");
concrectModelDuck.performaceFly();
System.out.println("Comportamento quack do ModelDuck foi mudado em tempo de execução,");
concrectModelDuck.SestQuackBehavior(new MuteQuack());
System.out.println("para o comportamento Mute.");
concrectModelDuck.performaceQuack();
 
 
}
 
 
}
</source>
<br />
 
=== Explicação MallarDuck ===
MallarDuck é uma classe que herda a classe Duck, herdando assim a capacidade de mudar de comportamento Fly e Quack, que foi atribuida a classe Duck, através da implementação do padrão Strategy.
O código foi retirado de <ref>FREEMAN, Eric; FREEMAN Elisabeth. Use a Cabeça (head first) Padrões de Projeto. – Rio de Janeiro : Alta Books, 2007.</ref>.
 
<source lang="java">
/**
package simduck;
* Interface pattern Strategy.
*/
public interface Strategy {
 
// Calcula comissão.
/**
double calcularComissao(double valorVenda);
*
*
*/
public class MallarDuck extends Duck {
 
public MallarDuck() {
quackBehavior = new Quack();/*Inicializado com o comportamento Quack*/
flyBehavior = new FlyWithWings();/*Inicializado com o comportamento FlyWithWinds, pois ele é um pato selvagem logo voa*/
}
 
public void Display(){
System.out.println("I'm a mallar Duck!");
}
 
}
</source>
<br />
 
=== Explicação ModelDuck ===
ModelDuck é uma classe que herda a classe Duck, herdando assim a capacidade de mudar de comportamento Fly e Quack, que foi atribuida a classe Duck, através da implementação do padrão Strategy.
O código foi retirado de <ref>FREEMAN, Eric; FREEMAN Elisabeth. Use a Cabeça (head first) Padrões de Projeto. – Rio de Janeiro : Alta Books, 2007.</ref>.
 
<source lang="java">
/**
* Classe que calcula comissão de venda.
*/
public class Venda {
 
private double valorVenda;
package simduck;
private Funcionario funcionario;
private Strategy calculoComissao;
 
// Construtor [Implementa STRATEGY].
import simduck.FlyBehavior;
public Venda() {
 
switch (funcionario.getCargo()) {
/**
*
*
*/
public class ModelDuck extends Duck{
public ModelDuck(){
flyBehavior = new NoFly();/*Inicializado com o comportamento NoFly, pois ele é um pato de modelo, não é um pato de verdade*/
quackBehavior = new Squeak();/*Inicializado com o comportamento Quack*/
}
 
case ATENDENTE :
 
this.setCalculoComissao(new Strategy() {
public void Display() {
System.out.println("I'm a ModelDuck!");
}
 
@Override
public double calcularComissao(double valorVenda) {
return (valorVenda * 0.01);
}
});
break;
 
case VENDEDOR :
 
this.setCalculoComissao(new Strategy() {
}
</source>
<br />
 
@Override
=== Explicação MuteQuack ===
public double calcularComissao(double valorVenda) {
MuteQuack é um comportamento, ele é uma variante do comportamento Quack, logo implementa a interface QuackBehavior e tem como obrigação implementar o método Quack(), de acordo com a necessidade definida pelo programador.
return (valorVenda * 0.02);
O código foi retirado de <ref>FREEMAN, Eric; FREEMAN Elisabeth. Use a Cabeça (head first) Padrões de Projeto. – Rio de Janeiro : Alta Books, 2007.</ref>.
}
});
break;
 
case GERENTE :
<source lang="java">
package simduck;
 
this.setCalculoComissao(new Strategy() {
/**
*
*
*/
public class MuteQuack implements QuackBehavior {
 
@Override
public void Quack(){
public double calcularComissao(double valorVenda) {
System.out.println("Mute!");
return (valorVenda * 0.03);
}
}
}
});
break;
</source>
}
<br />
}
 
private void setCalculoComissao(Strategy calculoComissao) {
=== Explicação NoFly ===
this.calculoComissao= calculoComissao;
NoFly é um comportamento, ele é uma variante do comportamento fly, logo implementa a interface FlyBehavior e tem como obrigação implementar o método Fly(), de acordo com a necessidade definida pelo programador.
}
O código foi retirado de <ref>FREEMAN, Eric; FREEMAN Elisabeth. Use a Cabeça (head first) Padrões de Projeto. – Rio de Janeiro : Alta Books, 2007.</ref>.
 
private Strategy getCalculoComissao() {
<source lang="java">
return (this.calculoComissao);
package simduck;
}
 
public void save() {
/**
*
*
*/
public class NoFly implements FlyBehavior{
 
public void Fly() { //. . .
System.out.println("No can fly!");
}
}
</source>
<br />
 
/*
=== Explicação Quack ===
* Calcula o valor da comissão de venda sem que haja a necessidade de
Quack é um comportamento, ele é uma variante do comportamento Quack, logo implementa a interface QuackBehavior e tem como obrigação implementar o método Quack(), de acordo com a necessidade definida pelo programador.
* verificar qual o tipo cargo toda vez que o metodo <b>save</b> for executado.
O código foi retirado de <ref>FREEMAN, Eric; FREEMAN Elisabeth. Use a Cabeça (head first) Padrões de Projeto. – Rio de Janeiro : Alta Books, 2007.</ref>.
*/
final double valorComissao = this.getCalculoComissao().calcularComissao(this.valorVenda);
 
// . . .
<source lang="java">
}
package simduck;
 
/**
*
*
*/
public class Quack implements QuackBehavior{
public void Quack() {
System.out.println("quack quack quack!");
}
}
</source>
<br />
 
{{Padrões de projeto}}
=== Explicação QuackBehavior ===
Como foi identificado o comportamento Quack, entedemos que todo pato “quacka” mas não da mesma forma, logo temos um comportamento e todo comportamento precisa de uma interface pois assim obrigamos a todo comportamento ter um método Quack(); e cada comportamento que herda essa interface, fica responsável por implementar o método Quack();, como todos vão ter a interface QuackBehavior em comum na herança, isso permite o ''[[Polimorfismo]]'', necessário para trocar o comportamento em tempo de execução.
O código foi retirado de <ref>FREEMAN, Eric; FREEMAN Elisabeth. Use a Cabeça (head first) Padrões de Projeto. – Rio de Janeiro : Alta Books, 2007.</ref>.
 
<source lang="java">
package simduck;
 
/**
*
*
*/
public interface QuackBehavior {
void Quack();
}
</source>
<br />
 
=== Explicação Squeak ===
Squeak é um comportamento, ele é uma variante do comportamento Quack, logo implementa a interface QuackBehavior e tem como obrigação implementar o método Quack(), de acordo com a necessidade definida pelo programador.
O código foi retirado de <ref>FREEMAN, Eric; FREEMAN Elisabeth. Use a Cabeça (head first) Padrões de Projeto. – Rio de Janeiro : Alta Books, 2007.</ref>.
 
<source lang="java">
package simduck;
 
/**
*
*
*/
public class Squeak implements QuackBehavior{
public void Quack(){
System.out.println("Fiuuu Fiuuu!");
}
}
</source>
<br />
 
== Conceitos Orientados a Objetos Utilizados ==
 
<ref>Larman, Craig. Utilizando UML e padrões:uma introdução à análise e ao projeto orientados a objetos e ao desenvolvimento interativo. 3ª. Ed. Porto Alegre:Bookman, 2007.</ref>
 
<ref>GAMMA, Erich et al. Padrões de Projeto: soluções reutilizáveis de software orientado a objetos. – Porto Alegre: Bookman, 2000.</ref>
 
<div class="references" style="-moz-column-count:3; column-count:3;">
* ''[[Acoplamento Fraco]]''
* ''[[Composição de objetos]]''
* ''[[Polimorfismo]]''
</div>
{{ref-section}}
 
[[Categoria:Programação orientada a objetos]]