重复历史话题--GP

Jinhao Jinhao 墨衍会员 · AI 创作全网分发 墨衍智能分发 通过墨衍一键同步至各平台 可同步平台 CSDN微信公众号微博知乎掘金百家号博客园抖音小红书 你的文章也可以这样分发 墨衍会员 ¥399起/年,写一次发全网 我也要 + 加入社区
现代程序开发最关注的一件事之一就是如何提高代码的可复用性。

OOP提供了抽象概念来构建一个统一的世界模型,具像的物理对象被实现在这个简单的抽象模型体系中,最终形成庞大的树型结构来覆盖由该抽象涉及到的方方面面,可复用性由此诞生。

GP提供了另类的复用方法,让算法与类型无关。

在大多数的开发中,GP的运用几乎为空白,其实这并不是坏现象,除了让部分代码变得稍微优雅,剩下的可以说在大部分情况下,GP都是画蛇添足。在开发中,我们努力用OO的知识和经验来创建类,让这些类对象相互协同工作来达到目的,一般情况下,我们是处在一个很小的问题域中着手解决具体的问题,不需要更多的思考,所以template关键字几乎可以不用出现在我们编写的代码当中。

在以往的观点中,GP和OOP就像两条平行线,一边是静态多态,一边是动态多态,这样的观点让很多人误解了GP,加上在实际工作中,几乎不写template关键字,从而加深了这种误解。

到底GP存在的意义在哪里?相信大多数C++程序员都会用到STL,正是GP造就了STL的应用如此广泛。GP是一种用来开发高效,高复用程序库的编程范式,所以在实际工作的大多数项目中,GP对我们来说可有可无。用GP来分析问题的三个步骤:
1,将抽象问题域分类成Concepts.
在STL中,迭代器按行为被分类成5类。Input/Output/Forward/Bidirectional/Random Access Iterator。

2,基于这些Concepts,设计泛型算法。
例如std::generate要求Forward Iterator,而std::next_perutation要求Bidirectional Iterator.

3, 创建Concepts的具体模型。
例如,std::vector的Iterator,std::map的Iterator。

其实GP的分析方式与OOP极其类似,都是由具体的事物寻找抽象,然后按抽象来设计,最后基于抽象实现具象。

那GP编写的泛型程序库到底好在哪里?
可复用性:
我们尝试用OO来实现vector
class oo_vector
{
public:
void push_back(vec_elem_t& r)
{
vec_elem_t * n = r.clone(*this);
//hold n ...
}
};

如果我们要使用oo_vector,那么存储的元素类型必须由vec_elem_t派生并实现clone方法。如果用C++ Templates来实现,复杂度自然降低。至少我们的元素类型不会出现派生自vec_elem_t, map_elem_t, list_elem_t等等这种庞大的多重继承的情况。

粘和性:
用上面的oo_vector来思考。如果有一个现成的类,要让oo_vector来操作,该怎么办?C++ Templates应用到这种情况下大大提高了粘和性和可复用性。

Templates把C++变得太“泛”了?
C++是强类型语言,继承确定了两个类的关系,这种关系可以某些方法作用于子类对象上,他们之间存在着一种限制。而对于一个泛型算法,它能接纳的模板参数T,从形式上,看不任何限制,但这会使你的代码编译失败。例如把std::list的iterator传递到std::find中,得到的编译错误是iterator缺少某某东西,在这种情况下,如果编译错误能提示list的iterator不能用在find里,这样就会友好很多。其实这不仅仅只是提示得友好,因为我们在设计这种泛型算法的时候就是依据上面提到的Concepts,这种 Concepts在目前的C++语言中,只是一个潜在限制,作为泛型库的使用者,很容易忽略掉这种限制。或许有人会认为,如果C++引入Concepts的限制来做类型的检查,那么它还会是GP吗?它仍然是GP,显而易见的,泛型库的设计是从Concepts出发的,这好比一个子类是从基类出发一样。

Concepts会是画蛇添足吗?
就算语言引入了Concepts,那么list的iterator仍然不能用到find中去,这和没有Concepts的情况完全一样。Concepts描述了一组抽象的行为,我们可以提供一个算法函数来处理具有这种行为的类型,它的引入会把人们的关注目光从围绕T上转移到Concept上,这能更好地表达每个抽象的核心思想。按Concepts来特化算法,比按类型来特化算法,是更好GP。在解决list::iterator应用到find的问题上,只需要特化一个符合list::iterator Concept的find即可。

现在看来GP和OOP似乎很相似了,从分析的角度来说,他们的方向是一样,只是方法不同。这两个范式的区别不像OOP和面向过程那样,立竿见影。或许说,GP和OOP都应该是一种“泛型”,GP是基于行为抽象,OOP则是基于事物抽象。在OO的设计中,我们仍然会考虑到行为这一问题,只不过从OO的角度来说,这太隐晦,而GP在这方面则表达得更好,更抽象。
...全文

相关推荐

GP-Pro EX 使用秘笈

首先,GP-Pro EX 的一个重要特性是其画面创建技术,它允许用户有效地减少画面数量。通过重复利用原有的画面数据,结合各种精美图片,可以快速构建新的画面,大大节省了设计时间。

heybill123

Memory(记忆层)—— 核心就一个:让 AI 记住和你的对话上下文,不用你重复说背景,像真人聊天一样自然。

功能:不存全部对话,而是自动总结对话核心内容(比如 “用户是 Java 开发,想学习 LangChain 的 Memory 组件”);优点:节省内存,支持长对话;适用场景:聊很久的场景(比如一步步拆解创业思路)。Memory = AI 的聊天记事本,解决 “健忘” 问题;最常用的是 ConversationBufferMemory(简单)/ ConversationTokenBufferMemory(实用);用法固定:初始化 Memory → 绑定到 Chain → 直接调用,不用关心内部逻辑。

流量留

GP遗传编程_HH.zip

通过对历史数据进行拟合,GP可以生成能够描述数据趋势的函数,这些函数可用于预测未来数据点、发现隐藏的模式或者简化复杂系统的模型。

看那片云

MC68HC908GP32CRE使用说明书

#### 四、修订历史- **2001年7月**:修正了多个技术细节,如PTC到PTC1的修正、时间基控制寄存器的保留位描述、晶体振荡器组件值的更新等。

susuzhenyu

画面和逻辑编程软件GP-Pro-EX的五大特点.doc

**用历史趋势图轻松分析故障原因** 历史趋势图功能可以记录和显示过去一段时间内的数据变化趋势,这对于分析系统故障的原因非常有帮助。

zhangao_fengg
评论 14
收藏 已收藏
分享
返回顶部
Jinhao
非技术区 15,445 成员 58,111 内容