生活中的一个例子:
就拿汽车在路上行驶的来说。即有小汽车又有公共汽车,它们都不但能在市区中的公路上行驶,也能在高速公路上行驶。这你会发现,对于交通工具(汽车)有不同的类型,然而它们所行驶的环境(路)也在变化,在软件系统中就要适应两个方面的变化?怎样实现才能应对这种变化呢?
概述:
在软件系统中,某些类型由于自身的逻辑,它具有两个或多个维度的变化,那么如何应对这种“多维度的变化”?如何利用面向对象的技术来使得该类型能够轻松的沿着多个方向进行变化,而又不引入额外的复杂度?这就要使用Bridge模式。
结构图:
传统的做法:
通过类继承的方式来做上面的例子;
先看一下类结构图:
代码实现:
public class Road
{
pubilc void run(){System.out.println("在路上");}
}
public class SpeedWay extends Road
{
public void run(){System.out.println("高速公路");}
}
//市区街道
public class Street extends Road
{
public void run(){System.out.println("市区街道");}
}
public class CarOnSpeedWay extends SpeedWay
{
public void run(){System.out.println("小汽车在调整公路上行驶");}
}
public class BusOnSpeedWay extends SpeedWay
{
public void run(){System.out.println("公共汽车在高速公路上行驶");}
}
public class CarOnStreet extends Street{
public void run(){System.out.println("汽车在街道上行驶");}
}
public class BusOnStreet extends Street{
public void run(){System.out.println("公共汽车在街道上行驶");}
}
缺点:
但是我们说这样的设计是脆弱的,仔细分析就可以发现,它还是存在很多问题,首先它在遵循开放-封闭原则的同时,违背了类的单一职责原则,即一个类只有一个引起它变化的原因,而这里引起变化的原因却有两个,即路类型的变化和汽车类型的变化;其次是重复代码会很多,不同的汽车在不同的路上行驶也会有一部分的代码是相同的;再次是类的结构过于复杂,继承关系太多,难于维护,最后最致命的一点是扩展性太差。如果变化沿着汽车的类型和不同的道路两个方向变化,我们会看到这个类的结构会迅速的变庞大。
应用设计模式 桥接模式(Bridge)来做;
先看一下类结构图:
代码实现:
首先创建抽象的路
package com.utils;
public abstract class AbstractRoad
{
AbstractCar car;
public void setCar(AbstractCar car)
{
this.car=car;
}
public abstract void run();
}
创建高速公路类
package com.utils;
public class SpeedWay extends AbstractRoad
{
@Override
public void run()
{
car.run();
System.out.println("高速公路上行驶");
}
}
创建市区街道类
package com.utils;
public class Street extends AbstractRoad
{
@Override
public void run()
{
car.run();
System.out.println("市区街道上行驶");
}
}
创建抽象车类
package com.utils;
public abstract class AbstractCar
{
public abstract void run();
}
创建小汽车类
package com.utils;
public class Car extends AbstractCar
{
@Override
public void run()
{
System.out.println("小汽车在");
}
}
创建公共汽车类
package com.utils;
public class Bus extends AbstractCar
{
@Override
public void run()
{
System.out.println("公共汽车在");
}
}
在客户端调用
import com.utils.AbstractRoad;
import com.utils.Bus;
import com.utils.Car;
import com.utils.SpeedWay;
public class Client
{
/**
* @param args
*/
public static void main(String[] args)
{
//创建在高速公路上行驶的公共汽车
AbstractRoad carRoad=new SpeedWay();
carRoad.setCar(new Bus());
carRoad.run();
}
}
输出结果:
公共汽车在
高速公路上行驶
可以看到,通过对象组合的方式,Bridge 模式把两个角色之间的继承关系改为了耦合的关系,从而使这两者可以从容自若的各自独立的变化,这也是Bridge模式的本意。
这样增加了客户程序与路与汽车的耦合。其实这样的担心是没有必要的,因为这种耦合性是由于对象的创建所带来的,完全可以用创建型模式去解决。在应用时结合创建型设计模式来处理具体的问题。