學(xué)網(wǎng)站開發(fā)哪個好百度推廣的優(yōu)化軟件
介紹
? ? ? ? 橋接模式將抽象部分與其實現(xiàn)部分分離,使它們都可以獨立地變化。它是一種對象結(jié)構(gòu)型模式,又稱為柄體模式或接口模式
實現(xiàn)
myclass.h
//
// Created by yuwp on 2024/1/12.
//#ifndef DESIGNPATTERNS_MYCLASS_H
#define DESIGNPATTERNS_MYCLASS_H#include <iostream>class Implementor { // 實現(xiàn)抽象類,例如顏料
public:virtual void operationImpl() = 0;
};class Abstract { // 抽象類,例如毛筆
public:virtual void operation() = 0;
protected:Implementor *m_imp;
};class RefinedAbstraction : public Abstract { // 擴充抽象類,例如大號毛筆
public:RefinedAbstraction(Implementor *imp);~RefinedAbstraction();void operation() override;
};class ConcreteImplementorA : public Implementor { // 具體實現(xiàn)類,例如紅色顏料
public:void operationImpl() override;
};#endif //DESIGNPATTERNS_MYCLASS_H
myclass.cpp
//
// Created by yuwp on 2024/1/12.
//#include "myclass.h"RefinedAbstraction::RefinedAbstraction(Implementor *imp) {m_imp = imp;
}RefinedAbstraction::~RefinedAbstraction() {}void RefinedAbstraction::operation() {if (m_imp) {m_imp->operationImpl();}std::cout << "RefinedAbstraction::operation()" << std::endl;
}void ConcreteImplementorA::operationImpl() {std::cout << "ConcreteImplementorA::operationImpl()" << std::endl;
}
main.cpp
#include <iostream>
#include <mutex>
#include "myclass.h"int main() {Implementor *imp = new ConcreteImplementorA();Abstract *ab = new RefinedAbstraction(imp);ab->operation();return 0;
}
總結(jié)
優(yōu)點
? ? ? ? 1.?分離抽象接口及其實現(xiàn)部分。橋接模式使用“對象間的關(guān)聯(lián)關(guān)系”解耦了抽象和實現(xiàn)之間固有的綁定關(guān)系,使得抽象和實現(xiàn)可以沿著各自的維度來變化(即抽象和實現(xiàn)不再在同一個繼承層次結(jié)構(gòu)中,而是“子類化”它們,使它們各自都具有自己的子類,以便任意組合子類,從而獲得多維度組合對象)
? ? ? ? 2.?在很多情況下,橋接模式可以取代多層繼承方案。多層繼承方案違背了單一職責(zé)原則,復(fù)用性較差,且類的個數(shù)非常多。橋接模式是比多層繼承方案更好的解決方法,它極大地減少了子類的個數(shù)。
? ? ? ? 3.?橋接模式提高了系統(tǒng)的可擴展性。在兩個變化維度中任意擴展一個維度,都不需要修改原有系統(tǒng),符合開閉原則。
缺點
? ? ? ? 1.?橋接模式的使用會增加系統(tǒng)的理解與設(shè)計難度。由于關(guān)聯(lián)關(guān)系建立在抽象層,要求開發(fā)者一開始就針對抽象層進行設(shè)計與編程。
? ? ? ? 2.?橋接模式要求正確識別出系統(tǒng)中兩個獨立變化的維度,因此其使用范圍具有一定的局限性,如何正確識別兩個獨立維度也需要一定的經(jīng)驗積累。
適用場景
? ? ? ? 1.?如果一個系統(tǒng)需要在抽象類和具體類之間增加更多的靈活性,避免在兩個層次之間建立靜態(tài)的繼承關(guān)系,通過橋接模式可以使它們在抽象層建立一個關(guān)聯(lián)關(guān)系。
? ? ? ? 2.?抽象部分和實現(xiàn)部分可以以繼承的方式獨立擴展而互不影響,在程序運行時可以動態(tài)地將一個抽象類子類的對象和一個實現(xiàn)類子類的對象進行組合,即系統(tǒng)需要對抽象類角色和實現(xiàn)類角色進行動態(tài)耦合。
? ? ? ? 3.?一個類存在兩個(或多個)獨立變化的維度,且這兩個(或多個)維度都需要獨立進行擴展。
? ? ? ? 4.?對于那些不希望使用繼承或因為多層繼承導(dǎo)致系統(tǒng)類的個數(shù)急劇增加的系統(tǒng),橋接模式尤為適用。
練習(xí)
myclass.h
//
// Created by yuwp on 2024/1/12.
//#ifndef DESIGNPATTERNS_MYCLASS_H
#define DESIGNPATTERNS_MYCLASS_H#include <iostream>class FileFormat { // 實現(xiàn)抽象類
public:virtual void toFile(std::string data, std::string file) = 0;
};class Database { // 抽象類
public:virtual void trans() = 0;protected:FileFormat *m_fileFormat;
};class MysqlDatabase : public Database { // 擴充抽象類
public:MysqlDatabase(FileFormat *fileFormat);void trans() override;};class RedisDatabase : public Database {
public:RedisDatabase(FileFormat *fileFormat);void trans() override;protected:FileFormat *m_fileFormat;
};class TXTFileFormat : public FileFormat { // 具體實現(xiàn)類,例如紅色顏料
public:void toFile(std::string data, std::string file) override;
};class XMLFileFormat : public FileFormat {
public:void toFile(std::string data, std::string file) override;
};class PDFFileFormat : public FileFormat {
public:void toFile(std::string data, std::string file) override;
};#endif //DESIGNPATTERNS_MYCLASS_H
myclass.cpp
//
// Created by yuwp on 2024/1/12.
//#include "myclass.h"MysqlDatabase::MysqlDatabase(FileFormat *fileFormat) {m_fileFormat = fileFormat;
}void MysqlDatabase::trans() {std::string data = "mysql";if (m_fileFormat) {m_fileFormat->toFile(data, "mysql");}
}RedisDatabase::RedisDatabase(FileFormat *fileFormat) {m_fileFormat = fileFormat;
}void RedisDatabase::trans() {std::string data = "redis";if (m_fileFormat) {m_fileFormat->toFile(data, "redis");}
}void TXTFileFormat::toFile(std::string data, std::string file) {std::cout << "\"" << data << "\"" << "轉(zhuǎn)換為\"" << file << ".txt\"" << std::endl;
}void XMLFileFormat::toFile(std::string data, std::string file) {std::cout << "\"" << data << "\"" << "轉(zhuǎn)換為\"" << file << ".xml\"" << std::endl;
}void PDFFileFormat::toFile(std::string data, std::string file) {std::cout << "\"" << data << "\"" << "轉(zhuǎn)換為\"" << file << ".pdf\"" << std::endl;
}
main.cpp
#include <iostream>
#include <mutex>
#include "myclass.h"int main() {FileFormat *txtFormat = new TXTFileFormat();FileFormat *xmlFormat = new XMLFileFormat();FileFormat *pdfFormat = new PDFFileFormat();Database *database = new MysqlDatabase(txtFormat);database->trans();delete database;database = new MysqlDatabase(xmlFormat);database->trans();delete database;database = new MysqlDatabase(pdfFormat);database->trans();delete database;database = new RedisDatabase(txtFormat);database->trans();delete database;database = new RedisDatabase(xmlFormat);database->trans();delete database;database = new RedisDatabase(pdfFormat);database->trans();delete txtFormat;delete xmlFormat;delete pdfFormat;return 0;
}