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

推荐订阅源

让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Apple Machine Learning Research
Apple Machine Learning Research
月光博客
月光博客
量子位
IT之家
IT之家
Jina AI
Jina AI
Help Net Security
Help Net Security
Cyberwarzone
Cyberwarzone
人人都是产品经理
人人都是产品经理
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
AWS News Blog
AWS News Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
罗磊的独立博客
P
Proofpoint News Feed
S
Schneier on Security
Spread Privacy
Spread Privacy
The Hacker News
The Hacker News
Know Your Adversary
Know Your Adversary
雷峰网
雷峰网
L
LINUX DO - 热门话题
博客园 - 聂微东
C
Cisco Blogs
酷 壳 – CoolShell
酷 壳 – CoolShell
Security Latest
Security Latest
阮一峰的网络日志
阮一峰的网络日志
I
Intezer
K
Kaspersky official blog
C
CXSECURITY Database RSS Feed - CXSecurity.com
T
Threatpost
Last Week in AI
Last Week in AI
博客园 - Franky
G
GRAHAM CLULEY
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
T
Tailwind CSS Blog
L
LINUX DO - 最新话题
T
The Exploit Database - CXSecurity.com
博客园 - 三生石上(FineUI控件)
P
Privacy International News Feed
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
有赞技术团队
有赞技术团队
Schneier on Security
Schneier on Security
V
V2EX
V
Visual Studio Blog
S
Security @ Cisco Blogs
博客园 - 叶小钗
H
Hacker News: Front Page
小众软件
小众软件
WordPress大学
WordPress大学
V2EX - 技术
V2EX - 技术
美团技术团队

博客园 - 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即可。