【HeadFirst 设计模式学习笔记】19 桥接(Bridge)模式拾零
作者:gnuhpc
出处:http://www.cnblogs.com/gnuhpc/
1.概述
该模式也是Head First中未收录的,其主要用于分离接口与实现,常应用在你不希望将实现和抽象永久绑定的时候。其实质在于提供一个对抽象接口的抽象实现,而抽象实现中又包含一个具体实现接口(叫做“实现者”)的引用,通过这个引用给抽象实现提供能力。
2.实例
假设我们要创建一个具有持久化能力的类,其对象实例的持久化可能是通过数据库,也可能是通过文件系统进行。通常的实现是通过继承这个类分别完成数据库和文件系统持久化的能力。但这就会导致具体实现和抽象的紧密绑定,不利于以后单独对实现或抽象进行修改或扩展。我们可以使用桥接模式解决这个问题:
首先我们先创建持久化这个能力的接口:
1: /**
2: * Persistence Interface3: * Abstraction Interface4: */5: public interface Persistence {6:7: /**
8: * @param object9: * @return returns objectID10: */11: public String persist(Object object);12:13: /**
14: *15: * @param objectId16: * @return persisted Object17: */18: public Object findById(String objectId);
19:20: /**
21: *22: * @param id23: */24: public void deleteById(String id);25:26:27: }28:
对于这个抽象接口,我们提供一个抽象实现:
1: public class PersistenceImp implements Persistence {2:3: private PersistenceImplementor implementor = null;4:5: public PersistenceImp(PersistenceImplementor imp) {
6:7: this.implementor = imp;
8:9: }10:11: @Override12: public void deleteById(String id) {13:14: implementor.deleteObject(Long.parseLong(id));15:16: }17:18: @Override19: public Object findById(String objectId) {
20:21: return implementor.getObject(Long.parseLong(objectId));
22: }23:24:25:26: @Override27: public String persist(Object object) {28:29: return Long.toString(implementor.saveObject(object));30:31:32: }33:34: }35:
在这个抽象实现中,通过持有一个PersistenceImplementor接口的对象来完成每一个具体操作的实际实现。
现在我们就对这个实现者接口PersistenceImplementor进行定义,这个实现者则定义了三个方法,其不同于抽象接口定义的方法。
package bridge; /** * Implementor Interface */ public interface PersistenceImplementor { public long saveObject(Object object); public void deleteObject(long objectId); public Object getObject(long objectId); }
现在我们就实现数据库和文件系统持久化的具体方法,这是通过实现这个实现者接口完成的,为了突出这个设计模式,实现的具体细节略去:
1: /**
2: * Concrete Implementor3: *4: */5: public class FileSystemPersistenceImplementor implements PersistenceImplementor{6:7: @Override8: public void deleteObject(long objectId) {9:10:11: return;
12: }13:14: @Override15: public Object getObject(long objectId) {16:17: return null;18:19:20: }21:22: private Object readObjectFromFile(File f) {
23:24: // open file
25: // and load object
26: //return the object
27: return null;28: }29:30: @Override31: public long saveObject(Object object) {32:33:34: return 0;
35:36: }37:38: private void writeObjectToFile(File f, Object object) {39:40: // serialize object and write it to file
41:42: }43: }44:
1: public class DabatasePersistenceImplementor implements PersistenceImplementor{2:3: public DabatasePersistenceImplementor() {
4:5: // load database driver
6:7:8: }9:10: @Override11: public void deleteObject(long objectId) {12:13: // open database connection
14: // remove record
15:16: }17:18: @Override19: public Object getObject(long objectId) {20:21: // open database connection
22: // read records
23: // create object from record
24: return null;25: }26:27: @Override28: public long saveObject(Object object) {29:30: // open database connection
31: // create records for fields inside the object
32:33: return 0;
34: }35:36: }37:
到此为止,我们实现了桥接模式,通过实现者接口PersistenceImplementor完成了具体实现与抽象接口之间的桥接。
现在我们就可以使用这个桥接模式了:
1: public class PersistenceFrameworkDriver {2:3: public static void main(String[] args) {4:5:6: // this program needs a persistence framework
7: // at runtime an implementor is chosen between file system implementation and
8: //database implememtor , depending on existence of databse drivers
9:10:11:12: PersistenceImplementor implementor = null;
13:14: if(databaseDriverExists()){
15:16: implementor = new DabatasePersistenceImplementor();
17:18: }else{
19:20: implementor = new FileSystemPersistenceImplementor();
21: }22:23: Persistence persistenceAPI = new PersistenceImp(implementor);
24:25: Object o = persistenceAPI.findById("12343755");
26:27:28: // do changes to the object
29:30: // then persist
31:32: persistenceAPI.persist(o);33:34:35: // can also change implementor
36: persistenceAPI = new PersistenceImp(new DabatasePersistenceImplementor());37:38: persistenceAPI.deleteById("2323");
39:40:41: }42:43: private static boolean databaseDriverExists() {44:45: return false;46: }47: }48:
其中的persistenceAPI这个变量可以为Persistence类型也可以为PersistenceImp,在这里并无本质区别。
3.UML图