9. 桥接模式
目录
- 一、问题引入
- 二、桥接模式
- 2.1 概念
- 2.2 应用
- 2.3 实现
一、问题引入
- 环境
- 开发一个通用的日志记录工具
- 它支持数据库记录和文本文件记录
- 既可以运行在
.NET
平台,也可以运行在Java
平台
- 解决方案
- 将不同的日志记录方式分别作为单独的对象对待
- 为日志记录类抽象出一个基类
- 存在问题
- 不同平台的日志记录,对于操作数据库以及写入文本文件所调用的方式可能并不相同,因此需要继承扩展设计
- 不同平台的日志记录,对于操作数据库以及写入文本文件所调用的方式可能并不相同,因此需要继承扩展设计
- 假如现在要增加xml文件的记录方式,则只需要创建
XmlFileLog
类继承自Log
类即可,满足开闭原则。 - 假如要增加一个不同的平台,则需要在
DatabaseLog
和TextFileLog
类分别进行扩展。
- 第二种假设违背了类的单一职责原则:即一个类只有一个引起它变化的原因。第一种假设中引起变化的原因仅仅是存储形式,第二种假设引起变化的原因是存储形式和运行平台。
二、桥接模式
2.1 概念
- 在软件系统中,主要为了应对 “多维度的变化”。
- 桥接模式将
抽象部分
与实现部分
相分离。
2.2 应用
- 将多维度进行拆开,并针对每一个维度单独的进行详细设计。
- 实现了针对存储形式的设计(第一个设置图已经实现)。
- 实现日志运行平台的设计
- 将这两部分之间通过
对象组合
连接起来(桥接模式使用了对象组合方式)。
2.3 实现
#include <iostream>class ImpLog
{
public:virtual void Execute(const std::string& msg) = 0;virtual ~ImpLog() = default;
};class NImpLog : public ImpLog
{
public:void Execute(const std::string& msg) override{std::cout << ".NET platform: " << msg << std::endl;}
};class JImpLog : public ImpLog
{
public:void Execute(const std::string& msg) override{std::cout << "Java platform: " << msg << std::endl;}
};class Log
{
protected:ImpLog* implementor;public:void setImplentor(ImpLog* src){implementor = src;}virtual void Write(const std::string& log){implementor->Execute(log);}virtual ~Log() = default;
};class DatabaseLog : public Log
{
public:void Write(const std::string& log){implementor->Execute(log);}
};class TextFileLog : public Log
{
public:void Write(const std::string& log){implementor->Execute(log);}
};int main()
{//.Net平台下的DataBase LogLog* dblog = new DatabaseLog();dblog->setImplentor(new NImpLog());dblog->Write(".Net");//Java平台下的Text File LogLog* txtlog = new TextFileLog();txtlog->setImplentor(new JImpLog());txtlog->Write("Java");return 0;
}