在 C++ 软件设计模式中,通常将设计模式分为两大类:类型模式(Type Patterns)和对象型模式(Object Patterns)。这两种模式在实现和应用上有不同的特点和目的。
类型模式(Type Patterns)
类型模式主要关注类的继承关系和接口的设计。它们通过继承来扩展类的行为,或者通过接口来定义不同类之间的交互方式。类型模式通常涉及类的静态结构,即类的层次结构和接口定义。
常见的类型模式
-
类适配器模式(Class Adapter Pattern):
- 通过继承的方式将一个接口转换为另一个接口,从而实现类的适配。
- 示例:通过继承一个现有的类来实现另一个接口。
-
类装饰器模式(Class Decorator Pattern):
- 通过继承现有的类来动态地添加新的职责或行为。
- 示例:通过继承一个类并添加新的方法或属性来扩展其功能。
-
静态代理模式(Static Proxy Pattern):
- 通过继承或实现接口的方式来控制对其他对象的访问。
- 示例:通过继承一个类并重写其方法来实现访问控制。
对象型模式(Object Patterns)
对象型模式主要关注对象的组合和协作。它们通过对象的组合和委托来扩展对象的行为,或者通过对象间的动态关系来实现特定的设计目标。对象型模式通常涉及类的动态结构,即对象在运行时的创建和使用。
常见的对象型模式
-
对象适配器模式(Object Adapter Pattern):
- 通过对象组合的方式将一个接口转换为另一个接口,从而实现对象的适配。
- 示例:通过组合一个现有的对象来实现另一个接口。
-
对象装饰器模式(Object Decorator Pattern):
- 通过对象组合的方式来动态地添加新的职责或行为。
- 示例:通过组合一个对象并添加新的方法或属性来扩展其功能。
-
代理模式(Proxy Pattern):
- 通过对象组合的方式来控制对其他对象的访问。
- 示例:通过组合一个对象并重写其方法来实现访问控制。
-
单例模式(Singleton Pattern):
- 确保一个类只有一个实例,并提供一个全局访问点。
- 示例:通过控制类的实例化来确保只有一个实例。
-
工厂模式(Factory Pattern):
- 提供一个创建对象的接口,让子类决定实例化哪一个类。
- 示例:通过工厂方法来创建对象,隐藏对象的创建逻辑。
-
建造者模式(Builder Pattern):
- 将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
- 示例:通过建造者类来逐步构建复杂对象。
-
原型模式(Prototype Pattern):
- 使用原型实例指定创建对象的种类,并且通过复制这些原型创建新的对象。
- 示例:通过克隆现有对象来创建新的对象。
类型模式与对象型模式的对比
-
静态与动态:
- 类型模式:主要涉及类的静态结构,即类的继承关系和接口定义。它们在编译时就已经确定了类的结构。
- 对象型模式:主要涉及类的动态结构,即对象在运行时的创建和使用。它们在运行时通过对象组合和委托来实现功能的扩展。
-
扩展方式:
- 类型模式:通过类的继承来扩展功能。这种方式的扩展是静态的,一旦编译完成,类的结构就固定了。
- 对象型模式:通过对象的组合和委托来扩展功能。这种方式的扩展是动态的,可以在运行时根据需要动态地添加或移除功能。
-
灵活性:
- 类型模式:相对固定,因为继承关系在编译时就已经确定,不太容易在运行时改变。
- 对象型模式:更灵活,因为可以在运行时动态地组合和管理对象,更容易实现复杂的功能扩展和变化管理。
-
代码复用:
- 类型模式:通过继承来复用代码,但可能会导致类的层次结构复杂,增加维护难度。
- 对象型模式:通过组合和委托来复用代码,通常代码结构更简洁,更容易理解和维护。
示例代码对比
类型模式示例:类适配器模式
cpp
#include <iostream>
class Target {
public:
virtual void request() = 0;
virtual ~Target() = default;
};
class Adaptee {
public:
void specificRequest() {
std::cout << "Adaptee 具体请求" << std::endl;
}
};
// 类适配器
class Adapter : public Target, private Adaptee {
public:
void request() override {
specificRequest();
}
};
int main() {
Adapter adapter;
adapter.request();
return 0;
}
对象型模式示例:对象适配器模式
cpp
#include <iostream>
class Target {
public:
virtual void request() = 0;
virtual ~Target() = default;
};
class Adaptee {
public:
void specificRequest() {
std::cout << "Adaptee 具体请求" << std::endl;
}
};
// 对象适配器
class Adapter : public Target {
private:
Adaptee* _adaptee;
public:
Adapter(Adaptee* adaptee) : _adaptee(adaptee) {}
void request() override {
_adaptee->specificRequest();
}
~Adapter() override {
delete _adaptee;
}
};
int main() {
Adaptee* adaptee = new Adaptee();
Adapter adapter(adaptee);
adapter.request();
delete adaptee;
return 0;
}
总结
- 类型模式(Type Patterns):主要通过继承来扩展类的行为或控制对象的访问,关注类的静态结构。
- 对象型模式(Object Patterns):主要通过对象组合和委托来扩展对象的行为或控制对象的访问,关注类的动态结构。
理解这两类模式的区别和特点,有助于在实际设计和开发过程中选择合适的设计模式来解决问题。类型模式适用于需要在编译时固定类结构的场景,而对象型模式则适用于需要在运行时动态管理对象的场景。