惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

阮一峰的网络日志
阮一峰的网络日志
Apple Machine Learning Research
Apple Machine Learning Research
量子位
D
DataBreaches.Net
云风的 BLOG
云风的 BLOG
博客园 - 聂微东
博客园_首页
D
Docker
博客园 - 叶小钗
S
SegmentFault 最新的问题
大猫的无限游戏
大猫的无限游戏
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
J
Java Code Geeks
H
Hackread – Cybersecurity News, Data Breaches, AI and More
A
About on SuperTechFans
博客园 - 三生石上(FineUI控件)
F
Fortinet All Blogs
小众软件
小众软件
aimingoo的专栏
aimingoo的专栏
爱范儿
爱范儿
腾讯CDC
罗磊的独立博客
雷峰网
雷峰网
博客园 - Franky

博客园 - ronphy

DTO的深度克隆实现 UltraNumTextBox【实现所有数字输入的同时,可以控制当控件禁用时ForeColor】 关于 double类型乘以100精度丢失的奇怪问题? 安装中文VS2008 SP1 后智能提示是英文的解决办法(官方解决办法) NET牛人应该知道些什么 软件: Netscape正式死亡 软件: WorldWide Telescope即将发布 编程艺术——13个惊人的Code Demo 互联网: 谷歌连续第二年成为最适合工作的公司 微软将在2月12日把浏览器强制升级到IE7 微软公开.NET Base Classes源代码 IT: 蓝牙十岁了 IT2008预言:哪些可能发生,哪些不会 2008年十大个人技术趋势 联想IdeaPad品牌出炉 三款笔记本亮相 [今日推荐]昨天看到的有趣的消息. [共享一下]Head.First.设计模式.中文版 [推荐]2008年必不可少的20个网络产品 最好的免费web游戏
复杂型数据“动态规则”校验的设计与实现
ronphy · 2013-08-08 · via 博客园 - ronphy

前一段时间根据用户需求写了一个比较灵活的规则设计模型,与大家分享一下。

业务需求:

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     }

RuleA

工厂的设计:我们在工厂里动态创建规则,然后动态执行

 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     }

RuleFactory

三、规则执行测试

我们根据规则的优先级读出此业务需要执行的规则,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即可。