平常心谈软件设计模式(二)

来源:互联网 发布:db2删除数据库命令 编辑:程序博客网 时间:2024/04/30 00:29

小弟平常心谈软件设计模式(一)中讲解了原型模式,有位大侠给我建议很好,说叫我要一个一个将设计模式具体的运用场景,小弟打算从()中开始摆出实际例子来说说设计模式到底怎么去用。我之所以在这一篇中还是不去讲解,主要是还是想跟各位分享下设计模式的美妙成果,强调一下设计模式无处不在。

小弟这一讲主要是Observer模式,也就是传说中的观察者或者订阅-发布模式。简单讲模式本身,重点分析该模式的两个典型运用:javawebMVC架构和MFCdoc/view架构。

 

一.Observer模式:

先引用下K_Eckel老师的模式图:

Subject作为发布者为它的关联对象Observer提供注册和注销功能,这些关联对象放在一个链表中,当有Notify动作的时候就能遍历链表,找到注册的对象去调用它们的函数,这里给的是例子是Update()。由于SubjectObserver出现了两种关系,这里简单区分下:关系立场去区分,它们只是关联关系(a-a)subject是分别强依赖于Observer的各个子类,创建各个子类的操作对象;动作立场上去区分,它们是组合关系(contains-a):发起某一个动作的时候需要强依赖于一组对象,也就是对象链表。

 

二.运用之一:MVC

上个简图:

MVC就是是模型(model)-视图(view)-控制器(controller)Controller的主要用途就是决定调用那个model去处理数据,组织那个view去显示内容。View主要负责用户界面的显示和操作。Model负责数据的处理。

当然在这里 ViewControllerModelcontroller是双向关联关系,彼此包含和调用(小弟认为我们平常的运用系统可以按这个结构划分,但是仅仅使用一个observer模型,缺点太多,威力大减,需要配合mediator等其它模式方发挥最强威力,此是后话,下片详解)。

这个MVCObserver模式的对应关系为:controller就是 Subject的位置。Viewmodel就是Observer的位置。

小弟只是在这里简略的介绍了下MVC的最最基本的思想,比如具体MVMC是怎么交互的,如果是做B/S系统的大侠在SSH框架中应该比较清楚,不做的话,知道这个思想也就够了。

三.运用之二:Doc/View

先来看看MFC的对象关系图:

D/V模型中主要讲解的就是 CDocumentCView之间的关系。

首先简单的阐述下MFC的单文档工程的创建和工作过程:

一个单文档工程的CWinApp最先创建出来,CWinApp对象去创建一个单文档模版CDocTemplate对象。CDocTemplate对象去创建CFrameWnd对象,CFrameWnd初始化中去创建CView对象,CView对象被创建出来后会将自身的this指针注册到CDocument类中去。

CDocument主要管理数据,CView负责界面展示,CFrameWnd负责工程框架。当CDocument管理的数据有更新时就会通过UpdateAllViews(…)函数给注册过的CView对象发消息去通知CView类数据有变化,CView接收到CDocumentUpdate消息后就会响应OnUpdate(…)CView接着就会通过GetDocument()去获取具体变化的数据,然后在OnDraw()函数内通过DC对象绘制到界面。

好了,很笼统的说了下D/V流程。这个不是我要讲述的重点,我要表述的关键是这个模型体现Observer设计模式的思想。

 不难看出,CDocument扮演的就是设计模式中的Subject,而CView就是Observer角色。

 

四.知识点扩展:

1.             MVC框架思想的最好的实例得数当下流行的WEB工程框架:Struts-Spring-Hibernate。由于小弟不是重点研究SSH工程的,也无法给出明确划分界定,可以肯定strutActionServlet绝对是C的角色。

2.             MFC的消息机制。MFC的命令消息的运转过程可以分三部分讲解,一是消息的发送函数体,二是消息的接收队列及分发消息函数,三是消息映射机制。MFC工程的CWinApp创建一条主线程或者叫UI线程然后会继承父类的消息循环体Run()函数以及消息泵PumpMessage(),还会继承祖父类的OnCmdMsg()函数去传递发送消息或者重新去实现之。当然各个从CCmdTarget派生出来的子类都可以覆盖这个超类的OnCmdMsg函数体。在默认的OnCmdMsg函数体内会去调用GetMessageMap得到目标类的消息映射数组,经过匹配然后去触发命令消息的函数体。OnCmdMsg()传输消息,Run()维护消息队列,PumpMessage()分发消息,GetMessageMap去触发消息响应函数。

五.总结:

该模式实现了展示层跟数据层的真正解耦,是我们平常开发运用项目的经典模型。

当然如果Observer角色有多个,并且有上下层次的区别时,我们仅仅就用Observer模式去实现就只能达到单向的解耦无法实现层次之间的真正解耦,如果配合上使用Mediator中介角色那就不一样了,敬请关注小弟的小一讲 observer+mediator+Command模式搭建QQ通信框架。

原创粉丝点击