初此尝试C# MVC设计模式,理解与不足
MVC(Model-View-Controller)称模型-视图-控制器设计模式,是一种常见的桌面软件设计模式。它的主要介绍在这篇文档中已经非常详尽(https://www.codeproject.com/Articles/613682/Your-first-program-using-MVC-pattern-with-Csharp-W)。
在这里简单介绍其背景,MVC模式的软件系统,顾名思义,就是主要由三个部件构成的软件系统(M- Model-模型, V- View-视图, C-Controller- 控制器),这种设计模式主要应用于有GUI界面的软件设计。三个部分的结构图如图所示:
模型(Model):一般是指与底层相关的部分,比如串口控制,文件打开与保存,数据加密与解密等底层数据收发管理的操作,都可以打包成相关的模型类来让Controller方便的进行调用。一般而言,可以将每个底层控制都封装成为一个Model提高程序的模块性以及类的内聚性
视图(View):就是指用户的GUI界面,在界面上用户点击输入输出操作,比如修改串口的相关设置,修改待保存的文件名,保存文件等需要底层支持的操作输入。同时,View还需要对Model中产生的相关事件做出反应,比如保存文件成功与否需要反馈用户,所以需要在用户从View中得到Model的反馈信息
控制器(Controller):是指软件需要根据视图部分的请求来对底层模型进行操作,比如将USB口中接收到的数据存入文件的操作,在窗口的用户看来,也许只是一个按钮的点击,但是其中的逻辑比如上例将USB接收到的加密信息解密,然后再根据当前的文件名将数据保存,这样的逻辑都是由Controller来组织的
利用C#组织MVC模式逻辑固然是清晰简单,但在实际操作时却会出现非常严重的Controller臃肿问题,本人在初次尝试时将文件读取与写入,串口操作,以及进程间通讯,防超时模块等部件都直接拼凑进入了一个Controller类中,虽然View与各个Model的接口能够比较清晰,各类的内聚性能够比较好,但是只有一个Controller类去协调其中的逻辑却让Controller的可读性极差,所以在此记录下来在应用MVC模式发现的问题以及相应的解决方法:
1) 不要让Controller的逻辑过多的暴露在View中
比如目前有一操作需求为用户点击按钮来保存文件,但是保存文件的文件名中的关键词需要用户输入,继而需要将其转换为完整的文件名再来保存文件。对于此类操作,逻辑的细节不应被View相应用户点击的处理函数知道,它只需要操作一个controller.SaveFile(this.GetFileName())便可以操作细节都隐藏在函数中无需为外界所知。不要让逻辑过多的暴露在外就意味着需要设计精简的Controller接口,让它能够合理的获取参数以降低暴露再外的逻辑。
2)对于多层逻辑,不要让Controller直接与Model操作
当Controller的下的Model类型较多时,直接在单一的Controller类中操作会极大的降低代码的可维护性,会使得Model之间的底层信息处理逻辑直接暴露在Controller层面,不能保证其封装性。所以在使用MVC模型时可以在Model与Controller之间建立相关的Service以达到分解Controller复杂度的目的,但是这里的一个降低复杂度的原则,不要让一个类中包含关系的类成员多于三个,成员变量超过七个,尽量减小类与类之间的合作关系。
3)设计工作的重要性远高于编码工作
初期应该根据项目的需求以及需要用到的技术工具(比如需要哪方面的知识?串口,网络,多线程?先熟料操作能够满足需求的工具),根据技术工具确定各个类之间的接口,然后再开始编码。