(█(█(█(█(█(█(█请教通讯和面向对象设计方面的高手--通讯如何很好的和界面分离开来!!!!!!! (100分)

  • 主题发起人 主题发起人 NetNoCenter
  • 开始时间 开始时间
N

NetNoCenter

Unregistered / Unconfirmed
GUEST, unregistred user!
大家都知道在做基于TCP/IP的客户端应用的时候,许多大量接收到的消息需要表现到界面上(比如,发送过来的消息需要送到界面显示之类的),如果只是少量的界面,那这个问题不是很突出,但假如我要通知的界面很多,但底层通讯都用的是相同的东西的时候,感觉就很难组织了---也就是软件结构上很难组织了!

现在的问题是:
1 假如采用通讯直接和界面捆绑在一起的话--比如,界面上直接拖个SOCKET控件什么的(这样通讯其实是直接嵌入界面,和具体界面紧偶合),则这么多的界面根本没办法控制,写起来太复杂了,所以这种方法基本上不可行
2 假如把通讯模块单独放在一个类(或一组类)里,和界面分离开的话,则通讯类怎么设计才能适应不断变化或增加的界面呢??????
 
做成个动态库或什么之类的怎么样??
 
TO app2001:
关键就是这个“动态库或什么之类”的该怎么设计啊?要知道,通讯是双向的,不只是简单的函数调用!假如只是单向的函数调用,那这个类是比较好设计
 
看看设计模式
 
你的客户端是不是要主动的连接服务端被动的接收服务端的返回信息呢?如果是这样的话。
客户端只放一个ClientSocket1,服务端只放一个ServerSocket1就可以了.
客户端和服务端定义一个通讯层的单元,把你用到的通讯指令分类例如:连接请求;发送数据:断开连接;连接请求返回;发送数据返回。断开连接就没有返回了。定义好分类,分别写实现函数,所有界面的通讯调用这些函数,关于函数的返回值可以发挥“。。操作成功”或“。。。操作失败!”
这样说能明白吗?
 
通讯类和界面类有什么关系?
 
建议你找《Delphi高手突破》来看看,里面最后一章说的就是怎样实现界面与代码分离的示例。
 
《Delphi高手突破》不怎么样,不过总的来说还是值的,才35块钱吧。我买了。对界面分离未有数据库方面的实例,讲的是记事本
 
呵呵,偶并不是要楼主照抄例子呀,再说了,楼主是想要通讯与界面的分离,不是数据库。
 
还是用方法2。只要你的界面有相同之处,或可以归纳为几种类型,就可考虑用继承。
另外,在重新封装的通信控件里可提供若干property用于输入界面控件用,通信中的消息就显示在这些界面控件上
 
其实做通讯程序界面和逻辑分离不难,可以把地层通讯层做成一层,把他的OnRead什么的
做个接口提供给逻辑层,逻辑层再I/O分解,把不同的类型的消息分离成OnMsgOn,SendMsg什么的接口给界面层,我自己的代码基本上都是这么做的。不知道
其他朋友还有什么好的办法。
 
TO zhukewen:
惭愧,关于设计模式我虽然看了一下,至今比较明显也比较用的成功的就是用了一个Bridge

模式,把数据库和其他所有的如核心业务逻辑,界面等的完全的分离开来,但通讯和界面的分离

不象这种简单的同步调用,然后等待返回的应用,因为通讯是异步的!所以我感觉Bridge在这种

场合下不适用!其他的模式不知道有否比较适合这种场合的,若能指点一下,不剩感激!
TO:leg:


关于你说的是不是根据消息分类来通知不同的界面,假如是这个意思的话,首先,ServerSocket

1可以不用管,因为这是服务端的事情,我们来讨论ClientSocket1该怎么用,
假如说你把ClientSocket1包含到某一个界面类里(比如说主界面,典型的就象我们打开一个一

般的工程,然后拖一个ClientSocket放到这个界面上),那么这个ClientSocket1实例就和这个

界面捆绑在一起了,当消息来的时候,假如就是通知这个界面的,则正好,假如是通知其他界面

的,则需要在这个界面里去操作其他界面,更不好的一点是,当其他界面需要发送消息的时候,

又需要来这个界面里调用ClientSocket(为什么?因为整个系统典型的应用里一般只需要并且尽

量只用一条SOCKET来维护所有的通讯),这就造成了类之间的相互引用,解决办法是有的,比如

不直接调用类,而通过窗体之间互发消息来解决, 但这种方法一是非常麻烦,二是不符合类的

设计原则,也不利于代码的维护,所以非常不好!
所以,一般想到的是把ClientSocket1定义为一个全局变量(或叫全局实例),或建立一个通

讯类(两者效果是一样),这样就可以避免各个界面之间的相互引用,但这又产生了另外的问题

,我怎么样把接收到的消息根据分类通知到各个不同的界面(千差万别,别想窗体的继承什么的

)呢,一是在这个ClientSocket1的消息到来的时候,根据分离去动态操作各个界面,也就是说

,我有多少个界面,在我的通讯类里我就得包含多少这些界面的实例,这又把通讯和具体的界面

捆绑在一起了,维护也相当麻烦!!有朋友建议我在界面和通讯中间插入一个类,专门处理
接收到的消息,然后利用事件急智分别通知各个界面,我试了一下,不知道是我建立这个中间类

的方法不对呢,还是这种方法也存在误区,始终达不到界面和通讯完全分离的效果,关于这个方

法假如有人能提供好的建议的话,将非常感谢
TO ego:
谢谢,呵呵,一般的代码分离我感觉没什么问题,但处理异步通讯消息这方面不象一般的那种同步调用,不知道上面有否这方面的东西
 
如果用控件的话不太容易做到界面和逻辑分离,除非手动创建控件,要想做到真正分离,
最好自己封装WINSOCK,这个时候OOP就体现了强大的灵活性。
 
to 张无忌:
呵呵,和我现在尝试的非常接近了,我不是做成接口,是做成事件!
但具体应用时还是感觉有问题,我是这样做的:
A1:A界面类
B1:B界面类
CLIENTSOCKET:TCLIENTSOCKET

然后增加一个类TMID:中间类,这个类主要负责从CLIENTSOCKET的ONREAD事件里提取出消息,根据消息的不同,执行不同的事件,如OnMsgOn,ONfile什么的!
接下来就有问题了,比如,我在A1里加入一个MID1:TMID,实现了MID1的OnMsgOn事件,在B1里加入一个MID1:TMID,实现MID1的ONfile事件,这样,我发现其实是每个界面用了TMID的一个实列,但整个系统其实只有一个SOCKET连接,这里如何来维护这些分散的TMID实例处理的是同一个SOCKET连接来的消息?????到这里感觉就糊涂中了.....
 
这里我觉得和用不用控件应该没什么关系,因为不用控件,你可用的联系就是句柄,你一样要等待消息的到来,然后处理它,我觉得没什么两样的
 
这样不知可行?
1、采用2,通讯类提供一个回调函数(给不断增加的FORM提供注册“我将显示那些接收到的数据”的功能),这样每个FORM在CREATE之时,便调用这个通讯类提供的函数注册
可以假设这个回调函数的参数有 FORM的句柄,有我的数据时候处理函数(FORM提供给通讯类的函数)等,
2、每个增加的FORM提供一个回调函数给通讯类(在第1步,注册给通讯类),作用是当通讯类接收到的数据,根据第1步的注册信息,调用此回调函数(当然接收的数据可以做为参数)

吃完饭,再说
 
我感觉你的问题是没有一个逻辑管理类来处理所有的逻辑,
你的逻辑感觉都是分散的,缺乏一个核心类来调度所有的I/O。
 
我觉得可以这样去做:
1、将通讯类定义为全局的
2、通讯类中包含所有可能要显示的信息
3、在各界面中显示的内容,是各界面去通讯类中取的,而不是通讯类主动显示到各界面的
至于各界面怎么去通讯类中取值:最简单的就是用个定时器

这样,有关通讯的信息就只跟通讯类有关,而跟任何显示无关了。而显示呢也只是与通讯类中的显示信息有关,与通讯完全无关。对于显示界面要通讯等动作,则可在通讯类中定义相应的方法,在界面中调用即可。
 
"我感觉你的问题是没有一个逻辑管理类来处理所有的逻辑,
你的逻辑感觉都是分散的,缺乏一个核心类来调度所有的I/O。"
---呵呵,其他的逻辑我基本上理的比较清爽了,现在就差这个界面显示的问题,当然,假如简单一点考虑的话,也没什么问题,但比如假如以后我的通讯方式要改,或需要支持多协议之类的,或界面风格需要变换之类的,界面和通讯分离就非常有用了
 
后退
顶部