VB.net 观察者模式

 

Perry很喜欢MP4,每天没事就上网看行情:这个好,这个贵,设计这个的应该有逃课...Perry就是个观察者,但这还不是一个观察者模式。如果,行情能够告诉Perry说:你要找的MP4出新品了。这才是一个观察者模式。


但,行情怎么知道Perry喜欢MP4,而不是CUP?并且,当MP4有新信息时,行情又怎样来告诉Perry呢?对于做行情的人来说,这是个烦人事儿,但观察者模式能够解决这种场景要求,因为他使用了委托机制。

委托,就是Perry在行情看板中设定:如果有新的MP4行情,就通过EMail发送到他的邮箱。抽象来说:

  1. 通过EMail发送到他的邮箱,就是来向用户在系统中登记的某种方法传送消息

  2. 如果有新的MP4行情,就是某个条件满足要求

这里头包含以下几层含义:

  1. 用户能够在系统中登记某种方法

  2. 系统能够调用某种方法

  3. 用户和系统需要有一个公用的接口来统一“某种方法”

C++中第3点是不需要的,只要使用函数指针就可以:int (*addTemp)(int,int)#include <cstdlib>
#include <iostream>
using namespace std;

int add(int a,int b){
           return a+b;
}

int addFunction(int a,int b, int (*addTemp)(int,int)){
          return addTemp(a,b); //实际上是调用add方法
}

int main(int argc, char *argv[]){
     cout<<addFunction(1,2,add)<<endl; //add方法地址被传入addFunction函数
     system("PAUSE");
     return EXIT_SUCCESS;
}


但大家都知道VB.net中是没有指针这个东西的,需要另找“救命毫毛”。VB中有Delegate这样的关键字,从用途上来看,它就是实现委托的唯一选择(实际上也不是,用户可以定义自己的回调类型及体系,来实现类似于Delegate,但有几个人会这样做?就当没有)。


委托(Delegate)VB中的定义

Delegate sub DelegateName(Msg as String),注意这条语句生成了一个委托类型,而不是一个过程.

Public Delegate Sub DisplayMessage(ByVal msg As String) '委托的定义:处理一个字符串


Public Class ITMessage '假设它是一个IT信息看板

Dim ClientShowListens As List(Of DisplayMessage) '需要记录各种委托请求(每一种类型,一个集合)Public Sub Rigister(ByVal ClientShow As DisplayMessage) '委托请求登记
        ClientShowListens.Add(ClientShow)
End Sub

Public Sub Run() '看板在运行
        '.....
        '有新的信息了,要通知登记了的客户:
        ShowMessage("有新的MP4,5.1寸液晶,VGA分辨率,电池能用5,能看PDF文件,还能写VB程序")
        '.....
End Sub

Private Sub ShowMessage(ByVal Msg As String)
       
For Each ClientDisplayMessage As DisplayMessage In ClientShowListens 
                       
ClientDisplayMessage.Invoke(Msg) '调用客户自己的处理方法,来处理 Msg
        Next
End Sub

End Class


Public Class ClientPerry
       
Public Sub ShowMessage(ByVal msg As String) 'Perry是这样处理信息的:只看不买。
               
'Perry的信息接收过程
       
End Sub
End Class


Public Class ITShowSite '信息看板的启动
       
Public Sub RunITShowSite()
               
Dim ClientPerryObj As New ClientPerry() '一个客户
               
Dim ITMessageObj As New ITMessage() '信息看板
               
ITMessageObj.Rigister(AddressOf ClientPerryObj.ShowMessage) '注册客户的信息处理方式
                ITMessageObj.Run() '启动信息看板
       
End Sub
End Class


以上是一个委托到调用的过程,每一个客户(其实不用客户类型,只要他有符合Delegate Sub DisplayMessage(ByVal msg As String) 的过程,就可以在ITMessage中注册,甚至是模块中的方法ClientPerry是只看不买;ClientTom是胆汁型的,直接下单;而ITRobot则将信息收集起来,作成文件给老板...



回调

委托的另一种用法:

Public Delegate Sub DisplayMessage(ByVal msg As String)

Public Class ITMessage

        Public Sub ShowMessage(ByVal clientDisplayMessage As DisplayMessage)
               
'...
                clientDisplayMessage.Invoke("有新的MP4")
        End Sub

End Class


Public Class Client
       
Public Sub ShowMessage(ByVal msg As String)
       
'Perry的信息接收过程
End Sub

End Class


Public Class ITShowSite
       
Public Sub RunITShowSite()
               
Dim ClientPerryObj As New Client()
               
Dim ITMessageObj As New ITMessage()
               
ITMessageObj.ShowMessage(AddressOf ClientPerryObj.ShowMessage) '回调:客户对象中的方法
       
End Sub
End Class


模型/视图/控制器,分层

一个不恰当的比喻

模型: 数据

视图: GUI

控制器 数据与GUI的通信


模型,视图通常不是由MVC本身确定。他们依赖于业务逻辑和客户操作习惯。他们之间应该会有这样那样的表现上的差别和各自的调整,而匹配工作就由控制器来负责。


其实,PerryMVC也没多少认识。他认为有可能在不同的应用层,MVC的表示方式会不一样。对于终端代码来说能够清楚地将视图和数据隔离开,就可以了。搞得太复杂,对解决问题没多大的好处。总而言之,PerryMVC这个话题,选择了撤退。


而分层相对而言要好理解一些,它更多的是取决于开发者对项目的了解程度,归纳于经验,而不是技巧。层可以使应用清晰,部署灵活等等。不过要注意,层分的越多,所带来的额外开销也越多。需要协调层与层之间的通信,层的划分也会带来设计开发上的成本。


Perry明白,所有的规范,模式,场景。均需要和实际的解决问题相联系,要均衡考虑时间,人力,客户目标。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值