Java设计模式之桥接模式实例详解

本文实例讲述了Java设计模式之桥接模式。分享给大家供大家参考,具体如下:

概念:

桥接模式(Bridge Pattern):将抽象部分与它的实现部分分离,使它们都可以独立地变化。

桥接模式将继承关系转换为关联关系,从而降低了类与类之间的耦合,减少了代码编写量。

什么情况下会用桥接模式?

简单的说就是我们在抽象对象的特征时,对象的特征属性又很抽象,不得不把属性再次抽象。

否则的话,具体子类的数量将会成几何增长,而且不易扩展。没办法维护现有代码。

举例,我们在抽象手机这二个对象时,它的几个属性,如操作系统,cpu,屏幕,运营商网络等都很复杂。我们不能简单的把这几个属性直接定义,必须再次抽象化。而具体的一个手机对象就是这些属性的组合,但不是简单的组合,属性需要实现自己作为属性的功能。在这样的设计下,代码的维护和扩展也就容易了。

注意:在说这个模式的时候,我不能保证说的和写得例子都是正确的,毕竟我也是新接触到,所有例子均基于与个人理解。

我认为的桥接模式说明图:

下面是例子:

1. 首先定义抽象类,抽象和描述对象的特征。

在对象的属性上划分维度,为了以后桥接和扩展。

package test.design.bridge;
public abstract class CellPhone {
  private String cellPhoneName;
  public CellPhoneSystem cellPhoneSystem;
  public CellPhoneCPU cellPhoneCPU;
  public void works(){
    System.out.println("---------------------");
    System.out.println("This cellphone is:"+this.getCellPhoneName()+",welcome to use. ");
    System.out.println("This cellphone detail infomation:");
    System.out.println("系统类型:"+this.getCellPhoneSystem().getSystemName());
    System.out.println("cpu型号:"+this.getCellPhoneCPU().getCpuName());
    System.out.println("---------------------");
  }
  public String getCellPhoneName() {
    return cellPhoneName;
  }
  public void setCellPhoneName(String cellPhoneName) {
    this.cellPhoneName = cellPhoneName;
  }
  public CellPhoneSystem getCellPhoneSystem() {
    return cellPhoneSystem;
  }
  public void setCellPhoneSystem(CellPhoneSystem cellPhoneSystem) {
    this.cellPhoneSystem = cellPhoneSystem;
  }
  public CellPhoneCPU getCellPhoneCPU() {
    return cellPhoneCPU;
  }
  public void setCellPhoneCPU(CellPhoneCPU cellPhoneCPU) {
    this.cellPhoneCPU = cellPhoneCPU;
  }
}

2. 属性维度的抽象。(可以使用接口定义,关键看你的具体功能)

package test.design.bridge;
/**
 * 属性cpu被抽象成一个维度,为了以后扩展
 * @author lushuaiyin
 *
 */
public abstract class CellPhoneCPU {
  public CellPhone cellPhone;
  public String cpuName;
  public void cpuWorks(){
    System.out.println("I am cpu. My pattern is:"+this.getCpuName());
    System.out.println("I am working for this cellphone:"+this.getCellPhone().getCellPhoneName());
  }
  public CellPhone getCellPhone() {
    return cellPhone;
  }
  public void setCellPhone(CellPhone cellPhone) {
    this.cellPhone = cellPhone;
    this.getCellPhone().setCellPhoneCPU(this);// 装配(桥接,或者可以认为对象类与其属性类的传递)
  }
  public String getCpuName() {
    return cpuName;
  }
  public void setCpuName(String cpuName) {
    this.cpuName = cpuName;
  }
}
package test.design.bridge;
/**
 * 属性操作系统被抽象成一个维度,为了以后扩展
 * @author lushuaiyin
 *
 */
public abstract class CellPhoneSystem {
  public CellPhone cellPhone;
  public String SystemName;
  public void systemWorks(){
    System.out.println("I am "+this.getSystemName()+" system.");
    System.out.println("I am working for this cellphone:"+this.getCellPhone().getCellPhoneName());
  }
  public CellPhone getCellPhone() {
    return cellPhone;
  }
  public void setCellPhone(CellPhone cellPhone) {
    this.cellPhone = cellPhone;
    this.getCellPhone().setCellPhoneSystem(this);// 装配(桥接,或者可以认为对象类与其属性类的传递)
  }
  public String getSystemName() {
    return SystemName;
  }
  public void setSystemName(String systemName) {
    SystemName = systemName;
  }
}

3. 具体的维度属性对象。

这里我们在操作系统属性和cpu属性上各定义2个具体对象,

package test.design.bridge;
public class AndroidSystem extends CellPhoneSystem{
}
package test.design.bridge;
public class IOSSystem extends CellPhoneSystem{
}
package test.design.bridge;
/**
 * 双核cpu
 * @author Administrator
 *
 */
public class TwoCore extends CellPhoneCPU{
}
package test.design.bridge;
/**
 * 四核cpu
 * @author Administrator
 *
 */
public class FourCore extends CellPhoneCPU{
}

4. 测试代码。

其中说了在需要扩展维度的情况下,怎么扩展的。

定义一个手机对象

package test.design.bridge;
public class Phone1 extends CellPhone{
  //具体对象的属性与逻辑
}

测试main函数

package test.design.bridge;
public class TestMain {
  /**
   * @param args
   */
  public static void main(String[] args) {
    //任何一种具体的对象都是复杂多种属性的集合,在此可以看出桥接模式在构建对象时的灵活性
    //产生一个具体对象1
    CellPhone p1=new Phone1();
    p1.setCellPhoneName(" IPhone 6 ");
    CellPhoneSystem system1=new IOSSystem();//操作系统属性维度
    system1.setSystemName("ios7");
    system1.setCellPhone(p1);//装配
    system1.systemWorks();//工作
    /*装配说的简单点就是传值。因为我们把一个对象的属性按维度分开来了,
     那么桥接的时候就必须相互传递对象。即对象类可以调用子属相类对象,
     子属性类对象也可以调用该对象类.
     关于这样的传值方式有多种,你可以在构造函数中传递,也可以在
    调用具体逻辑方法时传递。这里我直接用set方法传递,只是为了更清楚.
    如果某个属性维度是必须出现的,那就可以在抽象类的构造函数中传入*/
    CellPhoneCPU cpu1=new TwoCore();//cpu属性维度
    cpu1.setCpuName("A6");
    cpu1.setCellPhone(p1);
    cpu1.cpuWorks();
    p1.works();//最终整体对象功能
    /*
    桥接模式就是为了应对属性的扩展,在此说的属性必须是在维度确定的情况下。
    比如,这里我们在定义手机对象时,确定两个属性维度:操作系统和cpu型号。
    以后再这两个属性中,需要扩展时,就可以使用该模式。比如,一种新的cpu
    型号出现了,那么我不用重新设计现在的代码,只要增添一个cpu类即可。
    如果出现了新的维度属性,比如手机对象必须考虑屏幕大小。那桥接模式
    在此就需要从根本上修改代码来了。
    */
    System.out.println("-----------分割---------------------------");
    //在cpu维度上扩展。比如出现新型cpu:8核三星Exynos 5 Octa芯片".
    //三星手机推出了GALAXY Note Ⅲ就是使用这种新型cpu. 写一个新类EightCore扩展cpu维度.
    //同时定义这个手机对象GALAXY Note Ⅲ为PhoneGalaxyNote3
    CellPhone note3=new PhoneGalaxyNote3();
    note3.setCellPhoneName("GALAXY Note Ⅲ");
    CellPhoneSystem system2=new AndroidSystem();
    system2.setSystemName("android4");
    system2.setCellPhone(note3);//装配
    system2.systemWorks();//工作
    CellPhoneCPU cpu2=new EightCore();//最新8核cpu
    cpu2.setCpuName("三星Exynos 5 Octa芯片");
    cpu2.setCellPhone(note3);
    cpu2.cpuWorks();
    note3.works();//三星GALAXY Note Ⅲ新体验
  }
}

如果需要扩展,定义新的维度属性

package test.design.bridge;
public class EightCore extends CellPhoneCPU {
}
package test.design.bridge;
public class PhoneGalaxyNote3 extends CellPhone{
  //具体对象的属性与逻辑
}

测试打印;

I am ios7 system.
I am working for this cellphone: IPhone 6
I am cpu. My pattern is:A6
I am working for this cellphone: IPhone 6
---------------------
This cellphone is: IPhone 6 ,welcome to use.
This cellphone detail infomation:
系统类型:ios7
cpu型号:A6
---------------------
-----------分割---------------------------
I am android4 system.
I am working for this cellphone:GALAXY Note Ⅲ
I am cpu. My pattern is:三星Exynos 5 Octa芯片
I am working for this cellphone:GALAXY Note Ⅲ
---------------------
This cellphone is:GALAXY Note Ⅲ,welcome to use.
This cellphone detail infomation:
系统类型:android4
cpu型号:三星Exynos 5 Octa芯片
---------------------

更多java相关内容感兴趣的读者可查看本站专题:《Java数据结构与算法教程》、《Java操作DOM节点技巧总结》、《Java文件与目录操作技巧汇总》和《Java缓存操作技巧汇总》

希望本文所述对大家java程序设计有所帮助。

(0)

相关推荐

  • Java设计模式之建造者模式实例详解

    本文实例讲述了Java设计模式之建造者模式.分享给大家供大家参考,具体如下: 建造者模式(builder)可以将部件和其组装过程分开.一步一步创建一个复杂的对象. 用户只需要指定复杂对象的类型就可以得到该对象,而无须知道其内部的具体构造细节. 什么情况下会用到建造者模式? 个人理解,当我们创建的对象在创建时需要逻辑的时候. 比如,一个简单的pojo对象,我们想要创建,直接就可以new出来,没有什么逻辑. 当有一个复杂的对象,你想要创建它时,它的各个属性之间是有逻辑关系的. 一个属性赋值取值依赖于

  • java中设计模式之适配器模式

    java中设计模式之适配器模式  前言: 适配器模式可以将一个类或接口应用于另一个不同但是却有联系的接口,主要的做法是通过声明一个目标接口的实现类,在该类中声明一个将被适配类或接口(被适配者)作为参数的构造器和被适配者的实例,这样在实现目标接口的时候就可以调用被适配者的实例,并且辅以一些额外的操作.适配器模式的主体有三个部分:适配者,适配者实现类和被适配者.具体类结构如下图: 这里将被适配者的对象以组合的方式放到适配器类中,那么被适配者及其实现者都可以使用该适配器.适配器模式的优点在于可以将不同

  • Java设计模式之代理模式与装饰模式实例详解

    本文实例讲述了Java设计模式之代理模式与装饰模式.分享给大家供大家参考,具体如下: 之所以把这两种模式放在一起说,是因为我发现这了两种模式几乎一模一样! 从网上也搜了一些资料,发现两者还是有一些区别的.我们在学习的同时也把这种困惑搞清楚. 定义: 代理模式,为其他对象提供一种代理以控制对这个对象的访问. 装饰模式,动态地给一个对象添加一些额外的职责. 代理模式,很好理解,就是把一个对象再次封装,以后就对封装的对象访问就可以了. 因为代理对象已经取代了被代理对象. 装饰模式,给一个对象增加功能,

  • Java设计模式之单例模式实例详解【懒汉式与饿汉式】

    本文实例讲述了Java设计模式之单例模式.分享给大家供大家参考,具体如下: 单例模式就是产生一个对象实例,供外外部访问. 它的应用场景就是在这个类在全局真资源需要统一访问,否则会造成混乱时,才有必要设计成单例. 懒汉式,就是在使用这个对象时,才去查看这个对象是否创建,如果没创建就马上创建,如果已经创建,就返回这个实例. 饿汉式,在加载这个类的时候就先创建好一个对象实例,等待调用. 两者的优缺点也能猜到,使用懒汉式,在反应速度上肯定要比饿汉式慢. 但是这个对象如果不被调用,那就节省了cpu和内存资

  • Java设计模式笔记之抽象工厂代码示例

    上一篇说到了工厂模式,那么学习了工厂模式,抽象工厂也得学习一下.实际上,抽象工厂模式实际上就是在工厂模式的基础上再嵌套一层工厂模式而已,通过父工厂制造子工厂.只是,也并不完全是嵌套一层,各个工厂会被抽象成一个集多个工厂共同点的抽象类.通过工厂制造器,创建出该抽象工厂的子类. 好比如说,一个博客页面有个换肤系统.那么假如有两套风格,黑和白.那么,我选择了黑色风格的,实际这步就相当通过换肤系统这个工厂制造器,创建出一个黑色主题的工厂,该黑色主题的工厂内可以生产各种黑色风格的产品,比如黑色头像挂饰,黑

  • Java设计模式之桥接模式实例详解

    本文实例讲述了Java设计模式之桥接模式.分享给大家供大家参考,具体如下: 概念: 桥接模式(Bridge Pattern):将抽象部分与它的实现部分分离,使它们都可以独立地变化. 桥接模式将继承关系转换为关联关系,从而降低了类与类之间的耦合,减少了代码编写量. 什么情况下会用桥接模式? 简单的说就是我们在抽象对象的特征时,对象的特征属性又很抽象,不得不把属性再次抽象. 否则的话,具体子类的数量将会成几何增长,而且不易扩展.没办法维护现有代码. 举例,我们在抽象手机这二个对象时,它的几个属性,如

  • Java设计模式中桥接模式应用详解

    目录 1.桥接(Bridge)设计模式定义 2.桥接设计模式优点以及不足 3.桥接设计的实现思路 4.桥接设计模式示例 5.桥接模式的应用场景 6.桥接设计模式和适配器设计模式对比 编程是一门艺术,大批量的改动显然是非常丑陋的做法,用心的琢磨写的代码让它变的更美观. 显示生活中有物品具有多个维度的属性,比如文字有颜色和字体两个维度的差别,汽车有颜色和牌子两个维度的属性等.如果用继承方式,不但对应的子类很多,而且扩展困难.如果用桥接模式就能很好地解决这些问题. 1.桥接(Bridge)设计模式定义

  • Java设计模式之监听器模式实例详解

    本文实例讲述了Java设计模式之监听器模式.分享给大家供大家参考,具体如下: 监听器模式有三个要素--事件源.事件对象.监听器. 事件源:顾名思义,事件发生的源头,比如点击的按钮,属于被监听的对象: 事件对象:这个经常和事件源混淆,它经常被用来包装事件源,切记,它毕竟是个事件,比如点击事件,和事件源的区别自己感受,木有栗子: 监听器:这个是监听器模式的核心,定义事件发生后的动作,通常事件对象作为监听器中定义的函数入参. 下面举个简单的栗子: 故事背景是,小明是个不讲卫生的孩子,他妈妈很担心他的健

  • java设计模式之工厂模式实例详解

    本文实例讲述了java设计模式之工厂模式.分享给大家供大家参考,具体如下: 工厂模式(factory) 涉及到4个角色:抽象工厂类角色,具体工厂类角色,抽象产品类角色和具体产品类角色. 抽象工厂类角色使用接口或者父类来描述工厂的行为, 具体工厂类角色负责创建某一类型的产品对象. 抽象产品类可以使用接口或者父类来描述产品对象的行为特征. 具体产品类就是某一具体的对象. 工厂模式不同于静态工厂模式的地方: 工厂模式在工厂类也实现了多态,而不仅仅是在产品对象上实现多态. 它可以应对不同类型的产品对应一

  • Java设计模式之工厂模式案例详解

    目录 分类 案例 需求 方案一:简单工厂模式 方案二:工厂方法模式 方案三:抽象工厂模式 对比分析 总结 分类 1.简单工厂模式 2.工厂方法模式 3.抽象工厂模式 案例 需求 根据蛋糕的不同口味,分别创建苹果味和香蕉味的蛋糕实例 方案一:简单工厂模式 定义蛋糕父类 /** * 蛋糕 * @author:liyajie * @createTime:2022/2/14 10:17 * @version:1.0 */ public class Cake { } 定义苹果味的蛋糕 /** * 苹果蛋糕

  • Java设计模式之外观模式示例详解

    目录 定义 案例 需求 方案:外观模式实现 分析 总结 定义 外观模式为多个复杂的子系统,提供了一个一致的界面,使得调用端只和这个接口发生调用,而无须关系这个子系统内部的细节 案例 需求 看电影的时候需要进行一系列的操作,比如打开播放器,放下屏幕,打开投影仪,打开音响等,这个要怎么进行管理呢 方案:外观模式实现 定义播放器类 public class Player { private static Player player = new Player(); private Player(){}

  • Java设计模式之策略模式示例详解

    目录 定义 结构 UML类图 UML序列图 深入理解策略模式 策略和上下文的关系 策略模式在JDK中的应用 该策略接口有四个实现类 策略模式的优点 策略模式的缺点 策略模式的本质 在讲策略模式之前,我们先看一个日常生活中的小例子: 现实生活中我们到商场买东西的时候,卖场往往根据不同的客户制定不同的报价策略,比如针对新客户不打折扣,针对老客户打9折,针对VIP客户打8折... 现在我们要做一个报价管理的模块,简要点就是要针对不同的客户,提供不同的折扣报价. 如果是有你来做,你会怎么做? 我们很有可

  • Java设计模式之策略模式案例详解

    目录 优缺点 Spring中哪里使用策略模式 策略模式设计图 代码案例 为什么使用策略模式? 答:策略模式是解决过多if-else (或者switch-case)代码块的方法之一,提高代码的可维护性.可扩展性和可读性. 优缺点 优点 算法可以自由切换(高层屏蔽算法,角色自由切换). 避免使用多重条件判断(如果算法过多就会出现很多种相同的判断,很难维护) 扩展性好(可自由添加取消算法而不影响整个功能). 缺点 策略类数量增多(每一个策略类复用性很小,如果需要增加算法,就只能新增类).所有的策略类都

  • Java桥接模式实例详解【简单版与升级版】

    本文实例讲述了Java桥接模式.分享给大家供大家参考,具体如下: 桥接模式简单版 一 代码 class Meal { protected MealImp imp; public Meal() { imp = new AmericanMealImp(); } public Meal(String type) { if (type.equals("American")) imp = new AmericanMealImp(); if (type.equals("Italian&q

随机推荐