zoukankan      html  css  js  c++  java
  • 框架设计总结

    前言

    毕业7年多时间,GIS出身的我从毕业就开始走上了编程的道路,接触过c++、java、.net,不过最终.net成了我营生的工具。

    7年终准确地说待过3家公司,纯做GIS软件的,一家做电信运营商软件的,现在这家做民航业务的,这3家公司有个共同点就是CS为主,偶尔冒出一个两个的BS小项目技术上也就是练练手入个门而已,所以始终对CS的框架比较关注,自己想做个总结,欢迎大家补充和指正。

    总体框架

    总体框架决定这个系统的未来诸多方面的命运,

    例如可扩展性:好的框架会预留一定程度的扩展能力,让未知的需求将来有容身之地;可读性:团队不是一成不变,加上现在的跳槽率一直很高,所以框架可读性是决定以后新人加入后上手、维护的成本,以及他的感受(谁也不想维护一个像垃圾堆一样的代码);可维护性:整体结构设计要很容易理解,设计要深入,不是项目开始的时候一拍脑袋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轴显示等可单独提出来一个节点,方便维护,也避免表内、图内的文字与表外图外的冲突。

    系统缓存

    当然系统缓存也少不了,不过实现起来也很简单。定义一些全局对象,用于存放系统级的数据和配置,需要时不用再请求数据库等。

    写出来是觉得自己能力有限,目前只总结到这个层次,欢迎各位拍砖。

  • 相关阅读:
    Ruby小白入门笔记之<个人记录档>
    Windows 10下怎么远程连接 Ubuntu 16.0.4(小白级教程)
    Ruby小白入门笔记之<Rails项目目录结构>
    GitHub 上传文件
    机器学习:项目流程及方法(以 kaggle 实例解释)
    数据科学:待学习的内容
    机器学习:项目流程
    数据科学:numpy.where() 的用法
    数据科学:Pandas 和 Series 的 describe() 方法
    Kaggle 比赛项目总结(项目流程)
  • 原文地址:https://www.cnblogs.com/wxbcrefut/p/3864978.html
Copyright © 2011-2022 走看看