【Java设计形式】Java实现桥接模式
【Java设计模式】Java实现桥接模式
不多说了,直接上代码。原代码是由一雨田使用C++写的,我改成了使用Java实现。
package cn.areful.designpattern.bridge; /************************************************************************************************************\ * 任务叙述:我们现在要实现一个画图系统,这个系统的需求暂时来说有以下几个: * 1、画圆、画长方形。(先实现画这两个形状) * 2、已经有两个画图库了,这些画图库中定义了我们需要的操作,我们没必要重新去实现了 * 3、我们的系统能够决定使用哪个的画图库中的操作 * 根据以上的需求,我们的代码设计如下(这里先不使用Bridge模式,以便对比) : \************************************************************************************************************/ /************************************************************************************************************\ * 两个画图库 \************************************************************************************************************/ /** 画图库1 */ class DrawLib1 { public void DrawCircle() { System.out.println("DrawLib1,DrawCircle()"); } public void DrawRectangle() { System.out.println("DrawLib1,DrawRectangle()"); } public void DrawTriangle() { System.out.println("DrawLib1,DrawTriangle()"); } } /** 画图库2 */ class DrawLib2 { public void DrawCircle() { System.out.println("DrawLib2,DrawCircle()"); } public void DrawRectangle() { System.out.println("DrawLib2,DrawRectangle()"); } public void DrawTriangle() { System.out.println("DrawLib2,DrawTriangle()"); } } /************************************************************************************************************ * \ 不使用桥接模式 \ ************************************************************************************************************/ /** 通过绘图系统的接口,很容易抽象出来两个绘图库的绘图接口: */ abstract class Shape1 { public abstract void draw(); protected DrawLib1 lib1; } abstract class Shape2 { public abstract void draw(); protected DrawLib2 lib2; } /** 然后通过绘图库1和绘图库2的接口,实现画圆和画矩形: */ class Circle1 extends Shape1 { public Circle1() { lib1 = new DrawLib1(); } @Override public void draw() { lib1.DrawCircle(); } } class Rectangle1 extends Shape1 { public Rectangle1() { lib1 = new DrawLib1(); } @Override public void draw() { lib1.DrawRectangle(); } } class Circle2 extends Shape2 { public Circle2() { lib2 = new DrawLib2(); } @Override public void draw() { lib2.DrawCircle(); } } class Rectangle2 extends Shape2 { public Rectangle2() { lib2 = new DrawLib2(); } @Override public void draw() { lib2.DrawRectangle(); } } /** 调用库1的方法 */ class Draw1 { public Draw1(Shape1 s1) { s1.draw(); } } /** 调用库2的方法 */ class Draw2 { public Draw2(Shape2 s2) { s2.draw(); } } /** 不使用桥接方式,实现绘图系统 */ class NoBridge { public void test() { Circle1 c1 = new Circle1(); Circle2 c2 = new Circle2(); Rectangle1 r1 = new Rectangle1(); Rectangle2 r2 = new Rectangle2(); new Draw1(c1); new Draw1(r1); new Draw2(c2); new Draw2(r2); } } /************************************************************************************************************ * \ 好的,上述的代码运行正常,如果不需要维护的话,我们就不用管它拉~~ 但是,代码是一定要维护的,逃不过的宿命。 出现变化的地方可能是这样的: * 1、出现了第三个库 2、画图系统需要画三角形 这个时候,我们再看看要完成这两个变化我们需要作的修改,就会发现,我要晕了 * (当一个程序员要晕的时候,也就是BUG要出现的时候了) \ ************************************************************************************************************/ /************************************************************************************************************ * 好了,现在让我们使用Bridge模式来实现上面的系统<br> * Bridge模式最重要是把表示和实现分开 ************************************************************************************************************/ /** 抽象出两个库中画圆,和画矩形的方法,为接口ShapeImp */ interface ShapeImp { public void DrawCircle(); public void DrawRectangle(); } /** 通过ShapeImp接口实现对库1的调用 */ class ShapeImp1 implements ShapeImp { public void DrawCircle() { dlib1.DrawCircle(); } public void DrawRectangle() { dlib1.DrawRectangle(); } private DrawLib1 dlib1 = new DrawLib1(); } /** 通过ShapeImp接口实现对库2的调用 */ class ShapeImp2 implements ShapeImp { public void DrawCircle() { dlib2.DrawCircle(); } public void DrawRectangle() { dlib2.DrawRectangle(); } private DrawLib2 dlib2 = new DrawLib2(); } /** 将"画圆"抽象到Circle类中 */ class Circle { private ShapeImp shape; public Circle(ShapeImp shape) { this.shape = shape; } public void draw() { shape.DrawCircle(); } } /** 将"画矩形"抽象到Rectangle类中 */ class Rectangle { private ShapeImp shape; public Rectangle(ShapeImp shape) { this.shape = shape; } public void draw() { shape.DrawRectangle(); } } /************************************************************************************************************ * \ * * ClassName: Bridge<br> * Description: 使用"桥接"模式重新实现画图系统 * <p> * * 再考虑下面的需求:<br> * 1.出现了第三个库<br> * 2.画图系统需要新增一个画三角形的方法 * <p> * * 针对对一个需求,只需添加一个ShapeImg就可以了。<br> * 针对第二个需求,只需添加一个Triangle类就可以了。<br> * 可以看出来,变化不再造成混乱,只需要单独针对变化改动代码就行了。<br> * 也就是,变化被Bridge给分开了。<br> * * @author gaojian email:gaojian@raiyi.com * @version * @since Ver 1.1 * @Date 2013 2013-10-28 下午1:58:13 * @see \ ************************************************************************************************************/ class Bridge { public void test() { ShapeImp s1 = new ShapeImp1(); Circle c1 = new Circle(s1); c1.draw(); Rectangle r1 = new Rectangle(s1); r1.draw(); ShapeImp s2 = new ShapeImp2(); Circle c2 = new Circle(s2); c2.draw(); Rectangle r2 = new Rectangle(s2); r2.draw(); } } /** 测试使用桥接模式,和不使用桥接模式实现的画图系统 */ public class BridgeTest { public static void main(String[] args) { /** 为true,测试使用桥接模式,否则,测试不使用桥接模式 */ final boolean isbridget = true; if (isbridget) { Bridge b = new Bridge(); b.test(); } else { NoBridge b = new NoBridge(); b.test(); } } }