前一段时间根据用户需求写了一个比较灵活的规则设计模型,与大家分享一下。
业务需求:
1.当数据提交的时候,需要校验注册的规则,根据规则执行情况返回相应结果
2.规则用户可维护,包括用户动态注册规则信息,维护规则提示信息、启用停用规则等
应用的技术:
反射、工厂、面向对象等等
一、数据库设计:
设计原则:
1.该规则动态创建并执行
2.规则分为优先级
1 create table T_BURULE 2 ( 3 ITEMID NUMBER(9) not null, 4 PARENTITEMID NUMBER(9), 5 RULECODE VARCHAR2(20), 6 RULENAME VARCHAR2(100), 7 RULECLASS VARCHAR2(100), 8 RULEDESC VARCHAR2(2000), 9 RULEMESSAGE VARCHAR2(500), 10 P1 VARCHAR2(1000), 11 P2 VARCHAR2(1000), 12 P3 VARCHAR2(1000), 13 P4 VARCHAR2(1000), 14 P5 VARCHAR2(1000), 15 RULETYPE NUMBER(9), 16 RULELEVEL NUMBER(9), 17 ENABLE NUMBER(9) 18 ) 19 tablespace IFIS1300000002013 20 pctfree 10 21 initrans 1 22 maxtrans 255 23 storage 24 ( 25 initial 64K 26 next 1M 27 minextents 1 28 maxextents unlimited 29 ); 30 -- Add comments to the columns 31 comment on column T_BURULE.ITEMID 32 is '流水号'; 33 comment on column T_BURULE.PARENTITEMID 34 is '父级流水号'; 35 comment on column T_BURULE.RULECODE 36 is '规则编码'; 37 comment on column T_BURULE.RULENAME 38 is '规则名称'; 39 comment on column T_BURULE.RULECLASS 40 is '规则所在的类'; 41 comment on column T_BURULE.RULEDESC 42 is '规则描述'; 43 comment on column T_BURULE.RULEMESSAGE 44 is '规则提示信息'; 45 comment on column T_BURULE.P1 46 is '参数1'; 47 comment on column T_BURULE.P2 48 is '参数2'; 49 comment on column T_BURULE.P3 50 is '参数3'; 51 comment on column T_BURULE.P4 52 is '参数4'; 53 comment on column T_BURULE.P5 54 is '参数5'; 55 comment on column T_BURULE.RULETYPE 56 is '规则类别'; 57 comment on column T_BURULE.RULELEVEL 58 is '规则优先级'; 59 comment on column T_BURULE.ENABLE 60 is '是否启用规则1启用 0不启用';
二、框架的设计

1 public class RuleBase 2 { 3 #region 成员变量及其函数 4 5 public IDACProduct Dac { get; set; } 6 7 #endregion 8 9 #region 构造函数 10 public RuleBase(IDACProduct dac) 11 { 12 Dac = dac; 13 } 14 #endregion 15 16 #region 公共函数 17 18 #endregion 19 20 #region 私有函数 21 22 #endregion 23 }
接口的设计:
主要考虑到所有业务的,所有规则都能动态执行,那么设计如下

1 public interface IRule 2 { 3 /// <summary> 4 /// 规则 5 /// </summary> 6 /// <param name="value"></param> 7 /// <returns></returns> 8 RuleDTO Rule(BaseBusinessDTO value1, RuleDTO value2); 9 /// <summary> 10 /// SQL规则 11 /// </summary> 12 /// <param name="value"></param> 13 /// <returns></returns> 14 string SQLRule(object value); 15 }
假定我们有一个规则,我们命名为:RuleA,并将RuleA的完整命名空间存入数据库的RuleClass,以后反射调用

1 public class RuleA : RuleBase, IRule 2 { 3 #region 构造函数 4 5 public RuleA(IDACProduct dac) 6 : base(dac) 7 { 8 9 } 10 11 #endregion 12 13 #region 公共函数 14 15 /// <summary> 16 /// 测试规则 17 /// </summary> 18 /// <param name="value1"></param> 19 /// <param name="value2"></param> 20 /// <returns></returns> 21 public RuleDTO Rule(VoucherDTO value1, RuleDTO value2) 22 { 23 throw new NotImplementedException(); 24 } 25 26 public string SQLRule(object value) 27 { 28 throw new NotImplementedException(); 29 } 30 #endregion 31 }
工厂的设计:我们在工厂里动态创建规则,然后动态执行

1 public class RuleFactory 2 { 3 #region 属性 4 /// <summary> 5 /// 规则 6 /// </summary> 7 private IRule Rule { get; set; } 8 /// <summary> 9 /// DAC 10 /// </summary> 11 private IDACProduct DAC { get; set; } 12 13 #endregion 属性 14 15 #region 构造函数 16 /// <summary> 17 /// 构造函数 18 /// </summary> 19 /// <param name="rule"></param> 20 public RuleFactory(IDACProduct DAC) 21 { 22 this.DAC = DAC; 23 } 24 /// <summary> 25 /// 构造函数 26 /// </summary> 27 /// <param name="rule"></param> 28 public RuleFactory(IRule rule) 29 { 30 this.Rule = rule; 31 } 32 #endregion 构造函数 33 34 #region 设置规则 35 /// <summary> 36 /// 设置规则 37 /// </summary> 38 /// <param name="rule"></param> 39 public void SetRule(IRule rule) 40 { 41 this.Rule = rule; 42 } 43 /// <summary> 44 /// 设置规则 45 /// </summary> 46 /// <param name="ruleClassNameSpace"></param> 47 /// <returns></returns> 48 public void SetRule(string ruleClassNameSpace) 49 { 50 object[] paras = new object[1]; 51 paras[0] = this.DAC; 52 53 Assembly assembly = Assembly.GetExecutingAssembly(); 54 Rule = (IRule)assembly.CreateInstance(ruleClassNameSpace, true, BindingFlags.Default, null, paras, null, null); 55 } 56 #endregion 设置规则 57 58 #region 执行规则 59 60 /// <summary> 61 /// 执行规则 62 /// </summary> 63 /// <param name="value1"></param> 64 /// <param name="value2"></param> 65 /// <returns></returns> 66 public RuleDTO ExeRule(VoucherDTO value1, RuleDTO value2) 67 { 68 return Rule.Rule(value1, value2); 69 } 70 #endregion 执行规则 71 72 }
三、规则执行测试
我们根据规则的优先级读出此业务需要执行的规则,Set规则,然后执行规则。
1 public void TestExe() 2 { 3 //RuleFactory rf = new RuleFactory(); 4 5 //查出所有规则List<Rule> list 6 7 //foreach (Rule r in list) 8 //{ 9 // rf.SetRule("规则多对应的类的命名空间"); 10 // Result rs=rf.ExeRule("业务DTO", "当前条规则数据"); 11 //} 12 13 }
四:用户界面设置
1.用户首先对业务进行划分
2.注册相应的规则:设置好描述信息、规则执行不过的提示信息、优先级等等
3.规则根据业务注册执行
五:总结
1.此设计充分考虑面向对象的设计是程序更加灵活
2.不同业务的规则开发人员只要实现接口,在自己的RuleA,RuleB...RuleX里实现规则
3.规则开发调用人员不必考虑规则的实现,变动,甚至是什么东西;只要读出自己业务的规则然后Set进去执行即可
4.中间传输采用BaseBusinessDTO,所以中间不必考虑多种业务问题,只要继承此基类DTO即可。