Desacopla uma abstração da sua implementação de modo que as duas possam variar independentemente.
Em um jogo lutadores de MMA (Mixed Martial Arts) brasileiros e japoneses utilizam diversos estilos de arte marcial (karatê, judô e jiu-jitsu). Durante a luta eles podem mudar a arte utilizada nos golpes para ataque e defesa. O jogador atuando como técnico decide como configurar cada lutador de acordo com esses diferentes estilos de arte marcial.
A implementação da abstração Fighter é organizada em duas hierarquias de classes separadas, uma para variação das nacionalidades dos lutadores (BrazilianFighter, JapaneseFighter) e outra para variação das artes marciais dos lutadores (Karate, Judo, Jui-Jitsu). FighterImpl mantém uma referência para um objeto MartialArt e delega a execução dos golpes para esse objeto, permitindo combinar as duas hierarquias sem ter que criar uma classe para cada possível combinação evitando, assim, uma explosão de classes.
Abstraction (FighterImpl): Define a interface da abstração e mantém uma referência para o objeto do tipo MartialArt.
RefinedAbstraction (BrazilianFighter, JapaneseFighter):Estende a interface definida em Abstraction.
Implementor (MartialArt): Define a interface para as classes de implementação.
ConcreteImplementor (Karaoke, Judo, Jui-Jitsu): Implementa a interface de Implementor e define sua implementação concreta.
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package uff.labies.bridgecodes;
import uff.labies.bridgecodes.client.Client;
import uff.labies.bridgecodes.model.BrazilianFighter;
import uff.labies.bridgecodes.model.FighterImpl;
import uff.labies.bridgecodes.model.JaponeseFighter;
import uff.labies.bridgecodes.model.MartialArt;
import uff.labies.bridgecodes.model.MartialArtJiuJitsu;
import uff.labies.bridgecodes.model.MartialArtJudo;
import uff.labies.bridgecodes.model.MartialArtKarate;
/**
*
* @author eduardo
*/
public class Main {
public FighterImpl getFighter(String nac, MartialArt ma) throws Exception{
FighterImpl f = new BrazilianFighter();
switch(nac){
case "Brazil": f = new BrazilianFighter(); break;
case "Japon": f = new JaponeseFighter();break;
default: throw new Exception("Nacionalidade '"+nac+"' desconhecida");
}
return f;
}
public MartialArt getMartialArt(String tp) throws Exception{
switch(tp){
case "Karatê": return new MartialArtKarate();
case "Judô": return new MartialArtJudo();
case "Jiu-Jitsu": return new MartialArtJiuJitsu();
default: throw new Exception("tipo de Arte Marcial '"+tp+"' desconhecida");
}
}
public static void main(String[] args) {
Main m = new Main();
Client c = new Client();
try {
FighterImpl f = m.getFighter("Brazil",m.getMartialArt("Karatê"));
c.setFighter(f);
c.doAttack();
}catch(Exception ex){
System.out.println(ex.getMessage());
}
}
}
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package uff.labies.bridgecodes.client;
import uff.labies.bridgecodes.model.Fighter;
/**
*
* @author eduardo
*/
public class Client {
private Fighter f;
public void setFighter(Fighter f){
this.f = f;
}
public void doAttack(){
f.toAttack();
}
public void doDeffend(){
f.toDefend();
}
}
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package uff.labies.bridgecodes.model;
/**
*
* @author eduardo
*/
public class MartialArtJudo implements MartialArt{
@Override
public void toAttack() {
// Define a forma de ataque utilizada pelo judô
}
@Override
public void toDefend() {
// define a forma de defesa utilizada pelo Judô
}
}
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package uff.labies.bridgecodes.model;
/**
*
* @author eduardo
*/
public abstract class FighterImpl implements Fighter{
private MartialArt ma;
public void setMartialArt(MartialArt ma) {
this.ma = ma;
}
public MartialArt getMartialArt() {
return ma;
}
}
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package uff.labies.bridgecodes.model;
/**
*
* @author eduardo
*/
public interface Fighter {
public void toAttack();
public void toDefend();
}
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package uff.labies.bridgecodes.model;
/**
*
* @author eduardo
*/
public class MartialArtJiuJitsu implements MartialArt{
@Override
public void toAttack() {
// Define a forma de ataque utilizada pelo Jiu-Jitsu
}
@Override
public void toDefend() {
// define a forma de defesa utilizada pelo Jiu-Jitsu
}
}
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package uff.labies.bridgecodes.model;
/**
*
* @author eduardo
*/
public class MartialArtKarate implements MartialArt{
@Override
public void toAttack() {
// Define a forma de ataque utilizada pelo karatê
}
@Override
public void toDefend() {
// define a forma de defesa utilizada pelo karatê
}
}
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package uff.labies.bridgecodes.model;
/**
*
* @author eduardo
*/
public class JaponeseFighter extends FighterImpl {
@Override
public void toAttack() {
getMartialArt().toAttack();
}
@Override
public void toDefend() {
getMartialArt().toDefend();
}
}
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package uff.labies.bridgecodes.model;
/**
*
* @author eduardo
*/
public class BrazilianFighter extends FighterImpl {
@Override
public void toAttack() {
getMartialArt().toAttack();
}
@Override
public void toDefend() {
getMartialArt().toDefend();
}
}
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package uff.labies.bridgecodes.model;
/**
*
* @author eduardo
*/
public interface MartialArt {
public void toAttack();
public void toDefend();
}