在设计类方面遇到的问题

来源:5-7 实现聊天室监听器:ChatHandler(下)

cherry车厘子

2019-10-02

为什么addClient,removeClient都是定义在Server,而不是定义在Handler,明明handler都是调用Server?如果仅仅是因为map定义在Server,传给Handler为什么传的是Server对象,这样会不会太耦合了,传个map会不会好些?想听听老师在设计Server和Handler的思路

写回答

1回答

Stannum

2019-10-04

同学你好~这是个好问题~我来简单谈一下设计ChatServer和ChatHandler时的思路:

首先,这两个类所代表的事物有本质上的不同。ChatServer是一个实实在在的聊天服务器的抽象,而ChatHandler(作为Runnable的子类)是一个任务的抽象。

存储在线客户的connectedClients,是只属于服务器的属性。因为每一个ChatHandler其实只需要负责处理一个客户端连接,所以Handler是不在乎其他在线客户的,将存储所有在线用户的属性强加给ChatHandler是不合适的。

正因为connectedClients是ChatServer属性,所以将操作connectedClients的各种方法的实现(addClient(), removeClient(), forwardMessage()等等)都放在ChatServer中,这样可以保证所有针对ChatServer内部属性的操作,都被封装在ChatServer类中。其他类如果需要操作connectedClients(比如这里的ChatHandler),只能通过调用ChatServer公开的借口来完成操作,这样恰恰是减少耦合性的设计。

相反的,如果ChatServer直接将connectedClients传入给ChatHandler,就等于是允许ChatHandler用它自己喜欢的方式随意操作改动connectedClients。这种把A类的内部属性开放给B类的行为,反而是增加A和B之间耦合性,且会破坏A类本身的信息隐藏。

当然了,设计是一个开放的问题,课程中的代码也并不是唯一一种可行的设计。比如说,如果把ChatHandler中的实现完全搬去ChatServer类里面,也没有问题。我单独创建一个ChatHandler类,其实是为了让大家更清楚的分开服务器和任务处理这两个不同的抽象对象。

这么好的问题,请大家一定多问~如果还有不清楚的地方,我们继续探讨~

8
0

系统学习Java网络编程 深度理解BIO/NIO/AIO

对比式学习助你真正理解BIO/NIO/AIO三大网络编程模型。

880 学习 · 148 问题

查看课程