Bridge

Intenção

Desacopla uma abstração da sua implementação de modo que as duas possam variar independentemente.

Vantagens

Desvantagens

Exemplos

Exemplo #1

Exemplo #2

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.

Diagrama de Classe

Exemplo #2 - Diagrama

Participantes

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.

 

 

Código

/*
 * 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();    
}
Clique aqui para fazer o download do código completo de implementação deste Design Pattern.

Padrões Relacionados

Este Padrão pode ser usado para resolver os seguintes problemas: