第十五讲:桥接模式

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();
    }

}

 

以上是关于第十五讲:桥接模式的主要内容,如果未能解决你的问题,请参考以下文章

雅思基础课程语法基础课程-第十五讲

HTML篇第十五讲:标签属性和属性值

少儿编程Scratch第十五讲,节日放烟花,附带程序

第二十五讲:命令模式

Java编程十五讲第八讲:正则表达式

设计模式(十五)——桥接模式