1、桥接模式介绍
桥接是什么?是指在传统的抽象与实现之间建立一个桥梁,使它们各自分开,消除他们之间的依赖关系,使它们各自富于变化,而不相互不受影响。也就是说桥接模式将抽象和行为划分开来,各自独立,但能动态地结合。
桥接模式的定义:是对象结构型模式(接口模式/柄体模式)、将抽象部分与它的实现部分分离,使它们都可以独立地变化。
桥接模式将抽象化与实现化解耦:
抽象化:存在多个实体中的共同的概念性联系。
实现化:将抽象化给出的具体实现。
2、举例实现
在软件系统中,某些类型由于自身的逻辑,它具有两个或多个维度的变化,那么如何应对这种“多维度的变化”?如何利用面向对象的技术来使得该类型能够轻松的沿着多个方向进行变化,而又不引入额外的复杂度?这就要使用Bridge模式。
例子说明:一个日志系统中、有三种记录日志的方式(数据库记录、文本记录、XML文件记录)、两种平台来实现日志系统。如果说按照我们传统的做法、是不是一个平台下有三种记录日志的方式、我们得设计几个类?
这个UML类图告诉我们,如果按照传统的做法,我们至少需要10个类。添加了设计者的麻烦、也不符合设计原则。那么桥接模式将如何去实现这个日志系统呢?看看用桥接模式构造后的类图。
角色说明:
1、抽象化角色:是桥接是抽象化类、包含实现具体的行为,特征和ImplLog接口。
2、修正抽象化角色:是继承抽象的子类,改变和修正父类对抽象化的定义。
3、实现化角色:模板目标接口类,给出实现化的接口,不具体实现。
4、具体实现化角色:目标实现类,是实现化角色的具体实现。
3、Java代码实现
3.1、抽象化角色
package com.czy.bride;
//日志抽象类
public abstract class Log {
//组合
protected ImplLogs implLogs;
public Log( ImplLogs implLogs){
this.implLogs = implLogs;
}
//日志的抽象方法
public abstract void wirter(String log);
}
3.2、实现化角色
package com.czy.bride;
//平台的抽象类
public abstract class ImplLogs {
//平台的抽象方法
public abstract void pingtai(String imlog);
}
3.3、具体实现化角色
package com.czy.bride;
//Java平台的抽象类实现
public class ImplLogsJava extends ImplLogs {
@Override
public void pingtai(String imlog) {
// TODO Auto-generated method stub
System.out.println("Java平台上实现日志记录"+imlog);
}
}
3.3、具体实现化角色
package com.czy.bride;
//net平台的抽象类实现
public class ImplLogsNet extends ImplLogs {
@Override
public void pingtai(String imlog) {
// TODO Auto-generated method stub
System.out.println("Net平台上实现日志记录"+imlog);
}
}
3.4、实现化角色
package com.czy.bride;
//数据库的方式日志的抽象类实现
public class LogDataBase extends Log {
@Override
public void wirter(String log) {
// TODO Auto-generated method stub
implLogs.pingtai("使用数据库的方式:"+log);
}
public LogDataBase(ImplLogs implLogs) {
super(implLogs);
// TODO Auto-generated constructor stub
}
}
3.4、实现化角色
package com.czy.bride;
//文本的方式日志的抽象类实现
public class LogTestFile extends Log {
@Override
public void wirter(String log) {
// TODO Auto-generated method stub
implLogs.pingtai("使用文本的方式:"+log);
}
public LogTestFile(ImplLogs implLogs) {
super(implLogs);
// TODO Auto-generated constructor stub
}
}
4、测试类
public class BridgeTest {
//main
public static void main(String[] args) {
//2种平台对象
ImplLogs jimplLogs = new ImplLogsJava();
//java平台日志实现
Log jdlog = new LogDataBase(jimplLogs);
Log jflog2 = new LogTestFile(jimplLogs);
jdlog.wirter("DB 记录");
jflog2.wirter("Text 记录");
//2种平台对象
ImplLogs nimplLogs = new ImplLogsNet();
//.net平台日志实现
Log nflog = new LogTestFile(nimplLogs);
Log ndlog2 = new LogDataBase(nimplLogs);
nflog.wirter("Text 记录");
ndlog2.wirter("DB 记录");
}
}
5、新添加的一个平台
5.1、具体实现化角色
package com.czy.bride;
//添加一个新的平台
public class ImplLogsAdd_PHP extends ImplLogs {
@Override
public void pingtai(String imlog) {
// TODO Auto-generated method stub
System.out.println("新添加的PHP平台、"+imlog);
}
}
6、测试
package com.czy.bride;
public class BridgeTest {
//main
public static void main(String[] args) {
//2种平台对象
ImplLogs jimplLogs = new ImplLogsJava();
//java平台日志实现
Log jdlog = new LogDataBase(jimplLogs);
Log jflog2 = new LogTestFile(jimplLogs);
jdlog.wirter("DB 记录");
jflog2.wirter("Text 记录");
//2种平台对象
ImplLogs nimplLogs = new ImplLogsNet();
//.net平台日志实现
Log nflog = new LogTestFile(nimplLogs);
Log ndlog2 = new LogDataBase(nimplLogs);
nflog.wirter("Text 记录");
ndlog2.wirter("DB 记录");
//新添加PHP平台
ImplLogs php = new ImplLogsAdd_PHP();
Log pd= new LogDataBase(php);
Log pf = new LogTestFile(php);
System.out.println();
System.out.println("新添加的PHP平台、只需继承ImplLogs抽象类就好了!");
pd.wirter("DB 记录");
pf.wirter("Text 记录");
}
}
上面用了对象组合的关系、解耦了抽象和实现类之间的固有的绑定关系,使得抽象类与实现可以各自变化。