设计模式之桥接模式
2016-03-08 14:37
274 查看
对象的继承关系是在编译时就定义好了,所以无法在运行时改变从父类继承的实现。
子类的实现与它的父类有非常紧密的依赖关系,以至于父类实现中的任何变化必然会导致子类发生变化。
当你需要复用子类时,如果继承下来的实现不适合解决新的问题,则父类必现重写或被其他更适合的类替换。这种依赖关系限制了灵活性并最终限制了复用性。
合成/聚合复用原则(CARP),尽量使用合成/聚合,尽量不要使用类继承。
聚合表示一种弱的‘拥有’关系,体现的是A对象可以包含B对象,但B对象不是A对象的一部分;
合成则是一种强的‘拥有’关系,体现了严格的部分和整体的关系,部分和整体的生命周期一样。
合成/聚合复用原则的好处是:优先使用对象的合成/聚合将有助于你保持每个类被封装,并被集中在单个任务上。这样类继承层次会保持较小规模,并且不太可能增长为不可控制的庞然大物。
桥接模式(Bridge),将抽象部分与它的实现部分分离,使它们都可以独立地变化。
什么叫抽象与它的实现分离,这并不是说,让抽象类与其派生类分离,因为这没有任何意义。实现指的是抽象类和它的派生类用来实现自己的对象。
Implementor类,实现类接口:
public abstract class Implementor {
public abstract void operation();
}
ConcreteImplementorA和ConcreteImiplementorB等派生类、具体实现类:
public class ConcreteImplementorA extends Implementor {
@Override
public void operation() {
System.out.println("具体实现A的方法执行");
}
}
Abstraction类,抽象类:
public class Abstraction {
protected Implementor mImplementor;
public void setImplementor(Implementor implementor) {
mImplementor = implementor;
}
public void operation() {
mImplementor.operation();
}
}
RefinedAbstraction类,扩充抽象类:
public class RefinedAbstraction extends Abstraction {
@Override
public void operation() {
super.operation();
// 其他代码
}
}
调用:
RefinedAbstraction ab = new RefinedAbstraction();
ab.setImplementor(new ConcreteImplementorA());
ab.operation();
ab.setImplementor(new ConcreteImplementorB());
ab.operation();
输出结果:
具体实现A的方法执行
具体实现B的方法执行
实现系统可能有多角度分类,每一种分类都有可能变化,那么就把这种多角度分离出来让它们独立变化,减少它们之间的耦合。
只要真正深入地理解了设计原则,很多设计模式其实就是原则的应用而已,或许在不知不觉中就在使用设计模式了。
例子:
手机软件抽象类:
public abstract class Soft {
public abstract void softRun();
}
游戏、MP3等具体类:
public class Game extends Soft {
@Override
public void softRun() {
System.out.println("玩游戏");
}
}
手机品牌类:
public abstract class Phone {
protected Soft mSoft;
public void setSoft(Soft soft) {
mSoft = soft;
}
public abstract void phoneRun();
}
品牌具体类:
public class Nubia extends Phone {
@Override
public void phoneRun() {
mSoft.softRun();
}
}
调用:
Nubia nubia = new Nubia();
Game game = new Game();
nubia.setSoft(game);
nubia.phoneRun();
Nokia nokia = new Nokia();
Mp3 mp3 = new Mp3();
nokia.setSoft(mp3);
nokia.phoneRun();
nokia.setSoft(game);
nokia.phoneRun();
输出结果:
玩游戏
播放音乐
玩游戏
子类的实现与它的父类有非常紧密的依赖关系,以至于父类实现中的任何变化必然会导致子类发生变化。
当你需要复用子类时,如果继承下来的实现不适合解决新的问题,则父类必现重写或被其他更适合的类替换。这种依赖关系限制了灵活性并最终限制了复用性。
合成/聚合复用原则(CARP),尽量使用合成/聚合,尽量不要使用类继承。
聚合表示一种弱的‘拥有’关系,体现的是A对象可以包含B对象,但B对象不是A对象的一部分;
合成则是一种强的‘拥有’关系,体现了严格的部分和整体的关系,部分和整体的生命周期一样。
合成/聚合复用原则的好处是:优先使用对象的合成/聚合将有助于你保持每个类被封装,并被集中在单个任务上。这样类继承层次会保持较小规模,并且不太可能增长为不可控制的庞然大物。
桥接模式(Bridge),将抽象部分与它的实现部分分离,使它们都可以独立地变化。
什么叫抽象与它的实现分离,这并不是说,让抽象类与其派生类分离,因为这没有任何意义。实现指的是抽象类和它的派生类用来实现自己的对象。
Implementor类,实现类接口:
public abstract class Implementor {
public abstract void operation();
}
ConcreteImplementorA和ConcreteImiplementorB等派生类、具体实现类:
public class ConcreteImplementorA extends Implementor {
@Override
public void operation() {
System.out.println("具体实现A的方法执行");
}
}
public class ConcreteImplementorB extends Implementor { @Override public void operation() { System.out.println("具体实现B的方法执行"); } }
Abstraction类,抽象类:
public class Abstraction {
protected Implementor mImplementor;
public void setImplementor(Implementor implementor) {
mImplementor = implementor;
}
public void operation() {
mImplementor.operation();
}
}
RefinedAbstraction类,扩充抽象类:
public class RefinedAbstraction extends Abstraction {
@Override
public void operation() {
super.operation();
// 其他代码
}
}
调用:
RefinedAbstraction ab = new RefinedAbstraction();
ab.setImplementor(new ConcreteImplementorA());
ab.operation();
ab.setImplementor(new ConcreteImplementorB());
ab.operation();
输出结果:
具体实现A的方法执行
具体实现B的方法执行
实现系统可能有多角度分类,每一种分类都有可能变化,那么就把这种多角度分离出来让它们独立变化,减少它们之间的耦合。
只要真正深入地理解了设计原则,很多设计模式其实就是原则的应用而已,或许在不知不觉中就在使用设计模式了。
例子:
手机软件抽象类:
public abstract class Soft {
public abstract void softRun();
}
游戏、MP3等具体类:
public class Game extends Soft {
@Override
public void softRun() {
System.out.println("玩游戏");
}
}
public class Mp3 extends Soft { @Override public void softRun() { System.out.println("播放音乐"); } }
手机品牌类:
public abstract class Phone {
protected Soft mSoft;
public void setSoft(Soft soft) {
mSoft = soft;
}
public abstract void phoneRun();
}
品牌具体类:
public class Nubia extends Phone {
@Override
public void phoneRun() {
mSoft.softRun();
}
}
public class Nokia extends Phone { @Override public void phoneRun() { mSoft.softRun(); } }
调用:
Nubia nubia = new Nubia();
Game game = new Game();
nubia.setSoft(game);
nubia.phoneRun();
Nokia nokia = new Nokia();
Mp3 mp3 = new Mp3();
nokia.setSoft(mp3);
nokia.phoneRun();
nokia.setSoft(game);
nokia.phoneRun();
输出结果:
玩游戏
播放音乐
玩游戏
相关文章推荐
- 3D Touch
- 解决ubuntu合盖后无法唤醒
- 分形艺术效果图第二弹
- ORA-31640: unable to open dump file ORA-19505 ORA-27037
- Java虚拟机类加载和执行机制
- ListView嵌套ViewPager事件冲突
- 为什么Java要把字符串设计成不可变的
- 基于SWOOLE的分布式SOCKET消息服务器架构
- libevent入门---定时器程序
- opencv中的阈值函数
- iOS多线程基本概念
- Android Studio 自定义签名,代码段快捷键
- W - stl 的 优先队列 Ⅲ
- Android RecyclerView 使用完全解析 体验艺术般的控件
- Android ImageReader使用
- bluez 协议栈实现3 应用层的协议栈实现分析之glib
- 小技巧收录----唯一ID
- Hierarchical convolutional Features for visual tracking
- 【python】编程语言入门经典100例--26
- mysql 常用操作(整理)