重学java23种设计模式(7)桥接模式
2015-07-28 16:46
357 查看
跟着《软件秘笈---设计模式那点事》学习
预热:
一个各种开关,各种灯泡,中间一种电线的故事
定义:
将抽象与实现分离,使他们都可以独立变化。
在软件系统中,某些类型由于自身的逻辑,它具有两个或多个维度的变化,那么如何应对这种“多维度的变化”?这就要使用桥接模式,桥接模式使得软件系统能够轻松沿着多个方象进行变化,而又不引入额外的复杂度。
桥接模式的用意是,将抽象化与实现化解耦,使得二者可以独立地变化,关键词,抽象化,实现化,解耦。
很显然,将继承改为聚合就是上面说的抽象和实现之间的解耦,从而使两者可以独立变化。
角色:
开关,电灯,电线
类图:
实例:
首先用继承的方式实现电灯与开关,也就是电灯继承开关。
/*
* 开关基类(预告:子类是电灯)
* */
public abstract class AbsSwitch {
// 打开开关
public abstract void turnOn();
// 照明
public abstract void light();
// 关闭开关
public abstract void turnOff();
// 开灯照明
public final void makeLight(){
this.turnOn();
this.light();
this.turnOff();
}
}
public class Client {
public static void main(String[] args) {
//白炽灯实例
AbsSwitch light = new IncandescentLight();
//水晶灯实例
CrystalLight light2 = new CrystalLight();
System.out.println("-----一般开关-----");
light.makeLight();
System.out.println("\n-----遥控开关-----");
light2.makeRemoteLight(1);
}
}
很显然,水晶灯的开关无法控制白炽灯,白炽灯的开关无法控制水晶灯。
看看桥接模式的开关
电灯有自己的接口,开关有自己的基类,开关基类持有电灯接口,并通过构造方法注入。
package com.demo.bridge.lights;
/**
* 电灯接口
*/
public interface ILight {
// 接通电流
public void electricConnected();
// 照明
public void light();
// 断开电流
public void electricClosed();
}
下面是白炽灯和水晶灯。
public class IncandescentLight implements ILight {
@Override
public void electricConnected() {
System.out.println("白炽灯打开了。。。。。");
}
@Override
public void light() {
System.out.println("白炽灯照明");
}
@Override
public void electricClosed() {
System.out.println("白炽灯关闭");
}
}
客户端:
import com.demo.bridge.lights.CrystalLight;
import com.demo.bridge.lights.ILight;
import com.demo.bridge.lights.IncandescentLight;
import com.demo.bridge.switchs.BaseSwitch;
import com.demo.bridge.switchs.RemoteControlSwitch;
public class Client4Bridge {
public static void main(String[] args) {
//白炽灯实例
ILight light1= new IncandescentLight();
//水晶灯实例
ILight light2 = new CrystalLight();
System.out.println("-----一般开关-----");
BaseSwitch switch1 = new BaseSwitch(light1);
switch1.makeLight();
System.out.println("\n-----遥控开关-----");
RemoteControlSwitch switch2 = new RemoteControlSwitch(light2);
switch2.makeRemoteLight(1);
System.out.println("\n-----让遥控开关开关白炽灯-----");
RemoteControlSwitch switch3 = new RemoteControlSwitch(light1);
switch3.makeRemoteLight(1);
}
}
分析:
我认为软件秘籍里面这个例子很形象,电灯开关的继承关系太牵强,但又的确有可能被当做继承使用。
解决方案就是开关持有灯的引用,通过构造方法注入。
使用场合:
(1)不希望抽象类和它的实现部分之间有一个固定的绑定关系。
(2)类的抽象及实现都应该通过生成子类的方法加以扩充。
(3)对一个抽象的实现部分修改应对客户不产生影响,即客户的代码不必重新编译。
一句话总结:
所谓继承对象之间解耦,就是不用继承改用组合。
Java SDK中的原型模式:
java.utli.logging中的Handler和Formatter类。
参考资料:
《软件秘笈---设计模式那点事》
预热:
一个各种开关,各种灯泡,中间一种电线的故事
定义:
将抽象与实现分离,使他们都可以独立变化。
在软件系统中,某些类型由于自身的逻辑,它具有两个或多个维度的变化,那么如何应对这种“多维度的变化”?这就要使用桥接模式,桥接模式使得软件系统能够轻松沿着多个方象进行变化,而又不引入额外的复杂度。
桥接模式的用意是,将抽象化与实现化解耦,使得二者可以独立地变化,关键词,抽象化,实现化,解耦。
很显然,将继承改为聚合就是上面说的抽象和实现之间的解耦,从而使两者可以独立变化。
角色:
开关,电灯,电线
类图:
实例:
首先用继承的方式实现电灯与开关,也就是电灯继承开关。
/*
* 开关基类(预告:子类是电灯)
* */
public abstract class AbsSwitch {
// 打开开关
public abstract void turnOn();
// 照明
public abstract void light();
// 关闭开关
public abstract void turnOff();
// 开灯照明
public final void makeLight(){
this.turnOn();
this.light();
this.turnOff();
}
}
/* * 白炽灯 * */ public class IncandescentLight extends AbsSwitch { @Override public void turnOn() { System.out.println("白炽灯打开了。。。。。"); } @Override public void light() { System.out.println("白炽灯照明"); } @Override public void turnOff() { System.out.println("白炽灯关闭"); } }
/* * 水晶灯 * */ public class CrystalLight extends AbsSwitch { @Override public void turnOn() { System.out.println("水晶灯打开了。。。。。"); } @Override public void light() { System.out.println("水晶灯照明"); } @Override public void turnOff() { System.out.println("水晶灯关闭"); } /* * 使用遥控开关控制开灯和颜色 */ public final void makeRemoteLight(int openColor) { // 打开开关接同电流 this.turnOn(); // 照明 this.light(); String color = ""; switch (openColor) { case 1: color = "暖色"; break; case 2: color = "蓝色"; break; case 3: color = "红色"; break; default: color = "白色"; break; } System.out.println("现在是:" +color + "。。。。。" ); //断开开关关闭电流 this.turnOff(); } }
public class Client {
public static void main(String[] args) {
//白炽灯实例
AbsSwitch light = new IncandescentLight();
//水晶灯实例
CrystalLight light2 = new CrystalLight();
System.out.println("-----一般开关-----");
light.makeLight();
System.out.println("\n-----遥控开关-----");
light2.makeRemoteLight(1);
}
}
很显然,水晶灯的开关无法控制白炽灯,白炽灯的开关无法控制水晶灯。
看看桥接模式的开关
电灯有自己的接口,开关有自己的基类,开关基类持有电灯接口,并通过构造方法注入。
package com.demo.bridge.lights;
/**
* 电灯接口
*/
public interface ILight {
// 接通电流
public void electricConnected();
// 照明
public void light();
// 断开电流
public void electricClosed();
}
/* * 开关基类 * */ public class BaseSwitch { //使用组合,设置ILight为内部私有属性,此为桥梁 protected ILight light; //用构造方法将外部light注入进来 public BaseSwitch(ILight light) { this.light = light; } //开关灯方法 public final void makeLight(){ this.light.electricConnected(); this.light.light(); this.light.electricClosed(); } }
下面是白炽灯和水晶灯。
public class IncandescentLight implements ILight {
@Override
public void electricConnected() {
System.out.println("白炽灯打开了。。。。。");
}
@Override
public void light() {
System.out.println("白炽灯照明");
}
@Override
public void electricClosed() {
System.out.println("白炽灯关闭");
}
}
/* * 水晶灯 * */ public class CrystalLight implements ILight { @Override public void electricConnected() { System.out.println("水晶灯打开了。。。。。"); } @Override public void light() { System.out.println("水晶灯照明"); } @Override public void electricClosed() { System.out.println("水晶灯关闭"); } }
import com.demo.bridge.lights.ILight; /* * 水晶灯开关 * */ public class RemoteControlSwitch extends BaseSwitch { //构造方法注入 public RemoteControlSwitch(ILight light) { super(light); } /* * 使用遥控开关控制开灯和颜色 */ public final void makeRemoteLight(int openColor) { // 打开开关接同电流 this.light.electricConnected(); // 照明 this.light.light(); String color = ""; switch (openColor) { case 1: color = "暖色"; break; case 2: color = "蓝色"; break; case 3: color = "红色"; break; default: color = "白色"; break; } System.out.println("现在是:" +color + "。。。。。" ); //断开开关关闭电流 this.light.electricClosed(); } }
客户端:
import com.demo.bridge.lights.CrystalLight;
import com.demo.bridge.lights.ILight;
import com.demo.bridge.lights.IncandescentLight;
import com.demo.bridge.switchs.BaseSwitch;
import com.demo.bridge.switchs.RemoteControlSwitch;
public class Client4Bridge {
public static void main(String[] args) {
//白炽灯实例
ILight light1= new IncandescentLight();
//水晶灯实例
ILight light2 = new CrystalLight();
System.out.println("-----一般开关-----");
BaseSwitch switch1 = new BaseSwitch(light1);
switch1.makeLight();
System.out.println("\n-----遥控开关-----");
RemoteControlSwitch switch2 = new RemoteControlSwitch(light2);
switch2.makeRemoteLight(1);
System.out.println("\n-----让遥控开关开关白炽灯-----");
RemoteControlSwitch switch3 = new RemoteControlSwitch(light1);
switch3.makeRemoteLight(1);
}
}
分析:
我认为软件秘籍里面这个例子很形象,电灯开关的继承关系太牵强,但又的确有可能被当做继承使用。
解决方案就是开关持有灯的引用,通过构造方法注入。
使用场合:
(1)不希望抽象类和它的实现部分之间有一个固定的绑定关系。
(2)类的抽象及实现都应该通过生成子类的方法加以扩充。
(3)对一个抽象的实现部分修改应对客户不产生影响,即客户的代码不必重新编译。
一句话总结:
所谓继承对象之间解耦,就是不用继承改用组合。
Java SDK中的原型模式:
java.utli.logging中的Handler和Formatter类。
参考资料:
《软件秘笈---设计模式那点事》
相关文章推荐
- Java获取一个小时前的时间
- Eclipse打包过程
- SSH整合抛异常:action未发现
- java indexof 与split
- Eclipse调整字体
- LeetCode算法题3:Longest Substring Without Repeating Characters
- LeetCode算法题2:Add Two Numbers
- eclipse 快捷键
- JAVA技术实现上传下载文件到FTP服务器(完整)
- MyEclipse 快捷键
- myeclipse10破解 run.bat文件打不开、闪退问题
- eclipse中git分支创建与合并(-)
- java-事件监听
- Eclipse 打开js文件时出现 Could not open the editor...
- mac下java环境变量配置
- 单例模式(Singleton)
- 使用Maven构建Web应用(上)
- [LeetCode][Java] Word Ladder II
- 遇到myeclipse加载中突然退掉
- 【Java】不使用中间变量,如何交换两个数?