这次讲的是tran类,也是业务类.由于业务的逻辑都在builder类中完成了,所以在tran中只是提供了具体功能的实现.
1
public override bool ValidTable(out string ErrMessage)
2 {
3 ErrMessage=string.Empty ;
4 string ErrMessage2=string.Empty ;
5 if (null==TranTable )
6 return false;
7 myEntity.SetDialectZH();
8 try
9 {
10 bool valid=true;
11 if(!check.ValidColumnContains(TranTable,myEntity.OriSourcePartNo,out ErrMessage2))
12 {
13 ErrMessage+=ErrMessage2;
14 valid=false;
15 }
16 if(!check.ValidColumnContains(TranTable,myEntity.HsCode,out ErrMessage2))
17 {
18 ErrMessage+=ErrMessage2;
19 valid=false;
20 }
21 if(!check.ValidColumnContains(TranTable,myEntity.ChineseName,out ErrMessage2))
22 {
23 ErrMessage+=ErrMessage2;
24 valid=false;
25 }
26 if(!check.ValidColumnContains(TranTable,myEntity.Spec,out ErrMessage2))
27 {
28 ErrMessage+=ErrMessage2;
29 valid=false;
30 }
31 if(!check.ValidColumnContains(TranTable,myEntity.Type,out ErrMessage2))
32 {
33 ErrMessage+=ErrMessage2;
34 valid=false;
35 }
36 if(!check.ValidColumnContains(TranTable,myEntity.Currency,out ErrMessage2))
37 {
38 ErrMessage+=ErrMessage2;
39 valid=false;
40 }
41 if(!check.ValidColumnContains(TranTable,myEntity.Net,out ErrMessage2))
42 {
43 ErrMessage+=ErrMessage2;
44 valid=false;
45 }
46 if(!check.ValidColumnContains(TranTable,myEntity.Gross,out ErrMessage2))
47 {
48 ErrMessage+=ErrMessage2;
49 valid=false;
50 }
51 if(!check.ValidColumnContains(TranTable,myEntity.Bond,out ErrMessage2))
52 {
53 ErrMessage+=ErrMessage2;
54 valid=false;
55 }
56 if(!check.ValidColumnContains(TranTable,myEntity.PRICE,out ErrMessage2))
57 {
58 ErrMessage+=ErrMessage2;
59 valid=false;
60 }
61 if(!check.ValidColumnContains(TranTable,myEntity.Unit,out ErrMessage2))
62 {
63 ErrMessage+=ErrMessage2;
64 valid=false;
65 }
66 myEntity.SetDialectEN();
67 return valid;
68 }
69 catch
70 {
71 return false;
72 }
73 finally
74 {
75 myEntity.SetDialectEN();
76 }
77 }
这个接口函数在builder类的beforExecute()中被调用.
1
//校验文件格式
2 if (null!=excelDataTable)
3 {
4 detail.TranDataTable =excelDataTable;
5 if (tran.ValidTable(out ErrMessage))//验证导入的表列的正确
6 {
7 tran.ColumnNameToEn();//把中文的列名转成英文
8 tempTable=excelDataTable.Clone();
9 }
10 else
11 {
12 result.AddErrorResult (ErrMessage);
13 }
14 }
以及函数bool ValidAskFileName(out string ErrMessage)
1
public override bool ValidAskFileName(out string ErrMessage)
2 {
3 string Regular="REQ-BEIAN-OS-";
4 ErrMessage=string.Empty;
5 if (!check.ValidFileName(detail.AskFileName,Regular))
6 {
7 ErrMessage=SRTran.ErrorAskFileNameNotValid(detail.AskFileName);
8 return false;
9 }
10 return true;
11 }
在函数bool ValidAskFileName(out string ErrMessage)
1
protected bool ValidAskFileName(out string ErrMessage)
2 {
3 if (null==tran)
4 tran=CreateTran();
5 return tran.ValidAskFileName (out ErrMessage);
6 }
中被使用.
我在开发过程,始终有个指导思想,就是对某一个业务上的功能,把它的逻辑和具体实现分开来,具体的说,就是在一个类中用调用接口的方式实现逻辑的一个逻辑类,在本项目中,我就是使用的builder类来充当这个角色的.而具体的实现则有业务类来实现.也就是提供了接口的实现.在这个项目中,我使用tran类来充当这个角色.
希望众位看家可以说说你们的看法.
因为在开发和修改过程中,往往会面临功能上的改动,而我认为把功能的逻辑和实现分开来,可能是一个比较好的方法.一个优点是可以把改动只局限在某个具体的类中.还有一个优点是便于重复利用.
在开发过程,我还遇到过一个问题.请看下面这个函数.
1
public override TranResult CheckValid()
2 {
3 TranResult result=new TranResult();
4 if (null==TranTable )
5 {
6 //return false;
7 result.AddFailResult(SRTran.ErrorVerify);
8 }
9 else
10 {
11 BOSEntity myEntity_Zh=(BOSEntity)myEntity.Clone ();
12 myEntity_Zh.SetDialectZH();
13 string msg;
14 string message;
15 int rows=TranTable.Rows.Count ;
16 int i=0;
17 string[] Arraymsg=new string [rows];
18 bool valid1=true;
19 try
20 {
21 foreach(System.Data.DataRow row in TranTable.Rows )
22 {
23 bool valid=true;
24 msg=string.Empty;
25 message=string.Empty ;
26
27 if (!check.ValidFiledBasic(row[myEntity.OriSourcePartNo],out msg))
28 {
29 message+=myEntity_Zh.OriSourcePartNo+msg+";";
30 valid=false;
31 }
32
33 if (!check.ValideHscode (row[myEntity.HsCode],out msg))
34 {
35 message+=myEntity_Zh.HsCode+msg+";";
36 valid=false;
37 }
38
39 if (!check.ValidFiledBasic(row[myEntity.ChineseName],out msg))
40 {
41 message+=myEntity_Zh.ChineseName+msg+";";
42 valid=false;
43 }
44
45 if (!check.ValidFiledBasic(row[myEntity.Spec],out msg))
46 {
47 message+=myEntity_Zh.Spec+msg+";";
48 valid=false;
49 }
50
51 if (!check.ValidFiledBasic(row[myEntity.Type],out msg))
52 {
53 message+=myEntity_Zh.Type+msg+";";
54 valid=false;
55 }
56
57 if (!check.ValidFiledBasic10(row[myEntity.Currency],out msg))
58 {
59 message+=myEntity_Zh.Currency+msg+";";
60 valid=false;
61 }
62
63 if (!check.ValidFiledBasic10(row[myEntity.Unit],out msg))
64 {
65 message+=myEntity_Zh.Unit+msg+";";
66 valid=false;
67 }
68
69 if (!check.ValidFiledDecimal (row[myEntity.Net],out msg))
70 {
71 message+=myEntity_Zh.Net+msg+";";
72 valid=false;
73 }
74
75 if (!check.ValidFiledDecimal (row[myEntity.PRICE],out msg))
76 {
77 message+=myEntity_Zh.PRICE+msg+";";
78 valid=false;
79 }
80
81 if (!check.ValidFiledDecimal (row[myEntity.Gross],out msg))
82 {
83 message+=myEntity_Zh.Gross+msg+";";
84 valid=false;
85 }
86
87 if (!check.ValidFiledBond(row[myEntity.Bond],out msg))
88 {
89 message+=myEntity_Zh.Bond+msg+";";
90 valid=false;
91 }
92 Arraymsg[i]=message;
93 i++;
94 if (!valid)
95 {
96 valid1=false;
97 }
98 }
99 if (!valid1)
100 {
101 // log.addErrMessage (TranTable,Arraymsg);
102 result.AddErrorResult (Arraymsg);
103 }
104 // return valid1;
105 }
106 catch
107 {
108 // log.addErrMessage (TranTable,SRTran.ErrorVerify);
109 // return false;
110 result.AddFailResult(SRTran.ErrorVerify);
111 }
112 }
113 return result;
114 }
原来我的做法是这个函数返回一个布尔值,并且在这个函数中把出错信息放到log中,可以看被注释掉的部分.但是当项目要求更改写入日志的方法之后,我发现原先的做法会牵涉到大量的更改.所以后来我修改了原先的处理方式,不在tran里面处理日志功能,而是改成返回一个TranResult变量.定义如下:
1 public class TranResult
2 {
3 private TranState state;
4 private string message=string.Empty;
5 private string[] arrayMessage=null;
6 public TranResult()
7 {
8 //
9 // TODO: 在此处添加构造函数逻辑
10 //
11 state=TranState.Success;
12 }
13 #region Function
14 public void AddSuccessResult(string sucMessage)
15 {
16 state=TranState.Success;
17 if (null!=sucMessage)
18 {
19 message=sucMessage;
20 }
21 }
22 public void AddFailResult(string errMessage)
23 {
24 state=TranState.Failure;
25 if (null!=errMessage)
26 {
27 message=errMessage;
28 }
29 }
30 public void AddErrorResult(string[] errMessage)
31 {
32 state=TranState.Error;
33 if (null!=errMessage)
34 {
35 arrayMessage=errMessage;
36 }
37 }
38 public void WriteLog(System.Data.DataTable db,LogTable log)
39 {
40 switch(state)
41 {
42 case TranState.Success :
43 log.addSucessMessage (db);
44 break;
45 case TranState.Error:
46 log.addErrMessage (db,arrayMessage);
47 break;
48 case TranState.Failure:
49 log.addErrMessage (db,message);
50 break;
51 }
52 }
53 #endregion
54 #region Property
55 public TranState ResultState
56 {
57 get{return state;}
58 }
59 public string Message
60 {
61 get{return message;}
62 }
63 public string[] ArrayMessage
64 {
65 get{return arrayMessage;}
66 }
67 #endregion
68 }
具体写入日志改成在builder类中完成:
1
private TranResult ExecuteTran()
2 {
3 TranResult result=null;
4 try
5 {
6 detail.TranDataTable =tempTable;
7
8 result=tran.CheckValid();
9 if (TranState.Success ==result.ResultState)
10 {
11 result =tran.ImportData();
12 }
13 }
14 // catch(Exception ex)
15 // {
16 // throw new TranException (ex.Message,ex);
17 // }
18 finally
19 {
20 //报告消息,完成一笔数据
21 //OnRateReport (new RateReportEventArgs(Convert.ToInt32 (SR.ReportOfDataExcute)));
22 result.WriteLog (tempTable,log);
23 tempTable.Clear ();
24 }
25 return result;
26 }
我觉得这样的好处在于降低了模块之间的关系,原来的方案中log类在builder和tran中都存在,而且都发生了操作的行为.现在,我把log类从tran中去除,使得log类只与builder发生关系,且只有builder类能够操作log类.这样虽然会造成性能上的损失,但是是模块与模块之间的隅合度降低了.
下一篇,我会谈到本项目的数据库操作.