多人同时开发项目的系统架构
多人同时开发项目的系统架构
平常我们经常会遇到同一个解决方案下面有多个项目,并且每天都有可能多人同时修改同一个项目,更为严重的情况是已经上线的项目可能存在问题需要立即修改,然后立马再上线,这时候还有可能有新的项目正在开发中,这些过程在严重情况的时候,可能会出现一边要急着上线却又夹杂着未测试完成的代码,且平级项目之间又不能相互影响,这些情况给维护带来极大麻烦。
如上图所示,手机充值,水、电、煤交费、游戏点卡项目属于同一个解决方案,且共同使用同一个Web项目,我们希望在各自项目发布的时候对其它项目的影响减少到最小,究竟采用什么样的系统架构可以最大限度的减少麻烦呢?
一提到项目架构,我们就会想到三层架构,表现层、业务逻辑层、数据访问层,实际情况是在我们平常用.NET开发的时候,不可能把你的表现层完全避免逻辑代码,业务逻辑层一点也不夹杂着操作数据的代码,所谓完全独立只是一种理想状态,实际上不存在的。在一个比较复杂,或者在一个不只是三两个人的项目,系统架构上分了层次还是很必要,在这里我不想过多讨论谁优谁劣,只是想减少像这样需要不停发布新版本又在不断增加功能的项目管理的难度,于是我们马上会想到这样来规划基础架构,如下图所示
架构简介
BusinessLogic_Gamecard :游戏点卡项目业务逻辑
BusinessLogic_Topup : 手机充值业务逻辑
BusinessLogic_Pay : 水、电、煤支付
Jquery :共用的Web层
DataAccess : 数据访问层
基本的程序架构是这样的,下面通过例子来一步步介绍如何把维护的难度降到最低
假设有这样一个需求:在水、电、煤支付的时候,当我们确认生成订单准备付款的时候一般是这样的,页面上有个Button控件,在其页面代码写成如下的样子
protected void btn_OK_Click(object sender, EventArgs e)
{
try
{
// 检查打印机是否工作正常
// 获取支付扣率
// 检查后台支付服务接口是否工作正常
// 生成订单流水号
// 生成订单
// 开始支付
}
catch (Exception EX)
{
//错误处理
}
}
一个确认支付按钮的click事件里包含了这么多逻辑,这些逻辑我们可能会写在业务逻辑层,也可能直接写在本页面的代码里,一般来讲我们这样写程序也没什么不对,但是当项目越来越多,逻辑越来越复杂的时候,维护这些代码的程序员肯定非常头疼,如果每个项目还要隔三差五就要发布个新版本,测试人员测试出来的BUG的修改版本都混杂在一起的时候,即便是用再优秀的代码版本管理工具也解决不了问题,那我们究竟该怎么办呢?
在《企业应用架构与设计》书里提到过,在表现层与业务逻辑层之间加一个服务层,该服务层用于解决表现层与业务逻辑层之间的强依赖,让两者松耦合,这也是面像对像程序设计的精髓所在,我们也可以参考该想法来改善我们的程序,不过在用此方法之间,应当把我们的程序先做一点简单优化
像上面的click事件里就包含那么多的逻辑要处理,这样的话click事件就强依懒于这些逻辑,应当把这些逻辑提取出来放到单独的类库里,就命名叫BusinessLogicService吧,在该类库里用专门的类方法来处理逻辑,这个类可能是下面这个样子的
public class Pay
{
public void PayOrder()
{
try
{
// 检查打印机是否工作正常
// 获取支付扣率
// 检查后台支付服务接口是否工作正常
// 生成订单流水号
// 生成订单
// 开始支付
//
}
catch (Exception EX)
{
//错误处理
}
}
}
在PayOrder方法里的这些逻辑还是调用业务逻辑层的,那么再回过头来,刚才的click事件里的代码可能会变成下面这样子
protected void btn_OK_Click(object sender, EventArgs e)
{
Pay pay = new Pay();
pay.PayOrder();
}
怎么样?对比之前的,页面层的代码是不是少了很多?我们知道代码越多,包含的逻辑可能越多,逻辑是经常变化的,那页面的维护就会经常发生,代码少了,页面需要维护的概率就小了,更多的可能就是去维护业务逻辑层的程序了,如果业务逻辑层根据项目来划分,那就可以达到平级项目之间的影响减到最少。
上面提到在业务逻辑层和表现层之间增加服务层的概念,刚刚新增加的BusinessLogicService层其实还是表现层的一部份,因为他只是把表现层的事情提取了出来,要把表现层与逻辑层解藕,就是要把BusinessLogicService层与业务逻辑层之间解藕,如何解呢?
我们可以在增加一个接口层,就把项目命名叫IBusinessLogic吧,这时候click事件里的代码就会变成下面这样子
IPay pay = new Pay();
pay.PayOrder();
而 Pay类就需要实现 IPay接口,以后PayOrder()里的逻辑改了,换一下接口就可以了,不会影响以后的程序。
以上是一点点心得,写出来与大家分享,有不足之处,望与大家探讨。