第十五讲:桥接模式
Posted 绿茵好莱坞
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第十五讲:桥接模式相关的知识,希望对你有一定的参考价值。
package com.ibeifeng.eg1; //不同巴士安装的引擎不同,有的是3000CC,有的是2200CC,2400cc. public abstract class Bus implements Car{ public abstract void installEngine(); }
package com.ibeifeng.eg1; public class Bus2000 extends Bus{ @Override public void installEngine() { // TODO Auto-generated method stub System.out.println("给Bus安装2000cc发动机"); } }
package com.ibeifeng.eg1; public class Bus2200 extends Bus{ @Override public void installEngine() { // TODO Auto-generated method stub System.out.println("给Bus安装2200cc发动机"); } }
package com.ibeifeng.eg1; /** * 汽车 * @author zhongzh * */ public interface Car { public void installEngine(); }
package com.ibeifeng.eg1; public abstract class Jeep implements Car{ public abstract void installEngine(); }
package com.ibeifeng.eg1; public class Jeep2000 extends Jeep{ @Override public void installEngine() { // TODO Auto-generated method stub System.out.println("给Jeep安装2000cc发动机"); } }
package com.ibeifeng.eg1; public class Jeep2200 extends Jeep{ @Override public void installEngine() { // TODO Auto-generated method stub System.out.println("给Jeep安装2200cc发动机"); } }
package com.ibeifeng.eg1; //问题1:类非常多,如果再有卡车的话,或者再增加一种发动机规格. //这样添加的子类是以几何型增长的. public class MainClass { public static void main(String[] args) { Car car1 = new Bus2000(); car1.installEngine(); } }
//违反了开放封闭的原则
//如果增加了一种发动机规格,Bus又要修改了.Car的代码也要修改.
//另外如果接口定义的发动机规格Bus没有,为了保持接口的统一性不得不给Bus一个空的实现.这也是非常不好的.
package com.ibeifeng.eg2; //违反了开放封闭的原则 //如果增加了一种发动机规格,Bus又要修改了.Car的代码也要修改. //另外如果接口定义的发动机规格Bus没有,为了保持接口的统一性不得不给Bus一个空的实现. public class Bus implements Car { @Override public void install2000Engine() { // TODO Auto-generated method stub System.out.println("给Bus安装2000cc发动机"); } @Override public void install2200Engine() { // TODO Auto-generated method stub System.out.println("给Bus安装2200cc发动机"); } @Override public void install2300Engine() { // TODO Auto-generated method stub System.out.println("给Bus安装2300cc发动机"); } }
package com.ibeifeng.eg2; /** * 汽车 * @author zhongzh * */ public interface Car { //public void installEngine(); public void install2000Engine(); public void install2200Engine(); public void install2300Engine(); }
package com.ibeifeng.eg2; public class MainClass { public static void main(String[] args) { Car car1 = new Bus(); car1.install2000Engine(); } }
Car(抽象)持有Engine(发动机)(行为)的引用,这就是聚合.Car和Engine都有继承,它们也有封装.所以桥接模式使用了封装、聚合和继承.
Abstraction:抽象. Car
RefinedAbstraction: Bus和Jeep.
Implementor:行为 Engine(引擎).
ConcreteImplementorA:实际的行为. 2000cc/2200cc
ConcreteImplementorB:实际的行为.
不是一定要先做Engine再做Car,它们之间是相互独立的.它们之间有一座桥,这座桥就是一个聚合.Implementor是斜写的,抽象类.
桥接模式就很有扩展性.就算再添加一个卡车.那就再做一个卡车就行了,里面持有一个发动机的引用.
//这样程序就很有扩展性.就算再添加一个卡车.那就再做一个卡车就是了,里面持有一个发动机的引用.
//如果添加一个发动机,再做一个发动机就可以了.
//只是客户端在调用的时候稍微麻烦一些,但是这种麻烦并不是特别麻烦,也是需要判断的.
//客户端必须判断要支持一个什么样的实例,客户端必须得做的,你是实现哪一个实例/车的.
//第二种方案客户端必须知道你调用哪一个方法,但是桥接模式客户端只要知道传哪一个发动机进去就行了.
//客户端的判断是不可避免的.车的种类决定了你是要买2000的还是2200的还是买其他发动机规格的车.
//桥接就在于Car里面持有Engine的引用.正是因为有了这个引用的存在,Car和Engine联系在一起.
//Car持有Engine的接口的引用,可以传递不同的实现子类给它.因为有了不同的实现子类,又有了共同的接口,
//所以可以实现不同的方法.
//抽象和行为相互独立,而用桥(引用)将抽象和行为联系起来以后更加方便了,抽象和行为各自增加都不会产生任何的
//影响,这就是桥的作用,它们之间是一个引用的关系.Abstraction包含/持有了Implementor的引用.
//而且它们是一个接口,它们之间的方法是公开的公共的.
package com.ibeifeng.eg3; public class MainClass { public static void main(String[] args) { Engine engine2000 = new Engine2000(); Engine engine2200 = new Engine2200(); //更加灵活,把抽象与行为分开. Car car1 = new Bus(engine2000);//Bus是要做什么引擎的,就把什么引擎传进去. car1.installEngine(); Car car2 = new Bus(engine2200);//Bus是要做什么引擎的,就把什么引擎传进去. car2.installEngine(); //把发动机规格传进去就可以了. Car jeep1 = new Jeep(engine2000); jeep1.installEngine();//给jeep安装2000cc发动机 Car jeep2 = new Jeep(engine2000); jeep1.installEngine();//给jeep安装2200cc发动机 //这样程序就很有扩展性.就算再添加一个卡车.那就再做一个卡车就是了,里面持有一个发动机的引用. //如果添加一个发动机,再做一个发动机就可以了. //只是客户端在调用的时候稍微麻烦一些,但是这种麻烦并不是特别麻烦,也是需要判断的. //客户端必须判断要支持一个什么样的实例,客户端必须得做的,你是实现哪一个实例/车的. //第二种方案客户端必须知道你调用哪一个方法,但是桥接模式客户端只要知道传哪一个发动机进去就行了. //客户端的判断是不可避免的.车的种类决定了你是要买2000的还是2200的还是买其他发动机规格的车. //桥接就在于Car里面持有Engine的引用.正是因为有了这个引用的存在,Car和Engine联系在一起. //Car持有Engine的接口的引用,可以传递不同的实现子类给它.因为有了不同的实现子类,又有了共同的接口, //所以可以实现不同的方法. //抽象和行为相互独立,而用桥(引用)将抽象和行为联系起来以后更加方便了,抽象和行为各自增加都不会产生任何的 //影响,这就是桥的作用,它们之间是一个引用的关系.Abstraction包含/持有了Implementor的引用. //而且它们是一个接口,它们之间的方法是公开的公共的. } }
package com.ibeifeng.eg3; //public class Engine { public interface Engine{ public void installEngine(); }
package com.ibeifeng.eg3; public class Engine2000 implements Engine{ @Override public void installEngine() { // TODO Auto-generated method stub System.out.println("安装2000cc发动机"); } }
package com.ibeifeng.eg3; public class Engine2200 implements Engine{ @Override public void installEngine() { // TODO Auto-generated method stub System.out.println("安装2200cc发动机"); } }
package com.ibeifeng.eg3; //这里把Car不做成接口,做成抽象类. //Car持有Engine的引用. //抽象类是没有实例的. public abstract class Car { private Engine engine; public Car(Engine engine) { super(); this.engine = engine;//把engine设置上. } public Engine getEngine() {//获得Car里面的发动机类型. return engine; } public void setEngine(Engine engine) { this.engine = engine; } public abstract void installEngine();//因为每个汽车安装的引擎是不同的. }
package com.ibeifeng.eg3; public class Bus extends Car { public Bus(Engine engine) { super(engine); // TODO Auto-generated constructor stub } @Override public void installEngine() { // TODO Auto-generated method stub System.out.println("Bus:"); this.getEngine().installEngine();//行为实现类接口.Abstraction(Car)接口定义了基于 //Implementor接口(Engine)的更高层次的操作. //除了安装引擎之外,还打印了巴士. } }
package com.ibeifeng.eg3; public class Jeep extends Car { public Jeep(Engine engine) { super(engine); // TODO Auto-generated constructor stub } @Override public void installEngine() { // TODO Auto-generated method stub System.out.println("Jeep:"); this.getEngine().installEngine(); } }
以上是关于第十五讲:桥接模式的主要内容,如果未能解决你的问题,请参考以下文章