白话面向智能体编程(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 条评论
登录 后参与评论

相关文章

来自专栏Python爬虫实战

设计模式:抽象工厂模式

抽象工厂(Abstract Factory)模式提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。抽象工厂模式又称为Kit模式,属于对象创建型...

821
来自专栏数据科学与人工智能

【SQL技能】浅谈数据分析中的SQL

很久没写东西了,正好群里有童鞋最近要换工作,提到有关数据库方面的问题,个人认为,做数据分析的并没有必要把数据库开发之类的弄懂,你只需要从相应的数据库中调用你需...

2695
来自专栏程序人生

谈谈边界(Boundary)

上篇文章(Phoenix 1.3,迈向正确的道路)简单提了下「边界」,今早在火车上,顺着这个思路想了下去,写了篇 slide,中午分享给了团队。 我们做系统,做...

2496
来自专栏我是攻城师

Lucene暴走之巧用内存倒排索引高效识别垃圾数据

26710
来自专栏HansBug's Lab

【作业】HansBug的前三次OO作业分析与小结

OO课程目前已经进行了三次的作业,容我在本文中做一点微小的工作。 第一次作业 第一次作业由于难度不大,所以笔者程序实际上写的也比较随意一些。(点击就送指导书~)...

3096
来自专栏IT派

我用 Python 爬取微信好友,最后发现一个大秘密

你身处的环境是什么样,你就会成为什么样的人。现在人们日常生活基本上离不开微信,但微信不单单是一个即时通讯软件,微信更像是虚拟的现实世界。你所处的朋友圈是怎么样,...

1264
来自专栏禁心尽力

Java设计模式之适配器设计模式(项目升级案例)

 今天是我学习到Java设计模式中的第三个设计模式了,但是天气又开始变得狂热起来,对于我这个凉爽惯了的青藏人来说,又是非常闹心的一件事儿,好了不管怎么样,目标...

2228
来自专栏Java架构沉思录

同样是晶体管,为什么寄存器比内存快?

计算机的存储层次(memory hierarchy)之中,寄存器(register)最快,内存其次,最慢的是硬盘。

701
来自专栏java架构师

设计模式学习笔记之中介者模式

最近在学习设计模式,把学习过程中的点滴思考记录下来,其中也有一些从网上看到的精彩解析。 先从中介者模式开始记录。 精髓:将一堆对象(同事类)之间的复杂交互,封装...

36810
来自专栏苦逼的码农

为什么寄存器比内存快?

计算机的存储层次(memory hierarchy)之中,寄存器(register)最快,内存其次,最慢的是硬盘。

612

扫码关注云+社区