最常见的 C++ 设计模式库是什么?
我在 Alexandrescu 的书中读到了关于Loki图书馆的内容,但现在看起来它有点死了。那里有类似的东西吗?
“设计模式是针对你的编程语言的错误报告”——Peter Norvig
要回答为什么没有很多 C++ 设计模式库的问题,首先要知道设计模式是为了解决什么问题。经典的 GoF 书在前言中陈述
设计模式描述了面向对象软件设计中特定问题的简单而优雅的解决方案。
90 年代的面向对象编程风格在很大程度上依赖于使用抽象类作为接口,而具体的实现类则派生自这些接口。GoF 模式描述了不同类类型的对象之间的创建、结构和行为关系。他们的关键元素是:封装和参数化任何会经常改变的东西。许多 GoF 模式也可以使用模板重新制定,但是灵活性受限于编译时而不是运行时。
面向对象的编程使得添加接口的不同具体实现变得非常容易。OOP 遇到的困难是向现有接口添加新功能。访问者模式是一个典型的例子:它本质上是一种变通方法,它依赖于额外的间接级别,以允许新算法在现有数据结构上工作。
这与函数式编程完全相反:使用函数式编程,很容易为现有数据添加新函数,但要添加适用于这些函数的新数据类型要困难得多。在函数和类型中获得可扩展性的困难称为表达式问题。
OOP 风格的多态性很大程度上基于内部多态性:动态函数调度基于对象的类型。现代 C++ 还使用外部多态性,其中类型擦除等技术允许使用静态接口实现运行时灵活性。新的std::shared_ptr
and boost::any
oradobe::poly
类是这些技术的主要例子。
Tobias Darm最近的ACCU 演示展示了许多将旧的内部多态 GoF 模式转换为这种新风格的外部多态模式的示例。粗略的想法是用可以std::function
作为参数的函数参数替换抽象类。然后std::function
从外部控制多态灵活性。许多 GoF 模式可以通过这种方式在样板方面得到极大的增强。
TL;DR:经典的 GoF 模式是为解决 OOP 的缺点而量身定制的。但 OOP 不再是占主导地位的 C++ 风格。通用编程(标准库、Boost)和 OOP 的组合可以更优雅地解决许多问题,使经典设计模式不再是首选解决方案。
The original definition of a design pattern was a reusable approach to a reoccurring problem that could not be conveniently encapsulated in a library. Thus, the moment you can encapsulate a pattern in a library, it ceases to be a pattern, in my opinion. This has, for instance, largely happened with iterators in C++, as the standard C++ library has a comprehensive framework for implementing iterators now.
I’ve never tried to use Loki, but reading Alexandrescu’s book, I was not persuaded that a library based approach really had much to offer for many patterns.
May 似乎是重言式,但最常见的是……标准库本身!
严格来说,它不是“模式库”,而是用于解决常见模式实现的许多工具的文件夹。
请注意,您的问题无法回答,因为模式只是各种问题中常用的概念定义。图书馆不提供模式,他们(可以)使用模式(就像其他任何人一样)来提供特定问题解决方案的实现。
模式比编码处于更高的抽象层。
为了提高代码的可维护性、可重用性和可读性,一些研究人员(如 GoF、Booch)开始研究最佳实践。他们注意到有经验的开发人员采用了一些模式来解决特定的设计问题。
如您所见,经验创造了设计模式。因此,使用设计模式就像专家一样编码。对此没有灵丹妙药。
确实,一些简单的设计模式(例如装饰器)可以从特定语言中获得支持。但这就是极限。领域特定框架还指导您使用它们的接口来完成由它们的作者决定的设计模式。
库只会帮助您了解该库中使用的设计模式将如何促进您的实施。它甚至不会让您选择更改设计。