目前对一个大型的web业务系统进行修修补补,增加功能,完成工作之余,不得不对大量冗余的工作量表示抱怨。一个好的系统应该 对修改关闭,对扩展开放。
下面开始意识流。。。。
- 统一的命名规范与接口
命名规范没什么好说的,一个团队不一定要找最好的规范,但是必须统一。 接口与敏捷开发有些许的冲突,互联网的日新月异,敏捷的快速迭代,貌似不能再开发初期就把整个系统设计好。不过还是有很多的规范或者习惯在项目或者说全部开发初期约定好,比如方法名称的命名方式,重载的命名方式,参数顺序等等等等。 几个简单的例子。
- GetList的时候 返回值尽量用 IEnumable 而不是 List或者IList。
- 重载的时候差异的参数应该放后面等等。
- (减少&整合) 函数参数 比如对查询结果进行筛选,通过下面的方式 ,如果要增加一个筛选条件。。。太痛苦了
public IEnumable<Model> GetList( int? cityID, DateTime? beginTime, DateTime? endTime){}
不如下面这样,这样在以后的修改中不需要因为增加一个查询参数对很多Service代码进行修改。
public Class QueryFiter { public int? CityID{get;set;} public DateTIme? BeginTIme{get;set;} public DateTIme? EndTIme{get;set;} } public IEnumable<Model> GetList(QueryFitter fiter){}
- AOP,权限,日志:
目前的设计是将管理业务与权限管理(日志管理)完全结合在一起(操作前都需要判断权限),耦合度高,且引入大量冗余代码,需要每个操作都进行判断。 比如:
public class A { public method() { //权限判断逻辑 //核心逻辑 //记录日志 } }
而在一个系统中,类似的权限控制会很多,这些代码就好像一颗颗毒瘤一般蔓延于系统中的各处,一旦需要扩展,冗余的工作量很大,而且很容易出现遗漏和bug。
我能想到的解决方案:
- 利用AOP进行业务的横向切入,把权限判断逻辑和日志记录逻辑完全独立出来。(最好的办法)。PostSharp & 自己写一个简单的AOP框架。
- 利用装饰着模式,对于每个业务类进行包装,不过会产生大量的类。不过可以通过泛型 特性Attribute和反射改善一些。
- 使用MVC里的Fitter(如果使用mvc )这样应该也是AOP范畴吧
改善后的代码应该是这样的
public class Component:IComponent { [RequireAdmin(Power=999)] [Log(lever=1)] public Method A(){ } }
- 数据库查询
1.ORM
关于ORM,不能因为ORM而ORM。 如果业务太复杂,需要大量的多表查询,各种jion, union,这时候就不要使用ORM。 为了实体映射,有时候在做多表查询的时候可能需要会把所有的数据取出来,然后用相关的逻辑去拼接出需要的数据,导致数据库查询非常慢。 而且,对于敏捷开发,增加一个数据表字段应该很常见的需求,如果ORM,则需要修改多个地方。
2.延迟查询&延迟加载:程序员都想偷懒,何况数据了。
3.能早筛选尽量早筛选,最还在select的时候就使用Where条件筛选掉。特别是多表查询的时候。
- 缓存
应用缓存可以减少数据库压力,提供页面速度。 非实时数据可以缓存,或者说可以缓存的大数据(查询缓慢)都应该尝试着缓存。
- AJAX
JS框架,不管是Jquery mootools 或者自用的框架,必须统一,而且存放的目录和要取的文件名必须约定,调用方式也应该统一。返回的Json格式也要用统一的规范。
AJAX处理程序,如果是同一个业务,可以放在同一个ashx里处理。使用反射+xml+?工厂方法避免switch是一个很好的注意。或者使用反射实现客户端调用服务端方法也是个不错的主意。
AJAX必须有返回数据,客户端必须在确认服务端返回成功的信息后才更新网页,不能没收到确认就先更改页面。错误的提示要尽可能详细与易懂,能帮助开发人员快速定位bug。
- 异常
说说我的想法:异常处理,除非是可以容错的错误,不如,在service层里不应该把异常Catch掉,即使Catch掉(比如记录错误日志,数据库回滚,也应该继续throw出来,然后在展示层告诉用户是什么出错了,应该怎么处理等等。 前台获取客户端数据,少用Int.TryParse等方法屏蔽错误,而是应该把一系列的获取放在一个try里,如果出错要把这个错误包装翻译一下返回客户端,。不应该出现任何莫名其妙无法判断的错误。
硬编码
系统中不应该出现任何的硬编码,有含义的数字,比如表示权限的权限值,都应该用枚举替代。
- SESSION & COOKIE & CACHE & VIEWSTATE
- 配置文件
- 单元测试 & 短函数
- 细节
- 服务器控件
文章来源:http://blog.xujif.com/archives/better-design-less-work/