在软件开发中,设计模式是一种被广泛认可的最佳实践,它提供了解决特定问题的通用原则。本文不打算全面介绍设计模式,因为已经有其他文章对此进行了更深入的探讨。相反,本文将讨论如何在考虑设计模式时,实现和重用C++模板。
使用模板实现设计模式的基本思想是将功能和交互分开。这意味着可以实施一个完全工作的类,例如一个TCP/IP类,然后在一个应用程序中将其用作单例,在另一个应用程序中通过工厂模式使用。使用模板,相同的基类可以用于任一应用程序,而无需编写派生类,只需添加一行代码。
单例模式是最基本的设计模式之一。在C++中,可以编写以下代码来生成一个简单的单例:
class my_singleton {
private:
std::string my_string;
public:
my_singleton() : my_string("foo bar bash") {}
static my_singleton &instance() {
static my_singleton global_instance;
return global_instance;
}
std::string get_string() {
return my_string;
}
};
调用全局单例以获取关联字符串的方法如下:
cout << my_singleton::instance().get_string() << endl;
这非常简单直接。当想要重构代码,或者偶然发现单例不是解决所有问题的方案时会发生什么?或者,如果要使用的单例代码是第三方的怎么办?使用模板化设计模式库,可以重构代码并更改设计,而不必担心这个问题。创建并使用单例非常简单,只需观察并学习:
class third_party_code {
public:
third_party_code();
bool execute_heavy_code();
};
typedef template_pattern::singleton
在上面的代码片段中,类third_party_code
由外部开发人员提供,无法访问或更改代码。相反,声明了一个类型名global_third_party_code
,它是单例实例的别名,将third_party_code
实例全局化。使用单例的方法如下:
if ((*global_third_party_code()).execute_heavy_code()) {
// ...
}
本文提供的库支持单例模式的简单实现,并不处理单例模式可能产生的多种问题。
与单例设计模式相反,现在来看一下工厂设计模式。工厂设计模式的基本思想是有一个中央存储库来实例化实现给定接口的对象。在中央位置进行实例化使得交换组件变得容易,例如,将实际数据库对象更改为不将信息持久化到数据库的存根对象。下面展示了使用工厂设计模式的直接方法:
class data_source {
public:
virtual std::vector
显然,这很好,也非常容易阅读。将其更改为使用设计模式模板库的更通用代码,得到以下代码,该代码更短,更容易阅读:
typedef template_patterns::factory
再次,优势在于代码的灵活性。使用模板,不再需要担心维护工厂类,此外,模板可以一次又一次地重用,而不会重复代码。
假设重新设计应用程序,并发现如果工厂是一个单例实例会更好怎么办?没问题:将设计模式作为模板,可以轻松更改代码设计。扩展上面的例子,得到以下代码:
typedef template_patterns::factory