桥接模式的实际使用
桥接模式的定义
“将抽象部分与实现部分分离,使它们都可以独立地变化”
这句话本身就很抽象 但是大概可以了解到有两个主体:
抽象部分
实现部分
动作就是让他们独立地变化, 从独立变化我们可以了解出, 应该是通过接口隔离或者抽象类的方式来隔离变化
桥接模式的类图
那么根据类图, 他们的代码是这样的
abstract class Abstraction{ Implenmentation impl; void function(){ use impl; }}class RefinedAbstraction{...}interface Implementor{...}class ConcreteImplenmentor implements Implementor{...}
实际使用
大部分使用例子都是使用一些生活化的方案来讲解, 跟技术开发关系不大, 在这里, 我们在一个协议处理与序列化与反序列化的场景下使用这个桥接模式:
假设现有一个系统需要支持RPC, 并且需要支持多种协议, 那么我们可以定义出一个抽象类AbstractProtocol
来代表这个RPC协议:
abstract class AbstractProtocol{}
我们可以继承此抽象类实现更具体的RPC协议:
class HttpProtocol extends AbstractProtocol{...}class CustomProtocol extends AbstractProtocol{...}
接下来我们需要实现序列化与反序列, 假设现在需要两种方式:
xml
json
我们可以直接在具体协议硬编码上序列化反序列器::
class HttpProtocol{ var JsonSerializer; var XmlSerializer; ...}
但这种方式不仅造成代码重复, 而且难以维护.
另外一种方式是通过继承具体协议类, 来进行扩展:
class HttpJsonSerialize extends HttpProtocol{...}class XmlJsonSerialize extends HttpProtocol{...}
同样, 这种方式也会造成重复. 我们目前有两种协议, 两种序列化方式就要4个类, 类的数量是呈指数级增长.
我们转变思路, 对序列化器也进行抽象:
interface Serializer{...}class JsonSerializer implements Serializer{...}class XmlSerializer implements Serializer{...}
让AbstractProtocol
持有序列化器的引用:
abstract class AbstractProtocol{ protected Serializer serializer;}
这样具体协议实现类就能直接使用这个序列化器了.
最后我们就有了两个部分:
AbstractProtocl
Serializer
这两个接口都可以独立地变化, 而且也不会造成类膨胀.
最后的代码如下:
abstract class AbstractProtocol{ protected Serializer serializer;}class HttpProtocol extends AbstractProtocol{...}class CustomProtocol extends AbstractProtocol{...}interface Serializer{...}class JsonSerializer implements Serializer{...}class XmlSerializer implements Serializer{...}
总结
目前这个例子是最接近实际技术开发, 但这个例子也只是起一个抛砖引玉的作用.