框架设计
方案设计:
从上而下介绍方案,依次为:
1.框架架构图。
2.介绍框架能做什么,开发者能做什么,怎么用。
3.介绍各个模块功能,及模块之间的关系。
4.模块具体实现,可以是伪代码。
注意:1.框架与业务无关,考虑重用和扩展性,常量不要使用枚举。
2.所有的Model需要有说明,并介绍字段含义。
总体框架
总体框架决定这个系统的未来诸多方面的命运,
例如可扩展性:好的框架会预留一定程度的扩展能力,让未知的需求将来有容身之地;可读性:团队不是一成不变,加上现在的跳槽率一直很高,所以框架可读性是决定以后新人加入后上手、维护的成本,以及他的感受(谁也不想维护一个像垃圾堆一样的代码);可维护性:整体结构设计要很容易理解,设计要深入,不是项目开始的时候一拍脑袋1个小时内决定了怎么设计就按照这种方式去做,如果这样的话你或者你的团队终将付出代价;可复用性:好的设计能剥离出业务相关的东西,业务无关的东西、项目间通用的东西等等,是个技术积累沉淀的过程,也是自我提高的途径。等等诸如此类特性不一一赘述了。
模块管理:系统由各个功能模块组成,每个模块包括不同业务功能,将这些模块灵活的管理我的方法是采用反射,设计一个配置文件xml或者db table都行,配置功能模块的Show menugroup、icon、Initialize,系统启动时统一加载,如果未来像换个实现方式也不需要更新所有程序,只需要修改配置文件,替换功能对应的dll即可,或者改下菜单图标、名称等等。
容器:这么多模块来回切换,需要一个容器来装载,根据项目需求可以是single docment也可以是multiple docment,这些统一交给容器来初始化、缓存、切换显示等。容器与模块是松耦合的,如果觉得容器设计不好看,可以单独换掉容器部分,其他部分不用变。
组件管理
我这里把模块和组件分开来说,是根据模块是功能性的,与业务相关的,组件应该是包括模块的,有功能性组件,有非功能性组件,例如一些通用Util类等。
- 我在框架搭建的时候,一般要求具有一个Common目录,里面包含的组件有:
DataAccess:数据访问组件,包含几个常用数据库的provider,随着项目的积累可以逐渐补充其他数据库的访问。里面定义了常用的GetDataTable,GetDataSet、ExecuteNonQuery、Transcation、ExecuteReader等常用操作。
Config:配置组件,一个系统难免有一些配置文件,通过通用的配置组件来读取、访问他们、可以写一个泛型类即可解决,技术简单但思路很清晰很好用,个人觉得。
Log:日志组件,很多人用log4net都行,我一般是自己写的,也没多少代码,但用起来顺手。
Util:工具组件,定义一些常用的并且通用的xml序列化、反序列化、压缩、读取excel、文件操作、directory操作等等,也是个随着自己经历的项目越多逐渐补充积累的组件。
Control:控件组件,一般项目都有固定的界面组件库,可以基于公司常用的库,根据业务特性做一些展示上的封装,一般的功能可以就直接拿来用了,界面统一、速度快、省事省力,例如我们以前表格、趋势图、柱状图、仪表盘展示很多,封成组件后只需要给一个DataSource就可以了。
DataType:数据类型,为通用组件服务的一些数据结构和类型。
- 除了通用的组件外,还有就是业务方面的,一般我建一个Modules目录,里面包括:
模块里的通用部分,我叫它InternalCommon,包括:
Entity:模块数据结构
DataMapper:模块的一些数据访问封装,有些查询类的可以不封装,管理编辑系统的数据访问方式有限可以做封装。
模块中部分模块共用的一些InternalUtil、InternalControl、InternalService等等
模块本身部分:直接叫Modules,根据业务需求分成不同的模块,划分的依据一般根据业务相关性,相关性大的放在一个模块里,便于管理和阅读、将来修改某个功能只需要替换某个功能模块dll即可。
组件通信
通信一般我们会想到事件event,这种两个组件或者窗体间的通信是紧耦合的,一般模块内部会使用,但模块与模块之间的通信一般采用事件聚合器来做,
事件聚合器的有点是松耦合的,所有的消息管理都有聚合器本身去做,你只需要在发消息的模块中Publish消息,在收消息的地方Subscribe消息,给一个约定好的ID以及封装数据的结构即可。但也要慎用,用得太多到时候跟踪调试的时候比较麻烦,所以我的原则是模块级别的消息用它来做,普通的消息还是用.net的event来完成。
数据访问
见组件管理里对应部分
配置管理
见组件管理里对应部分
日志管理
见组件管理里对应部分
角色权限
这也是一个系统不可或缺的部分,比较重用的做法是建立角色与用户:
角色拥有权限,然后设置角色与用户的对应管理,每个用户对应有一个或多个角色,每个角色可分配给多个用户,一种m:n的关系
有些系统会涉及到按钮级别的权限,个人觉得这种不是太多,如果有的话可以在角色下设置功能节点,功能节点下设置按钮节点,对其进行权限设计。
多语言化
当时我做的有些项目会买到海外,所以涉及到了一些多语言的东西,不过当时设计方案很一般,有没有可借鉴的价值请自己衡量 呵呵。
最外层有一个多语言的配置,用于系统最常用的OK 、Cancle、Commit、Update等等,因为一个系统这类型的按钮基本上会这么叫,所以没必要重复定义。
但也有一些不这么叫的那就用功能自身的多语言配置文件,每个功能模块对应一个自己的配置,如果想覆盖最外层的配置,直接新增一个即可。
还有一些情况,比如表格内的字段名称,图的xy轴显示等可单独提出来一个节点,方便维护,也避免表内、图内的文字与表外图外的冲突。
系统缓存
当然系统缓存也少不了,不过实现起来也很简单。定义一些全局对象,用于存放系统级的数据和配置,需要时不用再请求数据库等。