Java设计模式之--桥接模式(bridge pattern)

来源:互联网 发布:C语言gets 编辑:程序博客网 时间:2024/06/11 18:50
概念:
桥接模式的用意是"将抽象化(Abstraction)与实现化(Implementation)脱耦,使得二者可以独立地变化"。实际项目中遇到某些类由于自身的逻辑,它具有两个或多个维度的变化,那么如何应对这种“多维度的变化”?如何利用面向对象的技术来使得该类型能够轻松的沿着多个方向进行变化,而又不引入额外的复杂度?这就要使用Bridge模式。。像我们常用的JDBC桥DriverManager一样,JDBC进行连接数据库的时候,在各个数据库之间进行切换,不需要动太多的代码,甚至丝毫不用动,原因就是JDBC提供统一接口,每个数据库提供各自的实现,用一个叫做数据库驱动的程序来桥接就行了。我们来看看关系图:

代码:
Driver interface
public interface Driver {    public boolean connect(String uri);    public Cursor query(String query);}
bridge class:
public abstract class DriverBridge {    private Driver driver;    public Driver getDriver() {        return driver;    }    public void setDriver(Driver driver) {        this.driver = driver;    }    public abstract boolean connect(String uri);    public abstract Cursor query(String query);}

有了桥再有两边:
db 实现类:
public class MysqlDriver implements Driver {    @Override    public boolean connect(String uri) {        System.out.println(String.format("%s.%s called!", this.getClass().getName(), "connect()"));        return false;    }    @Override    public Cursor query(String query) {        System.out.println(String.format("%s.%s called!", this.getClass().getName(), "query()"));        return null;    }}
public class DB2Driver implements Driver {    @Override    public boolean connect(String uri) {        System.out.println(String.format("%s.%s called!", this.getClass().getName(), "connect()"));        return false;    }    @Override    public Cursor query(String query) {        System.out.println(String.format("%s.%s called!", this.getClass().getName(), "query()"));        return null;    }}

public class OracleDriver implements Driver {    @Override    public boolean connect(String uri) {        System.out.println(String.format("%s.%s called!", this.getClass().getName(), "connect()"));        return false;    }    @Override    public Cursor query(String query) {        System.out.println(String.format("%s.%s called!", this.getClass().getName(), "query()"));        return null;    }}

user bridge class:
public class WeatherBridge extends DriverBridge {    @Override    public boolean connect(String uri) {        return getDriver().connect(uri);    }    @Override    public Cursor query(String query) {        return getDriver().query(query);    }}

测试类:
public class WorkClass {    public void test() {        DriverBridge driverBridge = new WeatherBridge();        driverBridge.setDriver(new MysqlDriver());        driverBridge.connect("");        driverBridge.query("");        driverBridge.setDriver(new DB2Driver());        driverBridge.connect("");        driverBridge.query("");    }}

测试结果 :
I/System.out: com.example.qinghua_liu.myapplication.designpatten.struct.adapt.MysqlDriver.connect() called!
I/System.out: com.example.qinghua_liu.myapplication.designpatten.struct.adapt.MysqlDriver.query() called!
I/System.out: com.example.qinghua_liu.myapplication.designpatten.struct.adapt.DB2Driver.connect() called!
I/System.out: com.example.qinghua_liu.myapplication.designpatten.struct.adapt.DB2Driver.query() called!

案例二:
天气类应用,天气状态分晴天和雨天,现有功能需要扩展,增加夜晚状态,这样天气状态存在变化,时间白天夜晚又存在另一维度的变化,应用桥接模式如下:
先写天气接口:
public interface Weather {    public String getWeatherText();}
两个接口的实现类:
public class Sunny implements Weather {    @Override    public String getWeatherText() {        return "clear";    }}

public class Rain implements Weather {    @Override    public String getWeatherText() {        return "rainy";    }}
天气桥接抽象类:
public abstract class WeatherBridge {    private Weather weather;    public WeatherBridge(Weather weather) {        this.weather = weather;    }    public Weather getWeather() {        return weather;    }    public void setWeather(Weather weather) {        this.weather = weather;    }    public abstract String showWeather();}
抽象的子类白天类与夜晚类:
public class DayTimeWeather extends WeatherBridge {    @Override    public String showWeather() {        //System.out.println(String.format("A %s day time", getWeather().getWeatherText()));        return String.format("A %s day time", getWeather().getWeatherText());    }    public DayTimeWeather(Weather weather) {        super(weather);    }}

public class NightWeather extends WeatherBridge {    @Override    public String showWeather() {//        System.out.println(String.format("A %s night", getWeather().getWeatherText()));        return String.format("A %s night", getWeather().getWeatherText());    }    public NightWeather(Weather weather) {        super(weather);    }}
测试:
WeatherBridge weatherBridge= new DayTimeWeather(new Sunny());System.out.println(weatherBridge.showWeather());weatherBridge.setWeather(new Rain());System.out.println(weatherBridge.showWeather());weatherBridge = new NightWeather(new Sunny());System.out.println(weatherBridge.showWeather());weatherBridge.setWeather(new Rain());System.out.println(weatherBridge.showWeather());
输出:
 I/System.out: A clear day time I/System.out: A rainy day timeI/System.out: A clear nightI/System.out: A rainy night

再加扩展:区分季节状态,再加第三维状态:
定义季节天气桥抽象类:
public abstract class SeasonBridge {    private WeatherBridge weatherBridge;    public SeasonBridge(WeatherBridge weatherBridge) {        this.weatherBridge = weatherBridge;    }    public WeatherBridge getWeatherBridge() {        return weatherBridge;    }    public void setWeatherBridge(WeatherBridge weatherBridge) {        this.weatherBridge = weatherBridge;    }    public abstract String showWeather();}

定义上面抽象类的实现类:夏季,冬季
public class Summer extends SeasonBridge {    public Summer(WeatherBridge weatherBridge) {        super(weatherBridge);    }    @Override    public String showWeather() {        return String.format("%s in summer",getWeatherBridge().showWeather());    }}
public class Winter extends SeasonBridge {    public Winter(WeatherBridge weatherBridge) {        super(weatherBridge);    }    @Override    public String showWeather() {        return String.format("%s in winter",getWeatherBridge().showWeather());    }}
测试代码:
        
WeatherBridge weatherBridge= new DayTimeWeather(new Sunny());SeasonBridge seasonBridge = new Summer(weatherBridge);System.out.println(seasonBridge.showWeather());weatherBridge.setWeather(new Rain());System.out.println(seasonBridge.showWeather());seasonBridge.setWeatherBridge(new NightWeather(new Sunny()));System.out.println(seasonBridge.showWeather());seasonBridge = new Winter(weatherBridge);System.out.println(seasonBridge.showWeather());
输出结果:
I/System.out: A clear day time in summerI/System.out: A rainy day time in summerI/System.out: A clear night in summerI/System.out: A rainy day time in winter


桥梁模式和适配器模式的区别
很多时候经常容易把桥接模式和适配器模式弄混。那什么时候用桥接,什么时候用适配器呢 ?
共同点:桥接和适配器都是让两个东西配合工作
不同点:出发点不同。
适配器:对已有的两个接口增加适配类,让他们相容。
桥接模式:分离抽象化和实现,使两者的接口可以不同,目的是分离。
所以说,如果你拿到两个已有模块,想让他们同时工作,那么你使用的适配器。
如果你还什么都没有,但是想分开实现,那么桥接是一个选择。
桥接是先有桥,才有两端的东西
适配是先有两边的东西,才有适配器
桥接是在桥好了之后,两边的东西还可以变化。
0 0
原创粉丝点击