设计模式 1.模板模式 应用场景: 算法所需的关键步骤已知,但具体实现未知
抽象类 :定义算法的主体框架,具体实现由子类完成
具体子类 :提供步骤的具体实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 #include <iostream> class Beverage {public : void prepareRecipe () { boilWater (); brew (); pourInCup (); addCondiments (); } void boilWater () { std::cout << "Boiling water..." << std::endl; } void pourInCup () { std::cout << "Pouring into cup..." << std::endl; } virtual void brew () = 0 ; virtual void addCondiments () = 0 ; virtual ~Beverage () = default ; }; class Tea : public Beverage {public : void brew () override { std::cout << "Steeping the tea..." << std::endl; } void addCondiments () override { std::cout << "Adding lemon..." << std::endl; } }; class Coffee : public Beverage {public : void brew () override { std::cout << "Dripping coffee through filter..." << std::endl; } void addCondiments () override { std::cout << "Adding sugar and milk..." << std::endl; } }; int main () { Tea tea; Coffee coffee; std::cout << "Making tea:" << std::endl; tea.prepareRecipe (); std::cout << "\nMaking coffee:" << std::endl; coffee.prepareRecipe (); return 0 ; }
2.策略模式 应用场景: 在需要动态选择不同算法的场景,如有大量的if-else
语句时,可以使用策略模式来进行优化。策略模式使不同的算法实现独立于使用它们的客户端进行管理和调用。
计算支付金额的例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 #include <iostream> #include <memory> class PaymentStrategy {public : virtual ~PaymentStrategy () = default ; virtual void pay (int amount) const = 0 ; }; class CreditCardPayment : public PaymentStrategy {public : void pay (int amount) const override { std::cout << "Paid " << amount << " using Credit Card." << std::endl; } }; class PayPalPayment : public PaymentStrategy {public : void pay (int amount) const override { std::cout << "Paid " << amount << " using PayPal." << std::endl; } }; class BitcoinPayment : public PaymentStrategy {public : void pay (int amount) const override { std::cout << "Paid " << amount << " using Bitcoin." << std::endl; } }; class PaymentContext {private : std::unique_ptr<PaymentStrategy> strategy; public : void setStrategy (std::unique_ptr<PaymentStrategy> newStrategy) { strategy = std::move (newStrategy); } void executePayment (int amount) const { if (strategy) { strategy->pay (amount); } else { std::cout << "No payment strategy set!" << std::endl; } } }; int main () { PaymentContext context; context.setStrategy (std::make_unique <CreditCardPayment>()); context.executePayment (100 ); context.setStrategy (std::make_unique <PayPalPayment>()); context.executePayment (200 ); context.setStrategy (std::make_unique <BitcoinPayment>()); context.executePayment (300 ); return 0 ; }
3.观察者模式 当⼀个对象的改变需要同时改变其他对象,且不知道具体有多少对象有待改变时,应该考虑使⽤观察者模式。在观察者模式中,主体是通知的发布者 ,它发出通知时并不需要知道谁是它的观察者,可以有任意数目的观察者订阅并接收通知。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 #include <iostream> #include <vector> #include <algorithm> class Observer {public : virtual ~Observer () {} virtual void update () = 0 ; }; class Subject {private : std::vector<Observer*> observers; public : void attach (Observer* observer) { observers.push_back (observer); } void detach (Observer* observer) { observers.erase (std::remove (observers.begin (), observers.end (), observer), observers.end ()); } void notify () { for (Observer* observer : observers) { observer->update (); } } }; class ConcreteObserver : public Observer {private : std::string name; public : ConcreteObserver (const std::string& observerName) : name (observerName) {} void update () override { std::cout << "Observer " << name << " has been notified!" << std::endl; } }; int main () { Subject subject; ConcreteObserver observer1 ("Observer 1" ) ; ConcreteObserver observer2 ("Observer 2" ) ; subject.attach (&observer1); subject.attach (&observer2); std::cout << "Notifying observers..." << std::endl; subject.notify (); subject.detach (&observer1); std::cout << "Notifying observers after detaching one observer..." << std::endl; subject.notify (); return 0 ; }
4.装饰模式 应用场景: 通过组合来实现功能的扩展(通过减少继承关系,来减少代码冗余),允许向一个对象动态地添加新的行为,而不会影响其他同类对象。
主要结构: 装饰模式的组合是用于递归地增强对象的功能。
组件接口: 定义了可以被装饰的对象的接口。
具体组件: 实现了组件接口,代表被装饰的对象。
装饰器: 实现了组件接口,并持有一个组件对象的引用,可以在保持接口一致的情况下扩展组件的功能。
具体装饰器: 继承自装饰器,实现具体的装饰功能。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 #include <iostream> #include <memory> class Component {public : virtual ~Component () = default ; virtual void operation () const = 0 ; }; class ConcreteComponent : public Component {public : void operation () const override { std::cout << "Plain Text" ; } }; class Decorator : public Component {protected : std::shared_ptr<Component> component; public : Decorator (std::shared_ptr<Component> comp) : component (comp) {} void operation () const override { if (component) { component->operation (); } } }; class BoldDecorator : public Decorator {public : BoldDecorator (std::shared_ptr<Component> comp) : Decorator (comp) {} void operation () const override { std::cout << "<b>" ; Decorator::operation (); std::cout << "</b>" ; } }; class ItalicDecorator : public Decorator {public : ItalicDecorator (std::shared_ptr<Component> comp) : Decorator (comp) {} void operation () const override { std::cout << "<i>" ; Decorator::operation (); std::cout << "</i>" ; } }; int main () { std::shared_ptr<Component> text = std::make_shared <ConcreteComponent>(); std::shared_ptr<Component> boldText = std::make_shared <BoldDecorator>(text); std::shared_ptr<Component> italicBoldText = std::make_shared <ItalicDecorator>(boldText); std::cout << "Decorated text: " ; italicBoldText->operation (); std::cout << std::endl; return 0 ; }
5.桥模式 应用场景: 适用于需要分离抽象和实现,使它们可以分别进行扩展的场景。例如,图形绘制系统中形状(如圆、矩形)和颜色(如红色、蓝色)的组合。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 #include <iostream> #include <memory> class Color {public : virtual ~Color () = default ; virtual void applyColor () const = 0 ; }; class RedColor : public Color {public : void applyColor () const override { std::cout << "Red" ; } }; class BlueColor : public Color {public : void applyColor () const override { std::cout << "Blue" ; } }; class Shape {protected : std::shared_ptr<Color> color; public : Shape (std::shared_ptr<Color> col) : color (col) {} virtual ~Shape () = default ; virtual void draw () const = 0 ; }; class Circle : public Shape {public : Circle (std::shared_ptr<Color> col) : Shape (col) {} void draw () const override { std::cout << "Circle drawn in " ; color->applyColor (); std::cout << " color." << std::endl; } }; class Square : public Shape {public : Square (std::shared_ptr<Color> col) : Shape (col) {} void draw () const override { std::cout << "Square drawn in " ; color->applyColor (); std::cout << " color." << std::endl; } }; int main () { std::shared_ptr<Color> red = std::make_shared <RedColor>(); std::shared_ptr<Shape> redCircle = std::make_shared <Circle>(red); redCircle->draw (); std::shared_ptr<Color> blue = std::make_shared <BlueColor>(); std::shared_ptr<Shape> blueSquare = std::make_shared <Square>(blue); blueSquare->draw (); return 0 ; }
6.工厂方法 应用场景: 希望添加新产品时,只需添加新产品类和具体工厂类
抽象产品 :定义产品的接口。
具体产品 :实现抽象产品接口的具体类。
抽象工厂 :声明工厂方法。
具体工厂 :实现工厂方法,返回具体产品实例。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 #include <iostream> #include <memory> class Document {public : virtual void open () const = 0 ; virtual ~Document () = default ; }; class TextDocument : public Document {public : void open () const override { std::cout << "Opening a text document." << std::endl; } }; class ImageDocument : public Document {public : void open () const override { std::cout << "Opening an image document." << std::endl; } }; class DocumentCreator {public : virtual std::unique_ptr<Document> createDocument () const = 0 ; virtual ~DocumentCreator () = default ; }; class TextDocumentCreator : public DocumentCreator {public : std::unique_ptr<Document> createDocument () const override { return std::make_unique <TextDocument>(); } }; class ImageDocumentCreator : public DocumentCreator {public : std::unique_ptr<Document> createDocument () const override { return std::make_unique <ImageDocument>(); } }; void openDocument (const DocumentCreator& creator) { std::unique_ptr<Document> doc = creator.createDocument (); doc->open (); } int main () { TextDocumentCreator textCreator; ImageDocumentCreator imageCreator; std::cout << "Using the text document creator:" << std::endl; openDocument (textCreator); std::cout << "\nUsing the image document creator:" << std::endl; openDocument (imageCreator); return 0 ; }
7.抽象工厂 抽象工厂可以理解为在工厂方法的基础上再做一层的扩展。
模式结构:
抽象工厂 :定义创建一系列相关对象的接口。
具体工厂 :实现抽象工厂接口,生成具体产品的实例。
抽象产品 :为每种产品声明接口。
具体产品 :实现抽象产品接口。
客户端 :使用抽象工厂和抽象产品接口来创建具体对象。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 #include <iostream> #include <memory> class Button {public : virtual void paint () const = 0 ; virtual ~Button () = default ; }; class WindowsButton : public Button {public : void paint () const override { std::cout << "Rendering a button in Windows style." << std::endl; } }; class MacButton : public Button {public : void paint () const override { std::cout << "Rendering a button in macOS style." << std::endl; } }; class TextBox {public : virtual void display () const = 0 ; virtual ~TextBox () = default ; }; class WindowsTextBox : public TextBox {public : void display () const override { std::cout << "Displaying a text box in Windows style." << std::endl; } }; class MacTextBox : public TextBox {public : void display () const override { std::cout << "Displaying a text box in macOS style." << std::endl; } }; class GUIFactory {public : virtual std::unique_ptr<Button> createButton () const = 0 ; virtual std::unique_ptr<TextBox> createTextBox () const = 0 ; virtual ~GUIFactory () = default ; }; class WindowsFactory : public GUIFactory {public : std::unique_ptr<Button> createButton () const override { return std::make_unique <WindowsButton>(); } std::unique_ptr<TextBox> createTextBox () const override { return std::make_unique <WindowsTextBox>(); } }; class MacFactory : public GUIFactory {public : std::unique_ptr<Button> createButton () const override { return std::make_unique <MacButton>(); } std::unique_ptr<TextBox> createTextBox () const override { return std::make_unique <MacTextBox>(); } }; void buildInterface (const GUIFactory& factory) { auto button = factory.createButton (); auto textBox = factory.createTextBox (); button->paint (); textBox->display (); } int main () { WindowsFactory windowsFactory; MacFactory macFactory; std::cout << "Building Windows interface:" << std::endl; buildInterface (windowsFactory); std::cout << "\nBuilding macOS interface:" << std::endl; buildInterface (macFactory); return 0 ; }
8.原型模式 通过复制现有对象来创建新的对象,而不是通过实例化类来创建。
模式结构:
示例:
一个简单的图形编辑器,需要频繁创建和复制不同类型的图形(如圆形和矩形)。在未使用原型模式的情况下,要会使用 new
关键字手动创建对象。使用原型模式后,可以更灵活地通过克隆已有对象来创建新对象。
没有使用原型模式的实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 #include <iostream> #include <memory> class Shape {public : virtual void draw () const = 0 ; virtual ~Shape () = default ; }; class Circle : public Shape {private : int radius; public : Circle (int r) : radius (r) {} void draw () const override { std::cout << "Drawing a circle with radius: " << radius << std::endl; } }; class Rectangle : public Shape {private : int width, height; public : Rectangle (int w, int h) : width (w), height (h) {} void draw () const override { std::cout << "Drawing a rectangle with width: " << width << " and height: " << height << std::endl; } }; int main () { std::unique_ptr<Shape> shape1 = std::make_unique <Circle>(5 ); std::unique_ptr<Shape> shape2 = std::make_unique <Rectangle>(4 , 6 ); shape1->draw (); shape2->draw (); std::unique_ptr<Shape> anotherCircle = std::make_unique <Circle>(5 ); anotherCircle->draw (); return 0 ; }
使用原型模式的实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 #include <iostream> #include <memory> class Shape {public : virtual void draw () const = 0 ; virtual std::unique_ptr<Shape> clone () const = 0 ; virtual ~Shape () = default ; }; class Circle : public Shape {private : int radius; public : Circle (int r) : radius (r) {} void draw () const override { std::cout << "Drawing a circle with radius: " << radius << std::endl; } std::unique_ptr<Shape> clone () const override { return std::make_unique <Circle>(*this ); } }; class Rectangle : public Shape {private : int width, height; public : Rectangle (int w, int h) : width (w), height (h) {} void draw () const override { std::cout << "Drawing a rectangle with width: " << width << " and height: " << height << std::endl; } std::unique_ptr<Shape> clone () const override { return std::make_unique <Rectangle>(*this ); } }; int main () { std::unique_ptr<Shape> originalCircle = std::make_unique <Circle>(5 ); std::unique_ptr<Shape> originalRectangle = std::make_unique <Rectangle>(4 , 6 ); originalCircle->draw (); originalRectangle->draw (); std::unique_ptr<Shape> clonedCircle = originalCircle->clone (); std::unique_ptr<Shape> clonedRectangle = originalRectangle->clone (); clonedCircle->draw (); clonedRectangle->draw (); return 0 ; }
9.构建器模式 应用场景: 适用于构建复杂对象,特别是当对象包含多个可选或可变部分时。
结构:
产品类 :需要构建的复杂对象。
构建器接口 :定义构建产品各个部分的方法 。
具体构建器 :实现 Builder
接口并提供构建产品的方法(可扩展的具体实现,与产品类用组合代替继承) 。
指挥者 :使用 Builder
来控制构建过程的顺序(步骤,可扩展) 。
客户端 :创建 Builder
和 Director
,并启动构建过程。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 #include <iostream> #include <memory> #include <string> class Car {public : std::string engine; std::string wheels; std::string body; void showCar () const { std::cout << "Car with engine: " << engine << ", wheels: " << wheels << ", body: " << body << std::endl; } }; class CarBuilder {public : virtual ~CarBuilder () = default ; virtual void buildEngine () = 0 ; virtual void buildWheels () = 0 ; virtual void buildBody () = 0 ; virtual std::shared_ptr<Car> getCar () = 0 ; }; class SportsCarBuilder : public CarBuilder {private : std::shared_ptr<Car> car; public : SportsCarBuilder () { car = std::make_shared <Car>(); } void buildEngine () override { car->engine = "V8 Engine" ; } void buildWheels () override { car->wheels = "Sports Wheels" ; } void buildBody () override { car->body = "Sleek Sports Body" ; } std::shared_ptr<Car> getCar () override { return car; } }; class Director {public : void construct (std::shared_ptr<CarBuilder> builder) { builder->buildEngine (); builder->buildWheels (); builder->buildBody (); } }; int main () { std::shared_ptr<CarBuilder> sportsCarBuilder = std::make_shared <SportsCarBuilder>(); Director director; director.construct (sportsCarBuilder); std::shared_ptr<Car> car = sportsCarBuilder->getCar (); car->showCar (); return 0 ; }
10.单例模式 应用场景: 确保某个类只有一个实例,并提供一个全局访问点来访问该实例。常用于需要控制全局访问、限制资源或共享资源的场景。用于减少创建对象的数量
特点:
唯一性 :保证一个类只有一个实例。
全局访问点 :提供对该实例的全局访问。
延迟实例化 :实例化通常是在首次访问时才创建,节省资源。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 #include <iostream> #include <string> #include <memory> class Logger {private : Logger () { std::cout << "Logger created" << std::endl; } Logger (const Logger&) = delete ; Logger& operator =(const Logger&) = delete ; public : static Logger& getInstance () { static Logger instance; return instance; } void log (const std::string& message) { std::cout << "Log: " << message << std::endl; } }; int main () { Logger& logger1 = Logger::getInstance (); Logger& logger2 = Logger::getInstance (); logger1.log ("This is the first message" ); logger2.log ("This is the second message" ); if (&logger1 == &logger2) { std::cout << "Both loggers are the same instance" << std::endl; } return 0 ; }
注1:私有构造函数 防止类的外部创建实例。
注2:通过删除拷贝构造函数和赋值运算符 ,防止实例被复制。
注3:static
变量 instance
保证实例只创建一次,并在程序结束时自动销毁。:
11.享元模式 应用场景: 用于减少创建对象的数量,从而减少内存消耗并提高性能。常用于系统中需要大量细粒度对象的场景,比如图形编辑器中的图元或文字处理器中的字符。
共享的部分做成员,外部状态做参数,调用时提供
特点:
共享 :将对象的共享部分提取出来,通过共享减少内存开销。
分离状态 :对象可以分为内部状态和外部状态。内部状态是共享的,外部状态是每个对象特有的,不会被共享。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 #include <iostream> #include <unordered_map> #include <memory> class Circle {private : std::string color; public : Circle (const std::string& col) : color (col) {} void draw (int x, int y, int radius) const { std::cout << "Circle: Color=" << color << ", x=" << x << ", y=" << y << ", radius=" << radius << std::endl; } }; class CircleFactory {private : std::unordered_map<std::string, std::shared_ptr<Circle>> circleMap; public : std::shared_ptr<Circle> getCircle (const std::string& color) { auto it = circleMap.find (color); if (it != circleMap.end ()) { return it->second; } auto newCircle = std::make_shared <Circle>(color); circleMap[color] = newCircle; std::cout << "Creating circle of color: " << color << std::endl; return newCircle; } }; int main () { CircleFactory circleFactory; auto circle1 = circleFactory.getCircle ("Red" ); circle1->draw (10 , 10 , 5 ); circle1->draw (20 , 20 , 10 ); auto circle2 = circleFactory.getCircle ("Red" ); circle2->draw (30 , 30 , 15 ); auto circle3 = circleFactory.getCircle ("Green" ); circle3->draw (15 , 15 , 7 ); return 0 ; }
注:
12.面门模式 应用场景: 为子系统中的一组复杂接口提供一个统一的接口,使得子系统更容易使用。适用于简化接口调用
客户端-》面门类-》子系统类
注:客户端不需要直接依赖子系统的具体实现,而是依赖门面接口,降低了耦合性。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 #include <iostream> #include <memory> class AudioPlayer {public : void playAudio () { std::cout << "Playing audio..." << std::endl; } }; class VideoPlayer {public : void playVideo () { std::cout << "Playing video..." << std::endl; } }; class Subtitles {public : void loadSubtitles () { std::cout << "Loading subtitles..." << std::endl; } }; class MediaFacade {private : std::unique_ptr<AudioPlayer> audioPlayer; std::unique_ptr<VideoPlayer> videoPlayer; std::unique_ptr<Subtitles> subtitles; public : MediaFacade () { audioPlayer = std::make_unique <AudioPlayer>(); videoPlayer = std::make_unique <VideoPlayer>(); subtitles = std::make_unique <Subtitles>(); } void playMedia () { audioPlayer->playAudio (); videoPlayer->playVideo (); subtitles->loadSubtitles (); } }; int main () { MediaFacade mediaFacade; mediaFacade.playMedia (); return 0 ; }
13.代理模式 应用场景: 用于为另一个对象提供一种“代理”或占位符以控制对这个对象的访问。例如延迟 加载、控制访问权限、日志记录等。
例: 使用虚代理来实现按需加载图像资源
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 #include <iostream> #include <string> #include <memory> class Image {public : virtual void display () const = 0 ; virtual ~Image () = default ; }; class RealImage : public Image {public : RealImage (const std::string& fileName) : fileName (fileName) { loadImage (); } void display () const override { std::cout << "Displaying image: " << fileName << std::endl; } private : std::string fileName; void loadImage () { std::cout << "Loading image from " << fileName << "..." << std::endl; } }; class ProxyImage : public Image {public : ProxyImage (const std::string& fileName) : fileName (fileName), realImage (nullptr ) {} void display () const override { if (!realImage) { realImage = std::make_unique <RealImage>(fileName); } realImage->display (); } private : std::string fileName; mutable std::unique_ptr<RealImage> realImage; }; int main () { std::unique_ptr<Image> image = std::make_unique <ProxyImage>("photo.jpg" ); std::cout << "Image created, but not loaded yet." << std::endl; image->display (); return 0 ; }
14.适配器模式 应用场景: 适配器模式主要解决接口不匹配的问题。
组成:
目标接口 :客户端期望的接口。
需要适配的类 :拥有不兼容接口的类。
适配器 :将目标接口与需要适配的类进行连接,转换接口以满足客户端需求。
客户端 :通过目标接口与适配器交互。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 #include <iostream> #include <string> #include <memory> class OldPrinter {public : void oldPrint (const std::string& text) { std::cout << "Old Printer: " << text << std::endl; } }; class NewPrinterInterface {public : virtual void print (const std::string& text) = 0 ; virtual ~NewPrinterInterface () = default ; }; class PrinterAdapter : public NewPrinterInterface {private : std::shared_ptr<OldPrinter> oldPrinter; public : PrinterAdapter (std::shared_ptr<OldPrinter> oldPrinter) : oldPrinter (oldPrinter) {} void print (const std::string& text) override { oldPrinter->oldPrint (text); } }; int main () { auto oldPrinter = std::make_shared <OldPrinter>(); PrinterAdapter adapter (oldPrinter) ; adapter.print ("Hello, World!" ); return 0 ; }
15.中介者模式 应用场景: 用于减少多个对象之间的直接相互依赖。通过引入一个中介者对象,所有对象之间的通信都通过中介者完成,降低了对象之间的耦合性。
未使用中介者模式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 #include <iostream> #include <string> class User {private : std::string name; public : User (const std::string& name) : name (name) {} void sendMessage (User& receiver, const std::string& message) { std::cout << name << " to " << receiver.getName () << ": " << message << std::endl; } std::string getName () const { return name; } }; int main () { User user1 ("Alice" ) ; User user2 ("Bob" ) ; user1.sendMessage (user2, "Hello, Bob!" ); user2.sendMessage (user1, "Hi, Alice!" ); return 0 ; }
使用中介者模式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 #include <iostream> #include <string> #include <vector> #include <memory> class ChatMediator {public : virtual void sendMessage (const std::string& message, class User* sender, const std::string& receiverName) = 0 ; virtual void addUser (std::shared_ptr<class User> user) = 0 ; virtual ~ChatMediator () = default ; }; class User {protected : std::string name; ChatMediator* mediator; public : User (const std::string& name, ChatMediator* mediator) : name (name), mediator (mediator) {} virtual void send (const std::string& message, const std::string& receiverName) { mediator->sendMessage (message, this , receiverName); } virtual void receive (const std::string& message, const std::string& senderName) { std::cout << name << " received from " << senderName << ": " << message << std::endl; } std::string getName () const { return name; } }; class ConcreteChatMediator : public ChatMediator {private : std::vector<std::shared_ptr<User>> users; public : void addUser (std::shared_ptr<User> user) override { users.push_back (user); } void sendMessage (const std::string& message, User* sender, const std::string& receiverName) override { for (const auto & user : users) { if (user->getName () == receiverName) { user->receive (message, sender->getName ()); return ; } } std::cout << "User " << receiverName << " not found!" << std::endl; } }; int main () { ConcreteChatMediator mediator; auto user1 = std::make_shared <User>("Alice" , &mediator); auto user2 = std::make_shared <User>("Bob" , &mediator); auto user3 = std::make_shared <User>("Charlie" , &mediator); mediator.addUser (user1); mediator.addUser (user2); mediator.addUser (user3); user1->send ("Hello Bob!" , "Bob" ); user3->send ("Hi Alice!" , "Alice" ); user1->send ("Hello David!" , "David" ); return 0 ; }
16.状态模式 应用场景: 对象的行为由对象的状态所决定,而通过使用状态模式实现了状态和行为的分离。
实现行为固定时,对状态的扩展
示例:
电梯有以下状态:
运行中(Moving)
停止中(Stopped)
开门(Open)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 #include <iostream> #include <memory> #include <string> class State {public : virtual void openDoor () = 0 ; virtual void closeDoor () = 0 ; virtual void move () = 0 ; virtual void stop () = 0 ; virtual ~State () = default ; }; class Elevator ;class StoppedState : public State {private : Elevator* elevator; public : explicit StoppedState (Elevator* elevator) : elevator(elevator) { } void openDoor () override ; void closeDoor () override ; void move () override ; void stop () override ; }; class MovingState : public State {private : Elevator* elevator; public : explicit MovingState (Elevator* elevator) : elevator(elevator) { } void openDoor () override ; void closeDoor () override ; void move () override ; void stop () override ; }; class OpenState : public State {private : Elevator* elevator; public : explicit OpenState (Elevator* elevator) : elevator(elevator) { } void openDoor () override ; void closeDoor () override ; void move () override ; void stop () override ; }; class Elevator {private : std::shared_ptr<State> currentState; public : explicit Elevator (std::shared_ptr<State> initialState) : currentState(std::move(initialState)) { } void setState (std::shared_ptr<State> state) { currentState = std::move (state); } void openDoor () { currentState->openDoor (); } void closeDoor () { currentState->closeDoor (); } void move () { currentState->move (); } void stop () { currentState->stop (); } }; void StoppedState::openDoor () { std::cout << "Opening door...\n" ; elevator->setState (std::make_shared <OpenState>(elevator)); } void StoppedState::closeDoor () { std::cout << "Door is already closed.\n" ; } void StoppedState::move () { std::cout << "Elevator is starting to move...\n" ; elevator->setState (std::make_shared <MovingState>(elevator)); } void StoppedState::stop () { std::cout << "Elevator is already stopped.\n" ; } void MovingState::openDoor () { std::cout << "Cannot open door while moving.\n" ; } void MovingState::closeDoor () { std::cout << "Door is already closed.\n" ; } void MovingState::move () { std::cout << "Elevator is already moving.\n" ; } void MovingState::stop () { std::cout << "Elevator is stopping...\n" ; elevator->setState (std::make_shared <StoppedState>(elevator)); } void OpenState::openDoor () { std::cout << "Door is already open.\n" ; } void OpenState::closeDoor () { std::cout << "Closing door...\n" ; elevator->setState (std::make_shared <StoppedState>(elevator)); } void OpenState::move () { std::cout << "Cannot move with door open.\n" ; } void OpenState::stop () { std::cout << "Elevator is already stopped.\n" ; } int main () { auto elevator = std::make_shared <Elevator>(nullptr ); auto initialState = std::make_shared <StoppedState>(elevator.get ()); elevator->setState (initialState); elevator->openDoor (); elevator->closeDoor (); elevator->move (); elevator->stop (); elevator->openDoor (); return 0 ; }
17.备忘录模式 应用场景: 允许在不暴露对象实现细节的情况下保存和恢复对象之前的状态(如浏览器回退、编辑器撤销)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 #include <iostream> #include <string> #include <vector> class Memento {private : std::string state; public : explicit Memento (const std::string& state) : state(state) { } std::string getState () const { return state; } }; class TextEditor {private : std::string text; public : void type (const std::string& newText) { text += newText; } void showContent () const { std::cout << "Current Content: " << text << std::endl; } Memento save () const { return Memento (text); } void restore (const Memento& memento) { text = memento.getState (); } }; class Caretaker {private : std::vector<Memento> history; public : void save (const Memento& memento) { history.push_back (memento); } Memento get (int index) const { if (index < 0 || index >= history.size ()) { throw std::out_of_range ("Invalid index" ); } return history[index]; } }; int main () { TextEditor editor; Caretaker caretaker; editor.type ("Hello, " ); caretaker.save (editor.save ()); editor.type ("World!" ); caretaker.save (editor.save ()); editor.type (" New content." ); editor.showContent (); editor.restore (caretaker.get (1 )); editor.showContent (); editor.restore (caretaker.get (0 )); editor.showContent (); return 0 ; }
18.组合模式 组合模式将对象组合成树形结构,来一致地处理单个对象和对象的组合。
结构:
Component(抽象组件): 定义了对象的公共接口,包括对组合对象的常见操作
Leaf(叶子节点): 表示树形结构的最小单元,不包含子节点。
Composite(组合节点): 包含子节点的容器,可以是Leaf
或Composite
,实现管理子节点的操作,例如添加、移除和遍历子节点。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 #include <iostream> #include <string> #include <vector> #include <memory> class FileSystemComponent {public : virtual void display (int depth = 0 ) const = 0 ; virtual ~FileSystemComponent () = default ; }; class File : public FileSystemComponent {private : std::string name; public : File (const std::string& name) : name (name) {} void display (int depth = 0 ) const override { std::cout << std::string (depth, '-' ) << "File: " << name << std::endl; } }; class Folder : public FileSystemComponent {private : std::string name; std::vector<std::shared_ptr<FileSystemComponent>> children; public : Folder (const std::string& name) : name (name) {} void add (std::shared_ptr<FileSystemComponent> component) { children.push_back (component); } void display (int depth = 0 ) const override { std::cout << std::string (depth, '-' ) << "Folder: " << name << std::endl; for (const auto & child : children) { child->display (depth + 2 ); } } }; int main () { auto file1 = std::make_shared <File>("file1.txt" ); auto file2 = std::make_shared <File>("file2.txt" ); auto subFolder = std::make_shared <Folder>("SubFolder" ); subFolder->add (file1); auto mainFolder = std::make_shared <Folder>("MainFolder" ); mainFolder->add (subFolder); mainFolder->add (file2); mainFolder->display (); return 0 ; }