看了你推荐的文章,浏览一些代码。谈谈对你的说法的认识,看有没有理解错,顺便再解释一下我的观点。
1)每个model都可以完成“自己”的增删改查?
IObject中的I不是表示接口(Interface),而是智能(Intelligent)的意思吧?若是代表接口,这种写法有一本书《clean code》倒是不提倡,我一般也不这么写。智能对象(IObject)具备“可观察”和“自我记忆”(增删改查)的能力。
你举例Object的equlas、clone等方法,认为“只有具备智能的动物或者智能机器人才有的能力做这样的结论,大多数的对象是没有此能力的”。 对于没有智能的object1和object2,其比较只能由某个智能对象执行equals(object1, object2),而不是object1.equals(object2)。
智能对象具有这些方法,自不必多说。但非智能对象也具备这些方法,我觉得更多地考虑到使用上的方便,而非逻辑。且从使用者的角度上看,两种写法只是记法不同而已(一个OO,一个PO),也就是从说使用者的角度来看,其语义都是两个对象(不论是否智能)的比较。
你希望每个Object都天生具有“可观察”(observable)和“自我记忆”(memory)的能力,就像James Gosling设计的Object天生具有“通知”(notify/notifyAll)和“自我克隆”(clone)等能力。从这点来看,我是支持每个模型都可以具有“增删改查的”的操作。
之前我的观点是,“增删改查”的操作,尽量按逻辑分配到各个模型(model)中去,比如博文(非智能对象或元素级别的实体)的“增删改查”就应该由博主(智能对象或集合级别的实体)来做,也就说除了最底层的实体不包含“增删改查”的操作,较高层次的实体总有负责一些逻辑相关的较低层次的实体的“增删改查”操作,当然最顶级的实体的“增删改查”操作可交给service(模型之外)来进行。
我个人认为“非智能”对象的notify、notifyAll、clone等方法,是语义服从于语法的表现,是面向对象语法的约束力所致,此时也许用面向过程的表达形式更合理(不一定更方便),但在一般的OO中,这种情况我们似乎没有别的选择。
所以,总的说来,你所提倡的每个模型都具有自我“增删改查”的操作的“统一做法”是可行的,但是我认为按照逻辑分配这些操作,理解和使用可能更自然一些,分配时可能多费一点周折,但也许是值得的。
2)界面只与model打交道?
最初的MVC含义,就提倡智能的模型(Smart Models),简易的控制(Thin Controllers)和直观的视图(Dumb Views)。你所说的View我觉得意义可能有所缺失,即少了Controller,两者组成User Interface(UI)。暂且认为你所说的View,就是我理解的UI,这点上应该没有什么分歧。
Trygve Reenskau提出DCI范式,就是弥补MVC的缺陷,也就是弥补“智能模型”这一说法的不足。因为这种说法,隐藏了一种观点:无论用户进行任何操作,总有一个智能模型可以完成。
但是呢?总有一些操作的执行,需要多个智能模型相互协作方能完成,这就是场景。用户直接调用某个场景(Service)就可以使用多个智能模型相互协作提供的服务。再者,每个场景包含的服务或业务逻辑,并不适合放在任何一个模型中,因为这是多个模型相互协作才能完成的。所以,界面也要和场景(service或context)打交道。
补充一点:个人认为,Trygve Reenskaug在介绍DCI时,将model和controller中的一些东西抽离出来放入场景context与交互interaction中,这是表示两种范式某种意义上的联系,而不是相互取代的关系。因为MVC中的controller与DCI中的interaction的意义相近,都包含“交互、相互作用”之意,MVC的model与DCI的data的意义相近,都包含“实体、模型”之意。