江苏赛孚建设工程有限公司网站,数据分析培训机构哪家好,国外优秀个人网站欣赏,西安市城乡建设管理局网站6引用
桥我们大家都熟悉#xff0c;顾名思义就是用来将河的两岸联系起来的。而此处的桥是用来将两个独立的结构联系起来#xff0c;而这两个被联系起来的结构可以独立的变化#xff0c;所有其他的理解只要建立在这个层面上就会比较容易。
基本介绍
桥接模式#xff08;Br…引用
桥我们大家都熟悉顾名思义就是用来将河的两岸联系起来的。而此处的桥是用来将两个独立的结构联系起来而这两个被联系起来的结构可以独立的变化所有其他的理解只要建立在这个层面上就会比较容易。
基本介绍
桥接模式Bridge是指将实现与抽象放在两个不同的类层次中是两个层次可以独立改变。该模式基于类的最小设计原则扩展功能时尽量少的增加类通过使用封装、聚合、继承等行为让不同的类承担不同的职责。主要特点是把抽象和行为实现分离开来从而可以保持各部分的独立性以及对他们的功能扩展。桥梁模式的用意是将抽象化与实现化脱耦使得二者可以独立地变化。
原理类图 桥接Bridge模式包含以下主要角色 client:桥接模式的调用者 Implementor实现化角色它是接口或者抽象类定义角色必需的行为和属性这个接口不一定要与Abstraction的接口完全一致事实上这两个接口可以完全不同一般而言Implementor接口仅提供基本操作而Abstraction定义的接口可能会做更多更复杂的操作。Implementor接口对这些基本操作进行了声明而具体实现交给其子类。通过关联关系Abstraction不仅拥有自己的方法还可以调用Implementor中定义的方法使用关联关系来替代继承关系ConcreteImplementor具体实现化角色实现接口或抽象类定义的方法或属性。在不同的ConcreteImplementor中提供基本操作的不同实现在程序运行时ConcreteImplementor对象将替换其父类对象提供给抽象类具体的业务操作方法Abstraction抽象化角色定义出该角色的行为同时保存一个对实现化角色的引用它一般是抽象类而不是接口其中定义了一个Implementor实现类接口类型的对象并可以维护该对象它与Implementor之间具有关联关系它既可以包含抽象业务方法也可以包含具体业务方法RefinedAbstraction扩充抽象类角色引用实现化角色对抽象化角色进行扩充。通常情况下它不再是抽象类而是具体类它实现了在Abstraction中声明的抽象业务方法在RefinedAbstraction中可以调用在Implementor中定义的业务方法
从UML图看这里的抽象类和接口是聚合关系就是调用和被调用的关系RefinedAbstraction的父类聚合了接口RefinedAbstraction调用接口的具体实现
优缺点
通过上面的讲解我们能很好的感觉到桥接模式遵循了里氏替换原则和依赖倒置原则最终实现了开闭原则对修改关闭对扩展开放。这里将桥接模式的优缺点总结如下。
优点
分离抽象接口及其实现部分。桥接模式使用“对象间的关联关系”解耦了抽象和实现之间固有的绑定关系使得抽象和实现可以沿着各自的维度来变化。所谓抽象和实现沿着各自维度的变化也就是说抽象和实现不再在同一个继承层次结构中而是“子类化”它们使它们各自都具有自己的子类以便任何组合子类从而获得多维度组合对象。在很多情况下桥接模式可以取代多层继承方案多层继承方案违背了“单一职责原则”复用性较差且类的个数非常多桥接模式是比多层继承方案更好的解决方法它极大减少了子类的个数。桥接模式提高了系统的可扩展性在两个变化维度中任意扩展一个维度都不需要修改原有系统符合“开闭原则”。
缺点
桥接模式的使用会增加系统的理解与设计难度由于关联关系建立在抽象层要求开发者一开始就针对抽象层进行设计与编程。桥接模式要求正确识别出系统中两个独立变化的维度因此其使用范围具有一定的局限性如何正确识别两个独立维度也需要一定的经验积累。
模式的实现
桥接模式的代码如下
package bridge;
public class BridgeTest {public static void main(String[] args) {Implementor imple new ConcreteImplementorA();Abstraction abs new RefinedAbstraction(imple);abs.Operation();}
}
//实现化角色
interface Implementor {public void OperationImpl();
}
//具体实现化角色
class ConcreteImplementorA implements Implementor {public void OperationImpl() {System.out.println(具体实现化(Concrete Implementor)角色被访问);}
}
//抽象化角色
abstract class Abstraction {protected Implementor imple;protected Abstraction(Implementor imple) {this.imple imple;}public abstract void Operation();
}
//扩展抽象化角色
class RefinedAbstraction extends Abstraction {protected RefinedAbstraction(Implementor imple) {super(imple);}public void Operation() {System.out.println(扩展抽象化(Refined Abstraction)角色被访问);imple.OperationImpl();}
}
程序的运行结果如下
扩展抽象化(Refined Abstraction)角色被访问
具体实现化(Concrete Implementor)角色被访问
案例场景模拟
假设设计一个日志系统这个系统可以记录多种日志类型如交易日志数据库日志用户操作日志等同时这个系统还支持多种日志的表现形式。如xml文件文本文件数据库库数据E-mail等。 抽象日志的种类。 实现日志的表现方式。
实现代码如下
Log源代码
public abstract class Log{protected LogSave logSave;public Log(LogSave logSave){this.logSavelogSave;}public abstract void writeToLog();
}
LogSave源代码
public abstract class LogSave{public abstract void write();
}
下面是三个Log的子类
TradLog源代码
public class TradLog extends Log{public TradLog(LogSave logSave){super(logSave);}Overridepublic void writeToLog(){System.out.println(写入TradLog数据)this.logSave.write();}
}
DbLog源代码
public class DbLog extends Log{public DbLog(LogSave logSave){super(logSave);}Overridepublic void writeToLog(){System.out.println(写入DbLog数据)this.logSave.write();}
}
UserLog源代码
public class UserLog extends Log{public UserLog(LogSave logSave){super(logSave);}Overridepublic void writeToLog(){System.out.println(写入UserLog数据)this.logSave.write();}
}
下面是LogSave的三个实现类
XmlImpl源代码
public class XmlImpl extends LogSave{Overridepublic void write(){System.out.println(使用xml方式存储)}
}
TextImpl源代码
public class TextImpl extends LogSave{Overridepublic void write(){System.out.println(使用文本方式存储)}
} EmailImpl源代码
public class EmailImpl extends LogSave{Overridepublic void write(){System.out.println(使用发邮件的方式存储)}
}
实现不能和抽象发生耦合而只能由抽象和实现发生耦合。
下面是启动类展示最终结果
Client源代码
public class Client{public static void main(String[] args){Log lognew UserLog(new XmlImpl());log.writeToLog();Log log2new DbLog(new EmailImpl());log2.writeToLog();}
}
运行结果如下 写入UserLog数据 使用xml方式存储 写入DbLog数据 使用发邮件的方式存储 应用场景
如果一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性避免在两个层次之间建立静态的继承联系通过桥接模式可以使它们在抽象层建立一个关联关系。对于那些不希望使用继承或因为多层次继承导致系统类的个数急剧增加的系统桥接模式尤为适用。一个类存在两个独立变化的维度且这两个维度都需要进行扩展。常用的场景 JDBC驱动程序日志框架银行转账系统 转账分类网上转账、柜台转账、ATM转账用户类型普通用户、银卡用户、金卡用户消息管理 消息类型即时消息、延时消息消息分类手机短信、邮件信息、QQ消息
桥接模式模式的扩展
在软件开发中有时桥接Bridge模式可与适配器模式联合使用。当桥接Bridge模式的实现化角色的接口与现有类的接口不一致时可以在二者中间定义一个适配器将二者连接起来其具体结构图如图桥接模式与适配器模式联用的结构图所示。 小结
对于系统的高层来说只需要知道抽象部分和实现部分的接口就够了其他部分由具体业务来完成桥接模式代替多层继承方案可以减少子类的个数降低系统的管理和维护成本桥接模式要求正确识别出系统中的两个独立变化维度因此其使用范围有一定的局限性适用于一定的应用场景