这样的引擎,还是很空的,试着对某些具体方面提出解决方案看看,如权限,如业务,这些将如何实现呢?以OO思维来思考:假设这样你引擎已经设计好(接口可以调用),你如何表述到一个真实的系统上呢?若果只是单纯解关系的话,将会失去意义了。简单来,拿登录和转账来说说?
那我就拿转帐来说说吧:
先描述一下转帐的业务需求:
1)源账户扣除转账金额,当然首先需要先判断源账户余额是否足够,如果不够,则无法转账;
2)目标账户增加转账金额;
3)为源账户生成一笔转账记录;
4)为目标账户生成一笔转账记录;
好了,如果从“对象+关系引擎+消息机制”的角度来设计这个需求的话,我觉得可以这样:
1)用BankAccount表示银行帐号类,用EventProcesser表示关系引擎,用transferEvent表示转帐的消息;
2)创建并发送一个转账消息给关系引擎,该消息包括源帐号,目标帐号,转帐金额,转账日期。示例代码如下:
EventProcesser.ProcessEvent(new TransferEvent(bankAccount1.Id, bankAccount2.Id, 1000, DateTime.Now));
3)关系引擎智能的解析该消息,然后自动获取源帐号对象和目标帐号对象,然后通知它们分别响应该消息;对于源帐号对象来说,它会响应该消息并做“转出钱”的操作,并且给自己创建一笔转帐记录;对于目标帐号来说,它会响应该消息并做“转入钱”的操作,并且给自己创建一笔转帐记录;
理想情况下,只要做这三步就可以实现转帐需求了。但实际上我们的关系引擎没有足够智能,它无法智能地分析这个转帐的消息。所以,我现在的做法是需要预先在程序启动时告诉关系引擎:转帐消息和该消息的响应者之间的关系,比如如何从该消息中提取源帐号对象和目标帐号对象,以及需要调用源帐号对象与目标帐号对象的哪个响应方法。
以下是我实现的具体代码(C#),奇怪,为什么jdon网站只支持插入java代码呢?难道是对C或.NET有歧视,呵呵:
|
如果你要看我具体的代码,可以具体参考我在博客园的一篇文章,那里讲的比较具体。http://www.cnblogs.com/netfocus/archive/2011/04/17/2019152.html
[该贴被tangxuehua于2011-04-26 13:08修改过]
[该贴被tangxuehua于2011-04-26 13:14修改过]
从DCI的角度看角色和权限会更加灵活。权限是有业务决定的,不可改变,但是角色是可变的,因为不同的管理环境下,角色场景及其划分不同,这些角色拥有的权限也不同。这也就是说场景决定角色,决定权限的不同组合。
这个感觉就是消息总线,你所提到的关系引擎,就是对象对消息的关注注册。其实总体来说就是消息总线的架构,可以说就是EDA。
我的架构是面向关系编程,不是对象对消息进行注册,而是类对消息进行注册,这和普通的EDA有本质区别。我注册的是事件的类型和对象的类型之间的关系映射。
另外一点是,我的对象都是独立的,不会对其他任何对象有任何引用或唯一标识的关联。这点和一般的对象设计方式也完全不同。
类对消息进行注册?可以理解为一类对象对某(类)消息进行注册么?若果是那样的话,那也是对关系声明而已,无论是谁关注事件,你只要用Event或者Message来关联,我认为都是EDA了。
独立的话,是与聚合相对。独立的话,DCI和NoSQL都有体现。我个人认为,对象过分独立,会带来事件复杂性,但独立又正好解耦,所以我还是觉得一个可控的度是关键。
确实也属于EDA的范畴。关于你提到的可能会导致事件的复杂的问题。我觉得如果所有对象都是独立的,不会导致事件的复杂,而是会让关系引擎要做的事情会更多。
比如,如果有A和B两个对象,他们之间有关系,A可能会通知B做什么事情,以前我们可能会用两种方式来让A知道B:1)A持有B的引用;2)A持有B的唯一标识;如果按照这两种方式来关联,则A让B做事情会很简单,因为A拥有B的信息或者拥有能找到B的信息。但是如果A和B是相互独立的,它们之间的关系是由关系引擎管理的。那此时如果A要让B做事情的话,对于A来说其实也很简单,不需要创建一个很复杂的消息。而只要创建一个简单的消息,这个消息只要包含A的唯一标识即可以及消息本身的意思。比如
class ChangeBStatus : Message
{
public Guid AId;
}
关键是关系引擎知道A和B的关系,所以它有能力根据A的唯一标识获取B,然后让B响应。
总结:
1)如果A和B之间本身保留了关系,那么关系引擎,或者你说的消息总线只需要做一个“转手”的动作即可,即将消息传递给B进行响应;
2)如果A和B之间没有任何关系,关系是由关系引擎维护,那么消息总系要多做一件事情。那就是首先要根据A所传递过来的消息获取一个关系列表,然后循环处理关系列表中的每个响应者类型,然后再根据A的唯一标识,就可以获取每个响应者的实例,从而让每个响应者去响应。
不知道你是否理解我的意思。
[该贴被tangxuehua于2011-04-29 16:35修改过]
相关主题:
DCI Javascript案例
该模型具有如下三个特点:
1)模型中的各个对象之间没有任何关系(无对象引用,无唯一键关联),并且对象的所有行为不需要暴露出来,全部私有(private)即可。因为对象的所有的行为都 ...
建设你看看SmallTalk的相关内容,估计对你有启发。
"的内容
我也想过类似的问题,
比如,我是一个人,在家里我是一个父亲角色,在公司我是一个职员角色,
问题来了,如果按照DCI的的思路,难道我在家里就没有作为一个职员的行为了?我就不能工作?这显然不符合逻辑