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

概念:
桥接模式的用意是"将抽象化(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 time
I/System.out: A clear night
I/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 summer
I/System.out: A rainy day time in summer
I/System.out: A clear night in summer
I/System.out: A rainy day time in winter


桥梁模式和适配器模式的区别
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章