zoukankan      html  css  js  c++  java
  • [设计模式]桥模式

    [设计模式]桥模式

    1. 桥模式的设计理念

      “桥模式”与“装饰模式”一样,是对于设计模式中的“单一职责”来进行修改的,其中“装饰模式”是对于很多附加功能的修改,而桥模式是针对多维度。

      桥模式是针对多维度实现装配组合的,举个例子,两个维度,m*n,则要至少实现m*n个类;而如果使用桥模式,在编译时去自由组合,只需要实现m+n个类。

      下面的就是很形象的,其存在两个维度:多平台(安卓,MacOs,Windows)、多版本(简约版,完美版)。

      

      而使用桥模式,将其拆分为两个维度,根据需要来编译时自由组合不同的版本,这样大大减少代码量。

    2. 反例

      如下代码,是一个很典型的反例,可以看出生成了大量的类来满足不同版本的需求

    class Messager{
    public:
        virtual void Login(string username, string password)=0;
        virtual void SendMessage(string message)=0;
        virtual void SendPicture(Image image)=0;
    
        virtual void PlaySound()=0;
        virtual void DrawShape()=0;
        virtual void WriteText()=0;
        virtual void Connect()=0;
        
        virtual ~Messager(){}
    };
    
    
    //平台实现
    
    class PCMessagerBase : public Messager{
    public:
        
        virtual void PlaySound(){
            //**********
        }
        virtual void DrawShape(){
            //**********
        }
        virtual void WriteText(){
            //**********
        }
        virtual void Connect(){
            //**********
        }
    };
    
    class MobileMessagerBase : public Messager{
    public:
        
        virtual void PlaySound(){
            //==========
        }
        virtual void DrawShape(){
            //==========
        }
        virtual void WriteText(){
            //==========
        }
        virtual void Connect(){
            //==========
        }
    };
    
    
    
    //业务抽象
    
    class PCMessagerLite : public PCMessagerBase {
    public:
        
        virtual void Login(string username, string password){
            
            PCMessagerBase::Connect();
            //........
        }
        virtual void SendMessage(string message){
            
            PCMessagerBase::WriteText();
            //........
        }
        virtual void SendPicture(Image image){
            
            PCMessagerBase::DrawShape();
            //........
        }
    };
    
    
    
    class PCMessagerPerfect : public PCMessagerBase {
    public:
        
        virtual void Login(string username, string password){
            
            PCMessagerBase::PlaySound();
            //********
            PCMessagerBase::Connect();
            //........
        }
        virtual void SendMessage(string message){
            
            PCMessagerBase::PlaySound();
            //********
            PCMessagerBase::WriteText();
            //........
        }
        virtual void SendPicture(Image image){
            
            PCMessagerBase::PlaySound();
            //********
            PCMessagerBase::DrawShape();
            //........
        }
    };
    
    
    class MobileMessagerLite : public MobileMessagerBase {
    public:
        
        virtual void Login(string username, string password){
            
            MobileMessagerBase::Connect();
            //........
        }
        virtual void SendMessage(string message){
            
            MobileMessagerBase::WriteText();
            //........
        }
        virtual void SendPicture(Image image){
            
            MobileMessagerBase::DrawShape();
            //........
        }
    };
    
    
    class MobileMessagerPerfect : public MobileMessagerBase {
    public:
        
        virtual void Login(string username, string password){
            
            MobileMessagerBase::PlaySound();
            //********
            MobileMessagerBase::Connect();
            //........
        }
        virtual void SendMessage(string message){
            
            MobileMessagerBase::PlaySound();
            //********
            MobileMessagerBase::WriteText();
            //........
        }
        virtual void SendPicture(Image image){
            
            MobileMessagerBase::PlaySound();
            //********
            MobileMessagerBase::DrawShape();
            //........
        }
    };
    
    
    void Process(){
            //编译时装配
            Messager *m =
                new MobileMessagerPerfect();
    }
    View Code

    3. 根据桥模式设计的代码

      如下,假设QQ存在如上所示的六种版本,桥模式的代码如下,可以看到其非常简约,其一个维度中+1只需要开发一个类即可,而不用桥模式的代码需要增加m(n)个类。

    #include <stdio.h>
    #include <iostream>
    #include <windows.h>
    using namespace std;
    
    //功能
    class QqFunc {
    public:
        virtual void SendMessage() = 0; // 发送消息
        virtual void SendPicture() = 0;  // 发送图片
        virtual ~QqFunc() {}
    };
    
    // 平台维度基类
    class QqPlatform {
    public:
        QqFunc* qFunc; // 两个维度在这里建立连接
        QqPlatform(QqFunc* p) :qFunc(p) {} // 初始化实现
        virtual void Login() = 0; // 登录
        virtual void Logon() = 0; // 注册
        virtual ~QqPlatform(){}
    };
    
    // 功能1 - 简约版
    class QqLite : public QqFunc {
    public:
        void SendMessage() {
            cout << "简约版发送消息功能" << endl;
        }
        void SendPicture() {
            cout << "简约版发送图片功能" << endl;
        }
    };
    
    // 功能2 - 完美版
    class QqPerfect : public QqFunc {
    public:
        void SendMessage() {
            cout << "完美版发送消息功能" << endl;
        }
        void SendPicture() {
            cout << "完美版发送图片功能" << endl;
        }
    };
    
    // 平台1 - Windows平台
    class  QqWindows :public QqPlatform {
    public:
        QqWindows(QqFunc* p) : QqPlatform(p) {}
        virtual void Login() {
            cout << "Windows平台下登录" << endl;
        }
        virtual void Logon() {
            cout << "Windows平台下注册" << endl;
        }
    };
    
    // 平台2 - Macos平台
    class  QqMacos :public QqPlatform {
    public:
        QqMacos(QqFunc* p) : QqPlatform(p) {}
        virtual void Login() {
            cout << "QqMacos平台下登录" << endl;
        }
        virtual void Logon() {
            cout << "QqMacos平台下注册" << endl;
        }
    };
    
    int main() {
        QqLite* qLite = new QqLite(); // 轻版
        QqMacos* qMacos = new QqMacos(qLite);  // Macos平台
        qMacos->Login();
        qMacos->qFunc->SendPicture();
        
    }
  • 相关阅读:
    Eclipse设置智能提示
    【GoLang】golang 如何像Java 一样通过类名反射对象?
    【GoLang】golang 面向对象编程 & 面向接口编程
    【Nginx】nginx 代理 Haproxy 怎么设置?
    【GoLang】GoLang struct 使用
    【GoLang】50 个 Go 开发者常犯的错误
    【GoLang】与或非 异或操作
    【GoLang】GoLang UTF8 与 Unicode
    【GoLang】GoLang 错误处理 -- 异常处理思路示例
    【GoLang】GoLang 的流程与函数
  • 原文地址:https://www.cnblogs.com/onetrainee/p/12733475.html
Copyright © 2011-2022 走看看