设计模式之结构模式(四)

版权声明:欢迎转载评论~哈哈哈哈请标明出处呀 https://blog.csdn.net/legendaryhaha/article/details/89055900

设计模式之结构模式(三)


桥接

在前面的设计模式中,我们知道,当不知客户调用哪些具体的产品时,我们可以将这些产品的共同特征抽象为接口或者抽象类,让客户端依赖这些抽象的东西。可是,如果生产产品的产家都不知道客户端会以一种怎样的方式来调用它,那么又应该如何解决呢?

这个时候我们可以采用桥接模式进行程序设计。举个例子,譬如我们的JDBC,它的设计思想体现的就是桥接模式(宏观上),在内部细节上,体现的是抽象工厂,由用户指定Driver后创建对应的connection。

数据库有多种,调用方式也多样,用户和产商在这种情况下怎样组织好它们的依赖关系呢?在JDBC技术中,它提供了两套接口,一个面向数据库厂商,一个面向JDBC使用者,进一步将抽象和现实分开出来,产品只要专注于产品的开发,用户调用时则制定好相应的Driver,从而解耦了业务与数据库通信协议这两个纬度之间的关系,所以这两个纬度之间的关系就需要一个桥,即Driver,至于DriverManager把这个关系接到哪里就是运行时的事情了。


桥接模式涉及的角色如图所示:

  1. Abstraction:抽象类。
  2. RefinedAbstraction:扩充抽象类(图中的AbstractionType_1,AbstractionType_2)。
  3. Implementor:实现类接口(图中的Implementer)。
  4. ConcreteImplementor:具体实现类 (图中的Implementer_1)。

在这里插入图片描述


运用我们说装饰器时的例子,有一个日志打印系统,打印方式有两种,直接打印到文件中,输出到控制台中,这里体现的产品多样化不确定的思想。然后,用户可以选择相应的日志形式,有HTML格式,有加工成二进制的,这里体现用户选择方式的不确定性。

用户选择日志的方式和日志打印方式是两个不同的维度的业务,为了使厂家专注于打印方式的生产,而不需要管日志是怎样形式,而用户也不需要关系打印方式是否能打印选择的日志格式。即为了使两者可以独立变化,我们采用如下方式:

厂家生产打印方式的模块

public interface Logger {
    void logger(String src);
}

public class CosoleLogger implements Logger {
    @Override
    public void logger(String src) {
        System.out.println("将"+src+"输出到控制台中");
    }
}

public class FileLogger implements Logger {
    @Override
    public void logger(String src) {
        System.out.println("将"+src+"输出到文件中");
    }
}

消息格式的方式

public interface Message {
    void logContent(String src);
}

public class MessageByBinary implements Message {
    private Logger logger;//持有Logger的引用

    public MessageByBinary(Logger logger){
        this.logger = logger;
    }
    @Override
    public void logContent(String src) {
        System.out.println("将"+src+"加工成二进制的形式");
        //对src进行操作
        logger.logger(src);
    }
}

public class MessageByHtml implements Message {
    private Logger logger;

    public MessageByHtml(Logger logger){
        this.logger = logger;
    }
    @Override
    public void logContent(String src) {
        System.out.println("将"+src+"加工成HTML格式");
        //对src进行操作
        logger.logger(src);
    }
}

客户端

public class Client {
    public static void main(String[] args) {
        Logger logger = new FileLogger(); //可以根据配置文件动态生成对象
        Message message = new MessageByHtml(logger);
        message.logContent("you will,my hands");
    }
}

和装饰器模式的比较

在装饰器模式中,我们看到代码和桥接模式的代码实现方式有点类似,当仔细分析后,其实是不同的。装饰器模式中,我们创建一个装饰器抽象类,并实现了File接口,即和日志打印方式共享一个接口,然后在子类中完成功能拓展(即变成HTML等等),而这里是隔离的两个接口,一个面对产家,一个面对用户,从而实现独立的变化,达到解耦饿目的。


猜你喜欢

转载自blog.csdn.net/legendaryhaha/article/details/89055900