Actor:人生如戏全靠演技--“三维度”逻辑编程语言的设计(3)

上一篇介绍了逻辑编程的做用,介绍了逻辑编程中的一些概念,包括逻辑程序的结构:事实、规则和问题;知识的表达方式:谓词演算、产生式规则,以及这些概念与三维度(角色+场景+时间)理论的契合关系,正式提出了“三维度逻辑编程”这个概念。为了更好的体现“三维度”的关系,今天要重点介绍一下角色的扮演者--Actor。html

其实,我是一个演员

这个标题来自电影《喜剧之王》周星驰的台词。人生如戏全靠演技,星爷这样说,咱们又未尝不是呢?编程

(图片来自网络,侵删)安全

在咱们的“游戏人生”这个游戏中,三好男人张三在家是丈夫,有了孩子后是父亲,他在老婆面前必须当好丈夫角色,在孩子面前必须当好父亲角色,一样张三在单位工做的时候必须当好员工角色,为了赚钱养家,老板要求996也得忍。。。加班回家一身疲惫,也得面带微笑,当好丈夫或者父亲角色。只有在夜深人静的时候,张三才能作回张三本身。张三一天深夜在某个聊天群写下了一段话:网络

夜深了,
我尚未睡,
想着写了2年半的代码,
是一种情怀,
能坚持到最后的勇气,
像极了18岁的本身。
我很菜,却依然坚持,
群里全是我膜拜的大神,
谈的我全不懂,
我依然愿意在群里,
发点感慨
明天继续!
           -----致和我同样努力写bug的垃圾码农

 

Actor就是那个演员

Actor,顾名思义:演员。在咱们的“三维度”逻辑程序中,使用Actor这个词来表示扮演角色的原生对象。Actor对象须要扮演多种角色,在不一样的地点(好比在家,在公司)、不一样的时期扮演不一样的角色。Actor是“社会化意义”上的人,好比行驶一我的或一群人的意志的团体,或者机构、公司,或者一部机器。若是Actor是一我的,就必定会扮演一个角色,一辈子要扮演不少角色,因此,Actor与角色的关系就像人和影子同样,只要在阳光下老是如影随行。架构

在当前这个“游戏人生”程序中,下面的示例代码描述了张三和貂蝉两个Actor对象具备的一些角色:张三是一个员工,张三同时也是貂蝉的丈夫;貂蝉是张三的妻子。框架

            //建立实体Actor对象
            Woman diaochan = new Woman() { Name = "貂蝉", Birthday = new DateTime(1990, 1, 2) };
            Man zhangsan = new Man() { Name = "张三", Birthday = new DateTime(1988, 3, 5) };
            //陈述事实:XX是YY角色
            Worker worker1 = new Worker(zhangsan);
            Wife wife1 = new Wife(diaochan,zhangsan);
            Husband husband1 = new Husband(zhangsan,diaochan);

注意上面的代码只是在申明Actor对象的实例,陈述Actor对象具备的角色事实关系。这里借助C#对象的构造函数,来为Actor对象申明一个相关的角色,这个角色会添加到Actor对象的角色集里面。可是为何要用角色对象的构造函数而不是Actor对象的角色集合添加角色对象呢?好比下面这样子的代码:编程语言

zhangsan.Roles.Add(new Worker);

zhangsan.Roles.Add(new Husband(diaochan));

上面的代码的确能够实现Actor Has a Role的效果,可是有几个问题:函数

1,上述代码没有以前的代码简洁;spa

2,以Actor对象为主,角色对象是Actor对象的附属对象.net

3,描述多个Actor对象之间的关系不方便,语义不清晰。

4,没法体现出逻辑编程中的谓词关系。

因此,要解决这些问题,或者说要弄清楚“三维度”逻辑编程的特色,须要深入的认识角色的含义,角色与Actor真正的从属关系。

Actor的马甲--角色谓词

谓词(参考定义)是用来刻画个体性质以及个体之间相互关系的词。在当前程序中,角色对象定义了对象的性质,也能够定义对象之间的关系,所以这里的角色就是一个谓词,Actor对象就是谓词对象的参数,一个谓词也能够表示多个Actor对象参数之间的关系。因此Worker、Wife、Husband都是谓词,是表达Woman/Man称谓的词。在逻辑编程中,强调对象之间的逻辑关系,这种关系就是谓词关系,逻辑编程就是谓词演算。为了更好的将逻辑编程与“三维度”(角色+场景+时间)理论联系起来,在“三维度”逻辑编程中将谓词称为角色谓词,程序的运行依赖于角色在系统中的交互。那么角色是什么,为何这么重要呢?

角色是一种特定的关系

人的社会性表如今人和人之间各类关系的总和,这些关系造成一个复杂的网络,角色是其中的一种关系。这种关系有时候是不稳定的,有时候是稳定的。例如:

  • 员工角色,他表现为某个特定的人当前是某个公司的雇员,员工和公司之间的关系是不稳定的、松散的,公司能够随时解约,因此员工角色定义的时候能够不指定从属的公司对象;
  • 丈夫角色,他表现为一个男性跟一个女性的家庭关系,这种家庭关系是稳定的,强有力的,要解除这种关系(离婚)须要复杂的法律手续,因此丈夫角色定义的时候必须明确指定男方对象和女方对象,女方对象从属于南方对象。
  • 妻子角色的定义与丈夫角色的定义相似。

经过这些角色关系,咱们的社会有机的组织了起来,有条不紊的运行着。总之,角色表达的是一个主体对象跟一个或者多个从属对象的关系,若是角色关系是不稳定的,从属对象能够不明确指出,当它仍然存在。

名不正言不顺

天下人无非追求的就是名利,要想作事就必须有一个名头,大到行军打仗须要“出师有名”,小到送个外卖,没有一个合适的工做角色就无法正大光明的去作事情,能作某件事情的名头就是角色,这个名头表明一种身份、社会地位以及权利。科学的解释是角色即为”必定社会身份所要求的通常行为方式及其内在的态度和价值观基础“。总而言之,一我的必须以某种角色去作某些事情,在作事情的时候扮演一种角色。为了明确区分不一样的角色,须要给每种角色一个约定俗成的名字,一个称谓,这即是角色谓词。

在“三维度”逻辑编程中,每个角色都是一个惟一的角色类,它们都继承自一个角色接口,该接口定义了角色名字和角色的拥有者,在定义具体角色的时候必须确保名字的惟一性和名字的约定俗成。

 interface IRole<out T> where T : Actor
    {
        string RoleName { get; }
        T Owner { get; }
        bool MatchRules(string ruleName);
    }

上面接口的定义反映出一个接口一定有一个它的拥有者,这个拥有者一定是一个Actor对象。这里角色拥有者做为角色对象的一个属性出现,也体现出来了角色和角色拥有者之间的主从关系。

角色才是真正的主人

前面说了角色的重要性,人必需要扮演一种角色去作某件事情,这是人的社会性的必然。人类社会就是由一套复杂的角色驱动着。这套角色,中国儒家称之为“礼”,君臣有礼,三纲五常,经过这套体系维持封建社会的稳定运转。现代国家更是设置了严密的等级体系,每一个二年都在这个体系里面生活、工做,好比体制内外的人社会地位有明显的差异,咱们每一个人都想去当公务员,都想当大老板。正是这些理想的社会角色,让咱们每一个人为之期盼、奋斗,永不停留脚步,有人叫你一声因此XX总,YY局,是否是很惬意?因此,你叫别人是什么不重要,别人叫你是什么才重要,角色才是咱们每一个人真正的主人。

这段话代表在描述角色和Actor之间的关系的时候,应该以角色为主,Actor为辅助,因此在咱们的逻辑编程中使用角色为谓词,称为角色谓词,以Actor对象为角色谓词的参数,使用C#来表达,就是前面已经说过的样子:

            Worker worker1 = new Worker(zhangsan);
            Wife wife1 = new Wife(diaochan,zhangsan);
            Husband husband1 = new Husband(zhangsan,diaochan);

 经过使用角色对象的构造函数,更容易将目光关注到对象的构造申明上,而不是构造的过程。咱们忽略无关的细节,更容易重视代码表达的语义,体现出了角色对象和Actor对象之间的从属关系。

虽说角色对于剧本讲故事很重要,可是再怎么重要的角色也须要一个出色的演员。演员的演技是可否驾驭角色的关键,下面须要咱们再来介绍下这位演员了。

 Actor的演技--角色的使用

演员的天分

没有Actor,角色将毫无心义,做为演员,它为角色而生。因此Actor对象须要内置一个角色集合,且不可移除,不可重置,只能向角色集合添加或者移除某个角色。每个Actor对象最终都继承自一个Actor抽象类,它有诞生时间,也有名字。此文,它还有扮演某个角色的方法,这让Actor天生有了当演员的才能。

    abstract class Actor
    {
        public Actor()
        {
            Roles = new List<IRole<Actor>>();
            AtTime = DateTime.Now;
        }
        protected internal List<IRole<Actor>> Roles { get; private set; }

        public T ActAs<T>() where T : class,IRole<Actor>
        {
            foreach (IRole<Actor> role in Roles)
            {
                if (role is T)
                    return role as T;
            }
            throw new InvalidCastException("Actor没有此角色:" + typeof(T).Name);
        }

        public DateTime AtTime { get; set; }
        public string Name { get; set; }
    }

 

再好的演技也须要角色

上面Actor抽象类的设计,让Actor具备了扮演角色的能力。咱们知道扮演角色是为了可以执行角色定义的方法,因为Actor的角色并非稳定的,角色在须要的时候才有,也会在特定的时候失去,因此在设计上Actor不能继承角色接口,也不该该将接口的方法直接定义在Actor对象中。那么可否让Actor对象直接执行角色对象的方法呢?也就是让对象动态添加一个方法/函数,这个功能在动态类型语言不是什么问题(好比Javascript、Python、Lisp等),但对于静态类型语言倒是很是困难的问题(好比C++、Java、C#、go等)。

下面演示的是Javascript动态添加属性和方法的例子:

var object = new Object();
object.name = "name";
object.age = 19;
object.fun = function(){
  console.log("这是一个动态添加的方法")
}

object.fun();//调用新增的方法

然而,采用动态类型语言这种动态添加方法的方案难以在语义上表达调用这个方法所包含的角色语义,更为重要的是调用这种动态的方法不能保证类型安全,好比让一个员工(角色)对象调用了老板角色“发工资”的方法这种错误的事情发生。“三维度”逻辑编程提出了角色谓词的概念,而且在设计上明确要求由Actor对象来扮演角色,经过角色对象来安全的执行角色的方法,这不只在代码上体现了角色语义,也保证了类型安全,让指定的角色干指定的事情,不会越俎代庖,每一个人职责分明,系统有条不紊。

Actor经过切换角色来实现不一样的功能,这个能够经过Actor对象的ActAs泛型方法来切换当前Actor对象的角色。ActAs泛型方法遍历Actor当前角色集合中全部的角色,若是找到就返回这个角色类型,找不到抛出异常,详细代码请看上面【演员的天分】。

回顾一下前面程序中Actor对象经过ActAs泛型方法切换当前角色执行角色功能的的示例代码示例,因为能够经过Actor对象来切换到拥有的角色对象,因此申明角色对象的变量都不须要了,这样能更加显示出角色谓词的强大力量:

           //使用角色谓词表示事实关系
new Worker(zhangsan);
new Wife(diaochan,zhangsan);
new Husband(zhangsan,diaochan);


//场景参与人开始扮演角色 diaochan.ActAs<Wife>().Child_bearing(); zhangsan.ActAs<Husband>().Money += zhangsan.ActAs<Worker>().Work(); zhangsan.ActAs<Husband>().Child_rearing();

上面的代码经过Actor对象切换角色来执行角色对象才有的方法,如故事男女主角做为夫妻功能才有的生孩子功能,以及男主做为员工角色进行工做赚钱的功能。事实上也原本如此,整个过程理解起来很是天然。

好演员更须要好剧本

好演员固然说到是饰演某个角色演的淋漓尽致、唯妙唯肖的演员,然而一个演员要饰演这样的角色,除了自身的演技,还得遇到很是好的剧本,毕竟一样的角色你们都有机会来当,好比我也想来演一次当老板的角色,但你是当一个小卖部老板仍是世界500强公司的CEO,这就要看导演给你的剧本了。演小老板有小老板的演法,演大公司CEO就必须有CEO的演法,这里的区别就是剧本中设定的角色规则,好比小老板角色设定的身价不能大于100万,而CEO角色的身价过亿,CEO能够聘请10000名员工而小老板只有本身一个员工。哪怕是一样的小老板,有的剧本是小老板一路开挂三五年作到大公司CEO,有的剧本是小老板当了不到一年就破产下岗了。这些剧本中决定角色命运的,就是编剧/导演给角色设定的规则。

因此,咱们的“游戏人生”剧本要讲好故事,介绍完了演员和角色,还须要重点讲讲角色的规则,这是下一篇文章准备讲的内容,也是“三维度”逻辑编程语言的重点内容,这部份内容在《SOD框架“企业级”应用数据架构实战》已经作了相应的介绍,手里有这本书的朋友能够先一睹为快。

 

 

--------------分界线-------------------------

构思整个系列花了2年多时间,写这篇文章写了3天,反复删改,但限于本人对于编程语言知识能力的浅薄,其中谬误确定不少,前几篇文章的内容也被PL领域的大佬批评略多。在此感谢这些大佬的批评建议,可是与大佬的水平相比较起来大佬在天上我在地上,不在一个交集上,因此这篇文章以及整个系列被大佬批判没法避免。只是但愿大佬可以手下留情,在点击文章【反对】以前先回帖留言详细说明您反对的地方,谢谢支持!

若是仅反对而不回帖留言,本人只好当您为空气,您的举手之劳毫无心义,一概略过。

相关文章
相关标签/搜索