白话面向智能体编程(Agent Oriented Programmig, AOP)之二

Agent之前-Object世界

在说起Agent之前,俺们还有必要先敬拜一下Agent的前辈Object,因为Agent实际上是由Object“进化”而来的。这话说出来,可能有些读者同志不太高兴了,Object有什么不好吗?现在这么多复杂的系统,不都是基于OO的思想设计出来的吗? 

然也,OO的确为提高软件开发效率做出了很大的贡献,但是在使用过程中,OO也暴露出了一些处:

痒处一:OO并没有对现实世界中的实体加以区分

在OO世界中,所有的软件实体都是Object,现实世界中的一张发票和一为员工,映射到OO世界中都是一个Class。Class发票具有一些数据(日期,金额)和操作(效验,保存),Class员工也具有一些数据(姓名,职位)和操作(上班,下班),从映射的角度来看,任何现实世界的实体都是数据和操作的集合。但实际上,在现实世界中,发票和员工还是有区别的。区别在哪里呢?在于发票是一个物体, 而员工是一个有心智的实体。发票类的方法只能是被动地被调用,如果我们不调用,任何一张发票都不会自动的进行效验或者保存。而员工的方法调用与否,是由员工自己来决定的。今天生病了, 不高兴上班,上班操作就不会被执行,今天任务重,他就会自动执行加班这个操作。换句话说员工类的操作不是被动调用的,而是自发完成的。

这种只能被动调用和自发执行的区别,归结一下其原因,是因为员工具有自己的心智,而发票是没有的。传统的OO并没有引入这个区分,而这种区分的却失所造成的结果就是所有的操作都是被动地等待调用。虽然我们也可以引入计时器,或者多线程技术来模拟主动操作,但这种并不完全贴合现实世界的设计思路是不是让各位隐约感觉有些不爽呢。

痒处二:同步和异步被人为地剥离。

上面讲的是OO对有些东东没有区分,这点说的是OO对某些东东又多余地加以了区分。比如,现实世界中,老师对同学们说:“请把书翻到78页。”老师并不需要知道翻书这个操作对于同学们来说是同步操作还是异步操作,他并没有说“请把书同步地/异步地翻到78页。”换句话说,翻书这个操作是同步还是异步,对于调用者(老师)来说,是不需要知道的,同学们知道就OK了。但是影射到OO世界中,对于调用者来说,他在调用的时候,就必须知道是同步调用还是异步调用。归纳起来说,在现实世界中,调用方式这种知识,是被调用方拥有的,而调用方是不需要考虑的,但在OO世界中,这个知识由被调用方转移到了调用方。Something is different。体会一下,这种差异会带来什么样的问题。

痒处三:无法自然地模拟现实世界中的感知能力(Sensebility)

举个烧菜的例子来说明感知能力。老妈教俺烧菜的时候,常用的语法是:“当什么什么的时候,就怎么怎么样”。比如:当水烧开的时候,把肉放进去;当鸡块炸至金黄色的时候,捞出锅来。这就是感知能力的例子。鸡块作为感知源,它的属性可以发生变化;俺作为感知器,可以捕捉到鸡块的颜色这个属性的变化。如果鸡块的颜色由肉色转变至金黄色,俺就必须做出相应的操作/处理:把鸡块捞出锅来。

这种感知能力在现实世界中是非常普遍地存在的,然而映射到OO世界中来,却显的有些别扭。如果我们将鸡块和人构造为两个Class,要想人能感知到鸡块上某个属性值的变化,首先想到的是使用观察者(Observer)模式,在.Net平台下呢,则是在鸡块类中构造一个delegate,然后将人的某个操作挂到这个delegate上,当鸡块颜色值发生变化的时候,触发这个delegate。这种方式至少存在三个让人感觉别扭的地方:

l 鸡块就是鸡块,为什么鸡块这个Class里面要包含一个额外的delegate呢,这个delegate的存在对于实现鸡块这个class本身的逻辑来说没有任何意义,对于鸡块的逻辑而言,这个delegate是完全多余的,这还只是颜色属性上的delegate,不难想像,如果外界还有其他Class需要感知鸡块类其他属性上的变化,会有更多的delegate,更多的与鸡块本身逻辑不相干的代码出现。

l 注意到一个比较细节的问题。俺在看到鸡块颜色变为金黄色后,执行的操作是把鸡块捞出锅。这个“捞出锅”的操作,是由俺的心智来完成的,不是受鸡块的心智指挥,它自己蹦出锅来的。而在上面提到的使用delegate的解决方案中,我们把“捞出锅”这个操作挂载到delegate上,则“捞出锅”是由鸡块当前占用的线程来执行的,如果将线程理解为心智的话,则意味着是由鸡块的心智控制着人将自己捞出锅。是不是很诡异J 更直白地说法是:应该有一个线程来处理鸡块颜色的变化,另外再有一个线程来收到颜色变化的通知,并执行“捞出锅”的操作。这里有同志应该说了:也好办,把delegate的机制修改为多线程的就OK了!的确是这样,但需要注意的是要保持多线程机制对鸡块和人的透明性,如果因为需要贴近现实世界而增加Class的复杂性,那也违背了我们的初衷。

l 最后一个问题比较有意思。在现有的delegate解决方案中,我们只能针对实例(Instance)进行注册,而不可以针对类型(Type)进行注册。什么概念呢?比如锅里面有十个鸡块,俺得把“捞出锅”这个操作到这十个鸡块上依次注册一遍,才能保证每个鸡块在适当的时机被捞出来。是不是觉得和现实世界中的实际情况有些出入J 如果能够提供针对类型的注册机制,只要将俺的后续操作到鸡块类上注册一次,在感知范围内的所有鸡块,管他是十块还是二十块,都能被俺感知到颜色上的变化并执行正确的后续操作,这样会来的更简洁,更自然。

上面罗罗嗦嗦给OO挑了些毛病。实际上归纳起来就一句话:OO并不是对现实世界最贴切地模拟。而软件世界的终极目标是为了模拟现实世界,既然OO并不是最贴切的模拟,问题也就暴露出来了,改进的余地也就显现出来了。

  怎么改进?轮到Object的接班人Agent出场了。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏ImportSource

程序员求生秘籍

不过即使是假新闻,也着实把人们吓得够呛。为此,我试图理了十个实用动作给大家保平安。

1304
来自专栏阮一峰的网络日志

代码的抽象三原则

软件开发是"抽象化"原则(Abstraction)的一种体现。 所谓"抽象化",就是指从具体问题中,提取出具有共性的模式,再使用通用的解决方法加以处理。 ? 开...

3454
来自专栏java一日一条

Java程序员的错

这些年来,在我见过的各种 Java 代码中,我发现这最大的问题是,写代码的人痴迷于把自己当作架构师。他们很喜欢这样,在我阅读他们的代码时,经常会发现这些代码与其...

622
来自专栏小白客

如何通过学习C语言来入门编程

本文仅仅针对编程小白而言,大神请绕过。 大多数人学习编程的第一步应该就是学习C语言了,那到底该怎么学习C语言?我讲一下我的亲身历程。 大一的时候,我们有C语言这...

3625
来自专栏程序人生 阅读快乐

编写高质量代码:改善Java程序的151个建议

在通往“Java技术殿堂”的路上,本书将为你指点迷津!内容全部由Java编码的最佳实践组成,从语法、程序设计和架构、工具和框架、编码风格和编程思想等五大方面对J...

711
来自专栏非著名程序员

优秀程序员眼中的整洁代码

有多少程序员,就有多少定义。所以我只询问了一些非常知名且经验丰富的程序员。 ? Bjarne Stroustrup,C++ 语言发明者,C++ Programm...

2067
来自专栏程序员宝库

比较优雅地编码

命名很重要,随便一本逻辑学教材(如果读者有兴趣,此处推荐《逻辑学导论》)里都会有长篇大论来讨论命名的问题,我国古代在人才辈出的百家争鸣时期曾经出现过一个学派叫“...

1333
来自专栏牛客网

一点咨询 提前批 大数据岗 面经总结

【每日一语】这个世界,生活,人本身,都是荒诞的。不要白费心智去猜,去理论,因为无可猜,无可理论。事情并不一定要因为一个理由而发生,发生之后并不一定要达到什么目的...

1241
来自专栏程序员八阿哥

你是如何自学 Python 的?

我是自学的Python。从对Python一无所知,到在博客上写Python相关的系列文章(Python快速教程),前后有将近三年的时间。期间有不少门槛,但也充满...

1071
来自专栏牛客网

热乎乎的网易游戏游戏研发工程师一面

面试小哥哥人很好说话,没有自我介绍直接进入主题,先聊了C++,然后数据结构,最后两道算法题

1292

扫码关注云+社区