软件技术和软件工程一样吗,湖南seo公司,南京机械加工网,苏州专业高端网站建设公司C中常用的设计模式有很多#xff0c;设计模式是解决常见问题的经过验证的最佳实践。以下是一些常用的设计模式#xff1a;
单例模式#xff08;Singleton#xff09;#xff1a;确保一个类只有一个实例#xff0c;并提供一个全局访问点。工厂模式#xff08;Factory中常用的设计模式有很多设计模式是解决常见问题的经过验证的最佳实践。以下是一些常用的设计模式
单例模式Singleton确保一个类只有一个实例并提供一个全局访问点。工厂模式Factory用于创建对象而不需要指定具体类。抽象工厂模式Abstract Factory提供一组相关或相互依赖的对象而不指定其具体类。建造者模式Builder将一个复杂对象的构建与其表示分离使相同的构建过程可以创建不同的表示。原型模式Prototype通过克隆已有对象来创建新对象以避免直接使用构造函数。适配器模式Adapter将一个接口转换成另一个客户希望使用的接口。装饰器模式Decorator动态地给一个对象添加一些额外的职责而不需要子类化。代理模式Proxy为其他对象提供一个代理以控制对这个对象的访问。观察者模式Observer定义了一种一对多的依赖关系当一个对象状态改变时所有依赖它的对象都会得到通知。策略模式Strategy定义一系列算法封装它们使它们可以相互替换。命令模式Command将一个请求封装成一个对象从而允许使用不同的请求、队列或日志请求。状态模式State允许对象在其内部状态改变时改变其行为。模板方法模式Template Method定义算法的骨架允许子类重写其中的步骤。访问者模式Visitor表示一个作用于某对象结构中的各元素的操作它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。组合模式Composite将对象组合成树形结构以表示“部分-整体”的层次结构。迭代器模式Iterator提供一种方法顺序访问一个聚合对象中各个元素而又不暴露该对象的内部表示。中介者模式Mediator定义一个对象封装一系列对象之间的交互从而降低对象之间的耦合度。备忘录模式Memento不破坏封装的前提下捕获一个对象的内部状态并在对象之外保存这个状态。桥接模式Bridge将抽象部分与它的实现部分分离使它们可以独立变化。解释器模式Interpreter给定一个语言定义它的文法的一种表示并定义一个解释器这个解释器使用该表示来解释语言中的句子。
这些设计模式都有特定的应用场景可以根据问题的性质选择合适的设计模式来解决。设计模式有助于提高代码的可维护性、可扩展性和复用性。
1.单例模式
提供所有设计模式的 C 示例代码是一个庞大的任务但我可以为您提供一个示例演示如何使用 C 实现一个常见的设计模式——单例模式Singleton。
单例模式Singleton 确保一个类只有一个实例并提供全局访问点。以下是一个基本的单例模式示例
#include iostreamclass Singleton {
public:static Singleton getInstance() {static Singleton instance; // 静态局部变量确保只初始化一次return instance;}void doSomething() {std::cout Singleton is doing something. std::endl;}private:Singleton() {} // 构造函数私有只能通过 getInstance() 获取实例
};int main() {// 获取 Singleton 实例Singleton singleton Singleton::getInstance();singleton.doSomething();return 0;
}在这个示例中Singleton 类的构造函数是私有的这意味着外部无法直接创建 Singleton 对象。通过 getInstance() 静态成员函数我们可以获取到单一的 Singleton 实例。这确保了只有一个实例存在。 单例模式常用于需要共享资源或控制访问某些全局状态的情况。在实际项目中设计模式的选择会根据具体需求和架构决策不同的模式可能会以不同的方式被实现和使用。
2.工厂模式
工厂模式Factory Pattern是一种创建型设计模式用于创建对象而无需指定对象的具体类。工厂模式通过定义一个共同的接口由不同的工厂子类来实现并根据不同的情况返回不同的具体对象。
以下是一个简单的工厂模式的 C 示例
#include iostream// 抽象产品类
class Product {
public:virtual void use() 0;
};// 具体产品类 A
class ConcreteProductA : public Product {
public:void use() override {std::cout Product A in use. std::endl;}
};// 具体产品类 B
class ConcreteProductB : public Product {
public:void use() override {std::cout Product B in use. std::endl;}
};// 抽象工厂类
class Factory {
public:virtual Product* createProduct() 0;
};// 具体工厂类 A用于创建 ProductA
class ConcreteFactoryA : public Factory {
public:Product* createProduct() override {return new ConcreteProductA();}
};// 具体工厂类 B用于创建 ProductB
class ConcreteFactoryB : public Factory {
public:Product* createProduct() override {return new ConcreteProductB();}
};int main() {// 使用具体工厂类 A 创建产品 AFactory* factoryA new ConcreteFactoryA();Product* productA factoryA-createProduct();productA-use();// 使用具体工厂类 B 创建产品 BFactory* factoryB new ConcreteFactoryB();Product* productB factoryB-createProduct();productB-use();delete factoryA;delete factoryB;delete productA;delete productB;return 0;
}在这个示例中我们定义了抽象产品类 Product有两个具体的产品类 ConcreteProductA 和 ConcreteProductB它们都继承自 Product。然后我们定义了抽象工厂类 Factory有两个具体工厂类 ConcreteFactoryA 和 ConcreteFactoryB它们分别负责创建不同的产品。
通过使用工厂模式我们可以根据具体的需求选择不同的工厂类来创建产品而无需关心产品的具体类是什么。这提供了灵活性允许我们轻松扩展和替换具体产品和工厂类。
这是一个简单的示例实际中工厂模式可用于更复杂的对象创建需求。工厂模式常用于创建对象的场景特别是在代码中需要降低耦合性时非常有用。
3.抽象工厂模式
抽象工厂模式Abstract Factory Pattern是一种创建型设计模式它提供了一个接口用于创建一系列相关或依赖的对象而不需要指定它们的具体类。抽象工厂模式的核心思想是为每个产品族相关的一组产品定义一个抽象工厂然后在每个具体工厂中实现该抽象工厂。
以下是一个简单的抽象工厂模式的 C 示例
#include iostream// 抽象产品 A
class AbstractProductA {
public:virtual void useA() 0;
};// 具体产品 A1
class ConcreteProductA1 : public AbstractProductA {
public:void useA() override {std::cout Product A1 in use. std::endl;}
};// 具体产品 A2
class ConcreteProductA2 : public AbstractProductA {
public:void useA() override {std::cout Product A2 in use. std::endl;}
};// 抽象产品 B
class AbstractProductB {
public:virtual void useB() 0;
};// 具体产品 B1
class ConcreteProductB1 : public AbstractProductB {
public:void useB() override {std::cout Product B1 in use. std::endl;}
};// 具体产品 B2
class ConcreteProductB2 : public AbstractProductB {
public:void useB() override {std::cout Product B2 in use. std::endl;}
};// 抽象工厂
class AbstractFactory {
public:virtual AbstractProductA* createProductA() 0;virtual AbstractProductB* createProductB() 0;
};// 具体工厂 1
class ConcreteFactory1 : public AbstractFactory {
public:AbstractProductA* createProductA() override {return new ConcreteProductA1();}AbstractProductB* createProductB() override {return new ConcreteProductB1();}
};// 具体工厂 2
class ConcreteFactory2 : public AbstractFactory {
public:AbstractProductA* createProductA() override {return new ConcreteProductA2();}AbstractProductB* createProductB() override {return new ConcreteProductB2();}
};int main() {// 使用具体工厂 1 创建产品 A 和 BAbstractFactory* factory1 new ConcreteFactory1();AbstractProductA* productA1 factory1-createProductA();AbstractProductB* productB1 factory1-createProductB();productA1-useA();productB1-useB();// 使用具体工厂 2 创建产品 A 和 BAbstractFactory* factory2 new ConcreteFactory2();AbstractProductA* productA2 factory2-createProductA();AbstractProductB* productB2 factory2-createProductB();productA2-useA();productB2-useB();delete factory1;delete productA1;delete productB1;delete factory2;delete productA2;delete productB2;return 0;
}在这个示例中我们定义了两个抽象产品类 AbstractProductA 和 AbstractProductB以及它们的具体实现类。然后我们定义了抽象工厂类 AbstractFactory它包括两个工厂方法分别用于创建产品 A 和产品 B。具体工厂类 ConcreteFactory1 和 ConcreteFactory2 分别实现了 AbstractFactory用于创建不同的产品族。
抽象工厂模式允许我们在不知道具体产品类的情况下创建一组相关产品这对于需要保持产品族之间的一致性非常有用。此模式还支持易于替换整个产品族以满足不同的需求。
4.建造者模式
建造者模式Builder Pattern是一种创建型设计模式用于构建一个复杂对象将构造过程和表示分离。通常情况下该模式包括一个 Director指挥者类、一个抽象 Builder建造者接口和具体的 Builder 实现类。
以下是一个简单的建造者模式的 C 示例
#include iostream
#include string// 产品类即要构建的复杂对象
class Product {
public:void setPartA(const std::string partA) {partA_ partA;}void setPartB(const std::string partB) {partB_ partB;}void setPartC(const std::string partC) {partC_ partC;}void show() {std::cout Product parts: partA_ , partB_ , partC_ std::endl;}private:std::string partA_;std::string partB_;std::string partC_;
};// 抽象 Builder 接口
class Builder {
public:virtual void buildPartA() 0;virtual void buildPartB() 0;virtual void buildPartC() 0;virtual Product getResult() 0;
};// 具体 Builder 实现
class ConcreteBuilder : public Builder {
public:ConcreteBuilder() {product_ new Product();}void buildPartA() override {product_-setPartA(Part A);}void buildPartB() override {product_-setPartB(Part B);}void buildPartC() override {product_-setPartC(Part C);}Product getResult() override {return *product_;}private:Product* product_;
};// 指挥者类负责构建产品
class Director {
public:Director(Builder* builder) : builder_(builder) {}Product construct() {builder_-buildPartA();builder_-buildPartB();builder_-buildPartC();return builder_-getResult();}private:Builder* builder_;
};int main() {ConcreteBuilder builder;Director director(builder);Product product director.construct();product.show();return 0;
}在这个示例中我们有一个产品类 Product包括三个部分。我们定义了抽象 Builder 接口包括构建每个部分的方法和获取最终产品的方法。具体 Builder 类 ConcreteBuilder 实现了 Builder 接口构建了 Product 的各个部分。指挥者类 Director 负责指导 Builder 构建产品。
使用建造者模式我们可以按照不同的需求构建不同的产品而不必关心构建的细节。这种模式尤其适用于构建复杂对象帮助将构建过程和表示分离提高了可维护性和可扩展性。
5.原型模式
原型模式Prototype Pattern是一种创建型设计模式其主要思想是通过复制现有对象原型来创建新对象而不需要从头开始构建。这种模式通常用于创建成本高昂或复杂的对象同时可以保持对象的不变性。原型模式基于对象的克隆可以分为浅拷贝和深拷贝两种。
以下是一个简单的原型模式的 C 示例
#include iostream
#include string// 原型类
class Prototype {
public:virtual Prototype* clone() 0;virtual void print() 0;
};// 具体原型类 A
class ConcretePrototypeA : public Prototype {
public:Prototype* clone() override {return new ConcretePrototypeA(*this); // 深拷贝}void print() override {std::cout ConcretePrototypeA std::endl;}
};// 具体原型类 B
class ConcretePrototypeB : public Prototype {
public:Prototype* clone() override {return new ConcretePrototypeB(*this); // 深拷贝}void print() override {std::cout ConcretePrototypeB std::endl;}
};int main() {Prototype* originalA new ConcretePrototypeA();Prototype* originalB new ConcretePrototypeB();// 克隆原型对象Prototype* cloneA originalA-clone();Prototype* cloneB originalB-clone();originalA-print();cloneA-print();originalB-print();cloneB-print();delete originalA;delete cloneA;delete originalB;delete cloneB;return 0;
}在这个示例中我们定义了一个抽象原型类 Prototype包括克隆方法 clone 和打印方法 print。然后我们创建了两个具体的原型类 ConcretePrototypeA 和 ConcretePrototypeB它们实现了克隆方法并在打印方法中展示自己的类型。
在 main 函数中我们首先创建原型对象 originalA 和 originalB然后通过调用它们的 clone 方法创建了相应的克隆对象 cloneA 和 cloneB。这些克隆对象与原型对象具有相同的状态但是是独立的对象。
原型模式允许我们根据需要克隆对象而不必重新创建。这对于创建成本高昂或复杂的对象以及需要保持对象不变性的情况非常有用。需要注意的是深拷贝和浅拷贝的选择取决于对象内部的状态和结构。在实际应用中可能需要自定义克隆方法以适应特定需求。
6.适配器模式
适配器模式Adapter Pattern是一种结构型设计模式它允许一个类的接口与另一个类的接口兼容。适配器模式主要用于解决两个已有接口之间的不匹配问题使它们可以一起工作而不需要修改它们的源代码。
适配器模式有两种主要类型类适配器和对象适配器。
类适配器 使用多重继承它继承了被适配类并实现了目标接口。
对象适配器 维护一个被适配类的实例并实现了目标接口然后委托被适配类的实例来执行相应的操作。
以下是一个简单的对象适配器模式的 C 示例
#include iostream// 目标接口
class Target {
public:virtual void request() 0;
};// 被适配类
class Adaptee {
public:void specificRequest() {std::cout Adaptees specific request. std::endl;}
};// 对象适配器
class Adapter : public Target {
public:Adapter(Adaptee* adaptee) : adaptee_(adaptee) {}void request() override {adaptee_-specificRequest();}private:Adaptee* adaptee_;
};int main() {Adaptee adaptee;Target* adapter new Adapter(adaptee);adapter-request();delete adapter;return 0;
}在这个示例中我们有一个目标接口 Target包括 request 方法。我们还有一个被适配类 Adaptee它包括 specificRequest 方法但它的接口与 Target 不兼容。
然后我们创建了一个对象适配器 Adapter它实现了 Target 接口并维护了一个 Adaptee 的实例。在 Adapter 的 request 方法中我们将调用委托给 Adaptee 的 specificRequest 方法从而使 Adaptee 可以与 Target 接口兼容。
适配器模式在现实中的应用非常广泛特别是在将旧系统与新系统集成或者使用第三方库时它可以起到很好的桥梁作用以确保不同接口之间的兼容性。
类适配器
类适配器模式使用多重继承来实现适配它继承了被适配类并实现了目标接口。以下是一个简单的类适配器模式的 C 示例
#include iostream// 目标接口
class Target {
public:virtual void request() 0;
};// 被适配类
class Adaptee {
public:void specificRequest() {std::cout Adaptees specific request. std::endl;}
};// 类适配器继承自 Adaptee 和实现 Target 接口
class Adapter : public Adaptee, public Target {
public:void request() override {specificRequest(); // 调用 Adaptee 的方法}
};int main() {Target* adapter new Adapter();adapter-request();delete adapter;return 0;
}在这个示例中我们有一个目标接口 Target包括 request 方法。我们还有一个被适配类 Adaptee它包括 specificRequest 方法但它的接口与 Target 不兼容。
然后我们创建了一个类适配器 Adapter它继承自 Adaptee 并实现了 Target 接口。在 Adapter 的 request 方法中我们可以直接调用 specificRequest 方法因为 Adapter 继承了 Adaptee。
类适配器模式使用多重继承这使得它可以同时继承多个类但也可能引入一些复杂性。适配器模式可用于解决现有系统的接口不兼容问题同时不需要修改被适配类的源代码。
7.装饰器模式
装饰器模式Decorator Pattern是一种结构型设计模式它允许你通过将对象包装在装饰器类的实例中来动态地扩展其行为而不需要修改其源代码。装饰器模式通常用于以下情况
动态地给对象添加功能而不是静态继承需要遵循开放/封闭原则即对扩展是开放的对修改是封闭的需要通过一系列可重用的装饰器来组合不同的行为。
以下是一个简单的装饰器模式的 C 示例
#include iostream// 抽象组件接口
class Component {
public:virtual void operation() 0;
};// 具体组件
class ConcreteComponent : public Component {
public:void operation() override {std::cout ConcreteComponent operation. std::endl;}
};// 抽象装饰器
class Decorator : public Component {
public:Decorator(Component* component) : component_(component) {}void operation() override {component_-operation();}private:Component* component_;
};// 具体装饰器 A
class ConcreteDecoratorA : public Decorator {
public:ConcreteDecoratorA(Component* component) : Decorator(component) {}void operation() override {Decorator::operation();std::cout ConcreteDecoratorA operation. std::endl;}
};// 具体装饰器 B
class ConcreteDecoratorB : public Decorator {
public:ConcreteDecoratorB(Component* component) : Decorator(component) {}void operation() override {Decorator::operation();std::cout ConcreteDecoratorB operation. std::endl;}
};int main() {Component* component new ConcreteComponent();Component* decoratorA new ConcreteDecoratorA(component);Component* decoratorB new ConcreteDecoratorB(decoratorA);component-operation(); // 基本组件操作decoratorA-operation(); // 增加了装饰器 A 的操作decoratorB-operation(); // 增加了装饰器 A 和装饰器 B 的操作delete component;delete decoratorA;delete decoratorB;return 0;
}在这个示例中我们有一个抽象组件接口 Component包括 operation 方法。具体组件 ConcreteComponent 实现了这个接口。
然后我们定义了抽象装饰器 Decorator它也实现了 Component 接口但在 operation 方法中调用了包装的组件的 operation 方法。具体装饰器类 ConcreteDecoratorA 和 ConcreteDecoratorB 扩展了 Decorator 类分别增加了特定的操作。
在 main 函数中我们创建了一个基本组件 component然后依次用装饰器 decoratorA 和 decoratorB 包装它。通过这样的嵌套我们可以动态地添加不同的行为而不需要修改组件的源代码。
装饰器模式允许我们以一种灵活的方式组合对象以满足不同需求。这可以帮助我们遵循开放/封闭原则同时保持代码的可维护性和可扩展性。
8.代理模式
代理模式Proxy Pattern是一种结构型设计模式它允许你提供一个代理类控制对其他对象的访问。代理模式通常用于以下情况
远程代理代理对象控制对远程对象的访问例如通过网络。虚拟代理代理对象控制对创建开销大的对象的访问只在需要时创建。保护代理代理对象控制对对象的访问权限用于权限控制等。智能引用代理对象添加额外的逻辑例如引用计数、懒加载等。
以下是一个简单的代理模式的 C 示例
#include iostream// 抽象主题
class Subject {
public:virtual void request() 0;
};// 具体主题
class RealSubject : public Subject {
public:void request() override {std::cout RealSubject handles the request. std::endl;}
};// 代理
class Proxy : public Subject {
public:Proxy(Subject* realSubject) : realSubject_(realSubject) {}void request() override {if (checkAccess()) {realSubject_-request();logAccess();} else {std::cout Access denied. std::endl;}}private:bool checkAccess() {// 检查访问权限的逻辑return true;}void logAccess() {// 记录访问日志的逻辑std::cout Access logged. std::endl;}Subject* realSubject_;
};int main() {RealSubject realSubject;Proxy proxy(realSubject);proxy.request();return 0;
}在这个示例中我们有一个抽象主题 Subject包括 request 方法。具体主题 RealSubject 实现了这个接口用于处理请求。
然后我们创建了代理 Proxy它也实现了 Subject 接口。在 Proxy 的 request 方法中我们可以添加额外的逻辑例如检查访问权限和记录访问日志。如果权限检查通过它将委托给实际主题 RealSubject 来处理请求。
代理模式使我们能够控制对对象的访问同时可以添加各种额外的功能例如权限控制、懒加载、缓存等。这对于保持代码的可维护性和可扩展性非常有帮助。
9.观察者模式
观察者模式Observer Pattern是一种行为型设计模式它定义了一种一对多的依赖关系使一个对象的状态发生变化时其所有依赖者观察者都会收到通知并自动更新。观察者模式通常用于以下情况
当一个对象的状态变化需要通知其他对象而且这些对象的数量和类型是未知的。当一个对象需要在不知道具体操作的情况下通知其他对象。当一个对象需要维护一系列依赖关系以便在状态变化时能够通知所有依赖者。
观察者模式包含以下几个关键角色
主题Subject主题是被观察的对象它包含一组观察者对象并提供方法来添加、删除和通知观察者。观察者Observer观察者是接收主题通知的对象它定义了更新方法以便在主题状态发生变化时能够执行相应操作。
以下是一个简单的观察者模式的 C 示例
#include iostream
#include vector// 观察者接口
class Observer {
public:virtual void update(const std::string message) 0;
};// 主题接口
class Subject {
public:virtual void addObserver(Observer* observer) 0;virtual void removeObserver(Observer* observer) 0;virtual void notifyObservers(const std::string message) 0;
};// 具体观察者
class ConcreteObserver : public Observer {
public:ConcreteObserver(const std::string name) : name_(name) {}void update(const std::string message) override {std::cout name_ received message: message std::endl;}private:std::string name_;
};// 具体主题
class ConcreteSubject : public Subject {
public:void addObserver(Observer* observer) override {observers_.push_back(observer);}void removeObserver(Observer* observer) override {// 寻找并移除观察者auto it std::find(observers_.begin(), observers_.end(), observer);if (it ! observers_.end()) {observers_.erase(it);}}void notifyObservers(const std::string message) override {for (Observer* observer : observers_) {observer-update(message);}}private:std::vectorObserver* observers_;
};int main() {ConcreteSubject subject;ConcreteObserver observer1(Observer 1);ConcreteObserver observer2(Observer 2);subject.addObserver(observer1);subject.addObserver(observer2);subject.notifyObservers(Hello, observers!);subject.removeObserver(observer1);subject.notifyObservers(Observers after removal.);return 0;
}在这个示例中我们定义了观察者接口 Observer 和主题接口 Subject分别包括添加、移除和通知观察者的方法。然后我们创建了具体的观察者类 ConcreteObserver 和具体的主题类 ConcreteSubject。
在 main 函数中我们创建主题对象 subject 和两个观察者对象 observer1 和 observer2。我们将观察者添加到主题中然后主题通知观察者时它们会接收到消息并执行相应的操作。
观察者模式使对象之间的关系松散允许主题和观察者之间的独立变化同时保持了对象之间的协作。这种模式常用于实现事件处理、发布-订阅系统以及任何需要实现对象之间松耦合通信的情况。
10.策略模式
策略模式Strategy Pattern是一种行为型设计模式它允许定义一系列算法并将每个算法封装到独立的策略类中使这些算法可以互相替换。策略模式的核心思想是将算法的选择与使用分离从而实现更灵活的算法切换同时不需要修改上下文类的代码。
策略模式包含以下几个主要角色
上下文Context上下文类包含一个策略接口的引用它可以在运行时切换不同的策略对象以实现不同的行为。上下文类不直接实现算法而是将算法委托给策略对象。策略Strategy策略是一个接口或抽象类定义了一个算法族的接口具体的策略类实现了这个接口每个策略类代表一个具体的算法。
使用策略模式的主要优点包括
算法的可独立替换性可以在运行时切换算法而不需要修改上下文类的代码。降低了上下文类的复杂性上下文类只需要关注如何选择和使用策略而不需要实现具体算法。提高了代码的可维护性和可扩展性每个策略类可以独立开发和测试容易新增新的策略。
以下是一个简单的策略模式的 C 示例
#include iostream// 策略接口
class Strategy {
public:virtual void doOperation() 0;
};// 具体策略 A
class ConcreteStrategyA : public Strategy {
public:void doOperation() override {std::cout Using Strategy A std::endl;}
};// 具体策略 B
class ConcreteStrategyB : public Strategy {
public:void doOperation() override {std::cout Using Strategy B std::endl;}
};// 上下文
class Context {
public:Context(Strategy* strategy) : strategy_(strategy) {}void setStrategy(Strategy* strategy) {strategy_ strategy;}void executeStrategy() {strategy_-doOperation();}private:Strategy* strategy_;
};int main() {ConcreteStrategyA strategyA;ConcreteStrategyB strategyB;Context context(strategyA);context.executeStrategy();context.setStrategy(strategyB);context.executeStrategy();return 0;
}在这个示例中我们有一个策略接口 Strategy定义了算法族的接口。然后我们创建了两个具体策略类 ConcreteStrategyA 和 ConcreteStrategyB分别实现了不同的算法。
上下文类 Context 包含一个策略对象的引用它可以在运行时切换不同的策略。当调用 executeStrategy 方法时上下文类会委托策略对象执行相应的算法。
策略模式的应用范围很广可以用于任何需要动态地选择算法的场景例如排序算法、计算费用、路由策略等。