有了上面的基础,我们很容易将这些类进行组合,构建我们的业务处理功能。在这个系统中,涉及到复杂业务处理的部分只有入库单入库这个功能,这个功能我们封装在Wharehouse类中,其过程可以用序列图表示如下:
相应的程序代码和注解如下,在这里,我们使用了事务处理,因此,Wharehouse类继承了System.EnterpriseServices.ServicedComponent:
//设置事务处理类型 [Transaction(TransactionOption.Required)] //继承ServicedComponent,以支持使用Windows的Transaction Service public class Wharehouse : System.EnterpriseServices.ServicedComponent { public Wharehouse(){} //入库的业务逻辑代码 public void StoreIntoWarehouse(EntityData IndepotForm) { //得到入库单明细 DataTable tbl=IndepotForm.Tables["InDepotFormDetail"]; try { //对于入库单明细中的每个产品,都要修改原有产品的库存数量 ProductEntityDAO ped=new ProductEntityDAO(); for(int i=0;i<tbl.Rows.Count;i++) { //得到入库单明细的一个产品信息 DataRow formdetail=tbl.Rows[i]; string productID=formdetail["ProductID"].ToString(); decimal inCount=(decimal)formdetail["InCount"]; //找到需要修改库存数量的产品 EntityData product=ped.FindByPrimaryKey(productID); DataRow productRow=product.GetRecord("Product"); //修改产品库存数量 productRow["CurrentCount"]=(decimal)productRow["CurrentCount"]+inCount; ped.UpdateEntity(product); } ped.Dispose(); //保存入库单 InDepotFormEntityDAO inDepotForm=new InDepotFormEntityDAO(); inDepotForm.InsertEntity(IndepotForm); IndepotForm.Dispose(); //如果成功,结束事务 ContextUtil.SetComplete(); } catch(Exception ee) { //否则,回滚事务 ContextUtil.SetAbort(); throw ee; } } } |
现在,整个系统的功能部分已经完成了,我们需要将这些功能组装成系统的各个模块,以便客户端的调用。
在前面的开发过程中,我们实际上还没有对系统进行明确的功能模块划分,在这里,我们才开始所谓的模块划分。在所有客户端对系统的调用中,基本上都是调用这个部分的功能,而不会直接调用前面几个部分的内容,这样使系统达到良好的封装性。
这是一个很好的软件开发的方式。采用这种做法,我们可以将前面的内容封装成一个个的组件,在这里,可以根据需要很方便的利用前面的组件进行功能的重新组合,也方便系统的修改和升级,为软件开发的组件化奠定基础。
在本系统中,业务服务位于BusinessFacade目录,在这里,我们将系统分成两个模块:产品资料的维护和仓库事务管理,模块功能调用接口分别封装在ProductManagement和WharehouseManagement类中。这两个类的代码很简单,主要是封装前面几层内容的功能。例如,WharehouseManagement类封装了入库的操作供客户端掉用,他的代码一目了然,如下:
//类设计成sealed,不能被继承 public sealed class WharehouseManagement { //采用Singleton设计模式,私有的构造函数,使得类不能直接实例化, //只能调用静态的StoreProductIntoWharehouse方法。 private WharehouseManagement() { } public static void StoreProductIntoWharehouse(EntityData entity) { Wharehouse house=new Wharehouse(); house.StoreIntoWarehouse(entity); } } |
1、 WEB层的主要功能是同客户交户,这一层向用户提供服务,主要功能是提供HTML界面,接受用户的输入,调用业务功能等,完成用户的需求。在这个层次里面没有业务逻辑的处理,而只是调用业务层面提供的服务。下面看看一个入库操作的例子。
private void btnAdd_Click(object sender, System.EventArgs e) { //得到一个InDepotForm实例 EntityData entity=EntityDataManager.GetEmptyEntity("InDepotForm"); DataRow row=entity.GetNewRecord("InDepotForm"); //设置入库单主信息 row["InDepotID"]=valInDepotID.Text; row["InDepotTime"]=System.DateTime.Parse(valInDepotTime.Text); entity.AddNewRecord(row,"InDepotForm"); //设置入库单明细信息,这是从DataGrid中读取得 DataTable detail=entity.Tables["InDepotFormDetail"]; for(int i=0;i<gridDetail.Items.Count;i++) { DataRow rowdetail=detail.NewRow(); rowdetail["InDepotID"]=valInDepotID.Text; rowdetail["InDepotDetailID"]=gridDetail.Items[i].Cells[0].Text; rowdetail["ProductID"]=gridDetail.Items[i].Cells[1].Text; rowdetail["InCount"]=decimal.Parse(gridDetail.Items[i].Cells[2].Text.Trim()); detail.Rows.Add(rowdetail); } //执行入库操作 WharehouseManagement.StoreProductIntoWharehouse(entity); } |
在这个层次中,我们没有将表单直接写在ASP.Net页面中,而是先把功能写成Web控件,然后再在ASP.Net页面中引用这些控件。这样做的目的,主要是为了将来的重用性考虑。