上周和两个朋友聊天谈到了面向对象,大家对程序中对象定义的范畴进行了讨论。对象可以是现实世界中的实体,对象可以是作用在这些实体上的一组操作,也可以是多个实体之间的相互作用。程序员经常把需要实现的一种服务定义为对象,或者一个流程定义为对象。面对现实世界中的诸多因素,究竟能抽象出哪些对象定义? 我从讨论中受到了一些启发,结合最近正在看的状态机和规则集合,有了些想法记录于此。
现实世界最基本的要素是事物和事物之间的关系,即实体和实体之间的作用。具体表现为:
(1) 实体有个体和集合的概念,如个人,人群。
(2) 实体包含多种属性,这些属性值的笛卡尔乘积即是这个实体的多个状态。
(3) 实体受到外部作用,引发自身的反应,自身状态发生变化。这是状态机模型,是实体被动的反应。
(4) 当自身状态和外部状态满足一定的条件,实体执行一些动作,对其他实体作用。 这是规则集模型,是实体主动的反应。
我们在程序里首先可以把实体定义为对象,对象上的方法则是对象受到外部作用后被动反应和主动反应的综合体现。如图所示:
从应用的角度来分析:
(1) 方法反映为对实体的操作。即外部作用于实体,实体状态发生变化,再依据变化后的状态,做出一些反应,作用其他的实体。例如“人.挨打”这个方法,在方法内部根据输入的打击的力度和部位,改变一些自身的状态,再根据状态决定逃跑或者还击。
(2) 方法反应为实体提供的功能和服务,即实体处理分配的任务。外部通知实体,交给实体一些要处理的任务,实体根据状态决定怎么处理,将处理后的结果返回。例如“人.工作”这个方法,输入工作任务,根据状态决定是否做还有怎么做,将处理后的结果返回。
(3) 多个操作可以组成一个更高层次的操作。一个操作的实现内部可以引发一个或者多个其他的操作。
(4) 同样多个服务可以组成一个更高层次的服务。一个服务的实现内部可以依赖于一个或者多个其他的服务。
(5) 一组对操作的调用可以组成一个流程,成为更大的一个操作。一组对服务的调用可以组成一个流程,实现为一个更大的服务。
(6) 更高层次的操作和服务可以没有现实中的实体来对应,但程序里可以定义一个新对象来包含这些更高层次的操作和服务。
(7) 实体对象和对象上的方法是一对多的关系,很多时候我们把这些方法提出实体对象之外来定义实现。这些方法可以构成一个新对象,方法实现对象。好处是一个实体对象可以在运行时绑定不同的方法实现对象。
(8) 多个对象组成集合。对集合的操作引发对集合内部各个对象的操作,集合提供的服务由集合内各个对象的服务组合而成。
概括一下:在程序中,我们首先把现实世界中的实体定义为对象,对象的方法表示对象上的操作和对象提供的服务;我们可以把这些方法提到该对象之外定义实现,组成一个新的对象;多个操作和服务可以构成更高层次,更大的操作和服务,可以定义一个对象包含这些没有实体对应的操作和服务。
按照以上的思路,和设计模式作对应,觉得有很多契合的地方:
(1) 对象的状态机模型和STATE(状态)模式对应。
(2) 对象构成集合和COMPOSITE(组成)模式对应。
(3) 实体对象和方法对象分离,对应INTERPRETER(解释器)模式,INTERATOR(迭代器)模式,VISITOR(访问者)模式。
(4) 大的操作和大的服务由更小操作和服务组合而成,对应DECORATOR(装饰)模式,CHIAIN OF RESPONSIBILITY(职责链)模式。
(5) 一组操作和服务调用构成的流程实现为新的对象,对应TEMPLATE METHOD(模板)模式。
设计模式的一个中心思想就是保证方法集合(即接口)最大程度的固定,可以对实体对象动态绑定同一接口的不同实现;多个实体对象和这些实体对象组成的集合具有同一接口;细粒度的操作和服务与由它们组成的粗粒度操作和服务具备同一接口;在流程既定时可以动态绑定流程中间一些方法的不同实现。以此来确保程序有好的扩展性。
不在此具体描述,关于面向对象和设计模式的思考有点容易意会,难以言传。觉得很难把自己的想法说的全面透彻,至少一小篇文章不行。:)