设计模式-桥接模式
桥接模式
文章目录
- 桥接模式
- 什么是桥接模式
- 为什么要用桥接模式
- 如何实现桥接模式
- 总结
什么是桥接模式
桥接(Bridge)模式的定义如下:将抽象与实现分离,使它们可以独立变化。它是用组合关系代替继承关系来实现,从而降低了抽象和实现这两个可变维度的耦合度。
为什么要用桥接模式
桥接模式可以通过组合代替继承的方式,极大的减少类的数量。举例如下:现在我们有大、中、小三种笔,同时又有红、黄、蓝三种颜色,想要组合成各种颜色各种型号的笔,方案有两种:
一种是多层继承(java只支持单继承,多实现):
一种是将颜色与类型组合,即桥接模式:
通过上面的例子我们可以发现,在使用桥接模式之前我们需要使用9个类来完成x色x笔的创建,假如新增一个颜色或者新增一个类型,那么需要响应的增加3个类来完成x色x笔的创建,这显然是不合适的。
而桥接模式的使用,通过组合的方式减少了类的创建。
如何实现桥接模式
我们将上面的代码通过代码来展示:
//抽象类
public abstract class Pen {protected Color color;public void setColor(Color color) {this.color = color;}public abstract void draw(String name);
}//扩充抽象类
public class SmallPen extends Pen {public void draw(String name) {String penType = "小号毛笔绘制";this.color.bepaint(penType, name);}
}//扩充抽象类
public class MiddlePen extends Pen {public void draw(String name) {String penType = "中号毛笔绘制";this.color.bepaint(penType, name);}
}//扩充抽象类
public class BigPen extends Pen {public void draw(String name) {String penType = "大号毛笔绘制";this.color.bepaint(penType, name);}
}//实现类接口
public interface Color {void bepaint(String penType, String name);
}//扩充实现类
public class Red implements Color {public void bepaint(String penType, String name) {System.out.println(penType + "红色的" + name + ".");}
}//扩充实现类
public class Yellow implements Color {public void bepaint(String penType, String name) {System.out.println(penType + "黄色的" + name + ".");}
}//扩充实现类
public class Blue implements Color {public void bepaint(String penType, String name) {System.out.println(penType + "蓝色的" + name + ".");}
}//配置文件configPen.xml
<?xml version="1.0"?>
<config><className>Blue</className><className>SmallPen</className>
</config>//使用java反射创建具体的颜色和画笔
public class XMLUtilPen {//该方法用于从XML配置文件中提取具体类类名,并返回一个实例对象public static Object getBean(String args) {try {//创建文档对象DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance();DocumentBuilder builder = dFactory.newDocumentBuilder();Document doc;doc = builder.parse(new File("configPen.xml"));NodeList nl = null;Node classNode = null;String cName = null;nl = doc.getElementsByTagName("className");if (args.equals("color")) {//获取包含类名的文本节点classNode = (Node) nl.item(0).getFirstChild();} else if (args.equals("pen")) {//获取包含类名的文本节点classNode = (Node) nl.item(1).getFirstChild();}cName = classNode.getNodeValue();//通过类名生成实例对象并将其返回Class c = Class.forName(cName);Object obj = c.newInstance();return obj;} catch (Exception e) {e.printStackTrace();return null;}}
}//客户端
public class Client {public static void main(String a[]) {Color color;Pen pen;color = (Color) XMLUtilPen.getBean("color");pen = (Pen) XMLUtilPen.getBean("pen");pen.setColor(color);pen.draw("鲜花");}
}
总结
在以下情况下可以使用桥接模式:
- 如果一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性,避免在两个层次之间建立静态的继承联系,通过桥接模式可以使它们在抽象层建立一个关联关系。
- 抽象化角色和实现化角色可以以继承的方式独立扩展而互不影响,在程序运行时可以动态将一个抽象化子类的对象和一个实现化子类的对象进行组合,即系统需要对抽象化角色和实现化角色进行动态耦合。
- 一个类存在两个独立变化的维度,且这两个维度都需要进行扩展。
- 虽然在系统中使用继承是没有问题的,但是由于抽象化角色和具体化角色需要独立变化,设计要求需要独立管理这两者。
- 对于那些不希望使用继承或因为多层次继承导致系统类的个数急剧增加的系统,桥接模式尤为适用。