再一次理解mvc。到此结束。
一个程序,界面和数据放在一起处理,是混乱的源头,所以第一步就是要建立一个中间层来隔离view 和model.
所以自然形成mvc这3层,.这3层的通讯关系,比如control调用 model.可以包含一个model的接口,这样来降低耦合度。但实际上包含具体的model更常见,因为包含接口有设计过的之味。
但这3部分。v这个层比较特殊,因为view的中子控件变化是最频繁的,并且动作(方法)是很多的,所以和view 接触的control 在实际上一般不是control来调用 view的方法。
比如付钱后,更新界面,view并不会有一个方法叫 'updateUiafterPay' 来提供给control调用,而是control直接掌握view 的所有子控件,随意处理view.
基本上主流的界面系统。默认都是如此。
1.微软 web
后台页面可以直接获得view 的控件。(有一个隐藏的页面 xxx.design.cs 定义了所有的控件,提供给后台页面使用 ,并且会自动帮助注册事件)
2苹果 ios
没有微软那么细致,直接在前端页面注册了控件名字和绑定了事件,只是叫的好听了点,定义控件叫outle, 注册事件叫 target action.
<所有系统都喜欢叫个不同的名词浪费大家时间> (用记事本打开storyborad文件可以看到)
<button
<connections>
<action selector="onClickRight:" destination="BYZ-38-t0r" eventType="touchUpInside" id="aQ3-IE-GEf"/>
</connections>
</button>
<connections>
<outlet property="leftBtn" destination="Tmg-bu-8s9" id="6IX-K5-sjC"/>
</connections>
3.android
控件是默认会定义给control使用,事件的话默认需要自己注册;xxcontrol.setClickListener
可以看出,view由于变化大,逻辑细繁,导致和control天生就是紧密的。主流都是把他们捆绑在一起。所以
没有必要追求纯mvc,重点是mv需要彻底分离。control把业务逻辑再划分出来。
所以才导致了微软的三层结构非常流行。
导致mvvc在android .mfc也很流行。
反而mvc实际上流行不起来。
总结
view ,control 无法分离 , 2者在一起统称为 UI 交互层。
control 需要把业务逻辑分离,control中的业务部分分类出来叫 bll逻辑层。
model一般和数据交互,所以可以叫做 dal数据层或者model层。
但简单mvc会出现vc过于紧密,意思就是control出现了xxbutton.settext("xxxx") .直接操控某个按钮。所以要隔离。隔离可以有2种方式
1.view写方法 public void setbutton{xxbutton.settext("xxxx")} .control调用方法setbutton. 什么,方法套一个语句,就隔离了?
是的,自己入门的时候,十分不能理解。调用一个只有一条语句的方法,和调用一个语句有什么区别?
那是因为自己还没有真正理解意图和实现的含义。刚接触接口以为意图和实现,专指的是接口。
后面发现有心的话很多东西都可以看作意图和实现,函数,文件,地址,等等。
虽然方法只包含一条语句。但是它包含的是实现(里面的一条语句),而提供了意图(public 出来的函数名)。函数名某种程度上也是意图,
所以函数也是可以实现开闭原则的。当然没有接口那么专业。
2.进一步三方最好通过接口沟通。这样三方,理想上,只要实现了接口,可以任意替换其中一方。就可以用来替换掉。非常符合开闭原则。但是个人觉得走入随时替换view的思路,已经太过了。mvc本意只是隔绝m和v,替换,呵呵,设计过度的味道。
mvc:逻辑:view 负责展示自己,并对control提出数据需求,control处理view的需求的时候,会对view提出界面修改的及接口需求,同时control会和model通讯的来获得数据,而不是自己直接获得数据。
所以整体上view是一个入口和出口,
而control是处理逻辑,是逻辑上的主导者,并对view 提出界面上的接口需求,对model提出数据上的需求。
以上是理论,实际上要考虑和系统的结合等因素。
参考.net mvc 的框架。
ms的control是只处理业务逻辑的。倾向直接把数据给view, 界面的逻辑还是留给view自己处理。
对应于android 的项目,就是control最好不要进行太细节化的控制view.
如初始化 方法可以initview(map xx)这样前端可以拿到字典数据。自由处理自己界面。
用户动作可以xxdata clickOk()。这样control返回数据,操作交给view. view得到数据自己安排自己的显示,而不是提供接口给control来调用。
纯mvc的理论指导意义大于实际。因为vc天然紧密且易变。导致接口数量繁多而且频繁变化,所以接口隔离不实际。
但是如果理想上,时间和精力成本非常低。那么用纯mvc非常好。反正人力多,前期累点,最后看起来舒服,view有什么功能一目了然,还可以进行ui单元测试。
但实际上要考虑具体实现,
如view或者control哪个先出来。还是有另外一个类来控制他们的生命?
所以更实际的操作是分层和 粗糙的mvc ,
如微软的三层结构。苹果的粗糙的mvc(vc有接口,但v也可以直接掌握view的具体控件)
分层,把业务逻辑从control中分离出来,把数据获得从control中分离出来。
粗糙的mvc,view可以提供自己一些的方法。把view的一些稳定方法,如初始,等方法。分离到粗糙的view。
对于ui逻辑和业务逻辑,在细小上无法定位一把准尺,某段代码是放入到view还是control。所以团队合作肯定会有不同意见。无法判断的准则,就不能成为准则。所以纯mvc不可靠。
分层,粗糙的mvc目的就是减轻control的负担,因为vc完全通过接口沟通不现实。
看看google的所谓实现了纯mvc, todo中的一个简单页面,,都还有那么多接口,就明白了。
当使用分层,粗糙的mvc之后,你就会恍然回忆mvc的目的是什么?目的就是变化隔离,适应修改。
而分层,粗糙的mvc,已经吧变化分离了大部分,
比方实现100%mvc需要100%劳动力。我们用40%的劳动力实现了80%的mvc,
为了剩下20%的变化,而需要60%的工作量,到底是否合算?这个自己衡量。
第二次小结
感觉纯mvc还是一个概念大于实用的模式。
纯mvc,
view必须是独立的,1.view自己有初始和修改,展示自己的各种方法,提供control使用,2.view应该含有一个实现了icontrol对象的接口,用于把用户动作所表达的数据逻辑给control.
control 1.应该有含有一个view对象,用于初始化view, 2. 应该有含有一个view对象修改view的样子来响应用户某个动作。
model 1,应该自己构建自己,并含有自己的各种操作逻辑 2. model的数据来源一般可以分离出来另外一个类,以便model 本身不含有非通用的动作(model放到不同的项目,可能数据来源动作不一致)
model 层是比较好理解和实际操作。并且符合实际。
但是view和control,好理解,但不符合实际操作,因为view的操作可以非常繁琐,如果把view的操作全部封装为方法,那么将非常耗费时间。
比如用户点击按钮修改按钮颜色,如果control含有view,那么可以直接取得按钮,并修改按钮的颜色。但是如果纯mvc。control必须通过view的一个方法如,changeXXButtonColro(),
如上,view必须含有很多的方法。而且会处理频繁的修改中。
很多mvc的模式教程都会开篇说,为了把vc解耦,之后巴拉巴拉,试过,思考过好几种mvc,自己的感觉就是vc不适合解耦,vc天然的紧密,不但紧密,而且变化修改相当频繁。
今天按钮的作用是修改颜色,明天可能修改颜色和另外一个按钮的大小。后天可能不变。再后天这个功能还是取消。
所以vc不需要分离。但是可以把control进行分层。分离出一个逻辑处理层。control既然和view 那么紧密,那就紧密吧。但是control除了和view的逻辑以外,其他逻辑全部分离出去。
这就是我们的分层,所以一般分离出一个逻辑层。逻辑层中又可以把处理数据部分的逻辑分离出去。处理数据层,又可以把缓存和数据库分开处理。
就好象面向对象设计很正确的概念,但最终被面向组合,面向接口所代替。
mvc 那就没有实际了意义?其实稍微想下,从某种意义,view已经是分离出去了。比如按钮,他就是一个view啊。修改按钮的大小如 btn.setsize().这个方法,已经由系统帮你实现了啊。我们不需要在control中去实现setsize()这个方法。我们在control操作的view的控件。就已经是在操作view的方法,已经是部分mvc了。 view 不单是指整个界面,view看作单独的控件。就有所安慰了。
纯mvc,是不错,但是耗费人力,精力。个人感觉,满足2条之一就可以用。
1.必须要有人员充足,甚至需要有多余的劳动力去处理view的分离。或者有工具提供了自动机制。
2.这个可能是纯mvc的有必要的理由,如果你的项目ui层,足够复杂,用户的每一个动作,都会引起界面各种复杂的变化。那么需要进行ui层的单元测试。
ui层的单元测试,那么就必须把ui的方法独立出来,不能混合业务逻辑和数据。只需要ui逻辑。那么view就有了充分独立出来的理由。也就有了纯mvc的理由。
存在每一个动作,都会引起界面各种复杂的变化的app吗?基本不存在,所以纯mvc的指导,理论意义大于实际。
第一次小结
android mvc
看了官方的todo的mvp的例子。无法接受这种模式,严格的分离导致,view 的繁琐。
基本的mvp不好。
不喜欢v c的沟通是通过接口沟通。不喜欢view把显示自己封起来,让control来调用。这样view会有很多的细节操作,需要自己一个一个全部包装起来。
仔细想想,如textview, 的方法 settextview. 。我个人觉得settextview的实现已经是view了。而调用settextview这是是control。不再需要view去包一层方法,那个已经是逻辑了。
就该由control来控制。总结就是 view把显示自己封起来的方法,不应该是view,而应该是control。view的渲染任务止步于 这些控件本身的 ondraw.
完全的隔离,必然需要更细节的沟通。
所以,
view: 静态xml或代码技术,放置好控件。就应该是view所做的全部任务。view的渲染任务,止步于它自己最底层的draw方法。
conrol:可以直接获得控件,不应该让view封装方法,而感知逻辑,就算是显示也不行,如果显示全部由view控制,那么必定会非常繁琐。
直接让control获得view,并控制显示view。 这个其实是control,而不是view的显示范畴。view的渲染任务,止步于它自己的最底层的draw方法.
bal:因为control的任务会比较多。所以必须设置bal.把独立出来。
model:本地或远程数据。
先学习的ios,后学习的android。
发现对于mvc 的态度一致。还是喜欢 弱iew,强 control. control稍微包含多一点。所以分出一个business等。
微软已经死掉的asp.net ,虽然死掉了。但是它的分层模型却是非常简单,有效。view<--->control<---->business<---->Model
IOS 的mvc
综述:所有的运用程序,都逃不开展示和互动。
view: 负责创建界面元素,界面布局,负责接收外部互动,并通知control处理。
control: 负责控制view元素的实际数据,负责处理view发过来的动作的逻辑处理。并在处理逻辑中,在界面方面的操作上对view提出的接口需求,当然也负责从model获得,保存数据
model: 负责数据模型的逻辑,通常还有另外一个数据获得帮助类。(如Book 和BookDBHelper类)
因此==>
view:1,应该有一个方法初始化创建元素: initUi ..2. 所有元素都可以公开给control,以便展示实际数据。3 提供外对接口,并执行接口函数,实际由control来实现。 protocal: onclick
control:1..应该拥有view. 如可以先执行view的初始方法。并得到view. self.view=xxx ==>getSomeControl. 2..实现view 的接口 <pagePortocal> 3 实现某些系统封装好的元素的接口如 .ios 's protocal .eg:table delegate.
model: getlist ,updatesomemode. ,观察数据变动。并向订阅者发送通知。
因此,任何control,只要创建一个view的实例,并实现接口。都可以很好接管view.甚至可以管理多个view.
而view是独立的,不依赖于control.
其实可以推广到大多数的程序结构。
如.web.
html负责创建和布局。并负责post 数据到服务端处理。
服务端处理互动事件。asp.net ,可以知道任何view的元素并进行数据显示。
如
综述:所有的运用程序,都逃不开展示和互动。
view:负责创建界面元素,界面布局,负责接收外部互动,并实现一个可注册的机制,负责公开所有必须的组件元素,提供给control来实现互动和其他功能。
control:负责控制view元素的实际数据,负责注册互动事件和实现事件。负责从model获得或发送数据。
model:保存数据,并响应control的请求。
所以v和c通讯的话,没有完美的分隔。比如注册机制,要完美的话,应该是每个控件都提供接口。让control来实现。
但是这样就非常繁琐,所以在控件的基类中,提供注册机制,而让control自己来注册,虽然暴露了控件,不但获得的灵活和简便,而且也是必须的。
两个模块的通讯可以完全隔离,用派生类需要的接口实现(已经注册好,让调用方实现),也可以让基类实现接口让一个有主动控制权(主动注册和实现)
对于 V和C感觉还是让control有更多控制权,完全掌握view。view只做2件事情:建立控件,布局控件。
!!!!!!!!觉得可以写个例子模拟一下。注册机制和接口机制。2种事件驱动模式。
对于get,set有了新的一个理解。之前的理解是通用的,就是封装性。后面发现其实还是 1.延迟加载2.减轻程序复杂压力。
1.当用的时候才执行get.不必要再某个地方集中get.避免浪费资源。因为有可能这个属性这次操作根本没用到。
2.也可以省去心思思考某个变量放在那里初始化,特别是写某些脚本程序的 时候,用户接触的类基本是派生类,初始化一般不会去overwrite.