事件上报的多种设计思路

业务很简单:一个事件 上报 然后会发短信通知和邮件通知
变化点分析:事件来源可能来自外系统,也可能增加别的通知方式

1 第一种面向对象设计  ssh结构 
public class Event {
 String event_id;
 String event_name;
}
/**
 * 该接口为创建接口
 * 凡是持久化动作需实现此接口 
 * 
 */
public interface ICreater {
	public void creat(  Event fw);
}
/**
 * 此接口为本系统的动作 
 */
public interface IPuter extends ICreater{
	 
}
/**
 * 此接口为外系统的动作
 */
public interface IGeter extends ICreater{
	 
   void conversion( Event obj);
}
/*
 * 上报者对象
 * 被观察者
 * 信息创建者
 */
public class Upsender extends Observable implements IPuter{

	@Override
	public void creat(Event fw) {
		//调用dao持久化
	}
}
/*
 * 发短信对象
 * 观察者
 */
public class TelSender implements Observer{

	@Override
	public void update(Observable o, Object arg) {
		//发短信
	}
}
/*
 * 发邮件对象
 * 观察者
 */
public class EmailSender implements Observer{

	@Override
	public void update(Observable o, Object arg) {
		//发邮件
	}
 }
public class service {
	/*
	 * service层
	 * 在服务提供中进行逻辑组装
	 */
	public void upsend(){
		
		Upsender upsender = new Upsender();
		EmailSender emailSender = new EmailSender();
		TelSender telSender = new TelSender();
		//加入观察者
		upsender.addObserver(emailSender);
		upsender.addObserver(telSender);
		//上报 事件持久化
		upsender.creat(new Event());
		
		//通知
		upsender.notifyObservers();

		 
	}
}

优点 最熟悉的方式  可根据变化点进行抽象封装以扩展
缺点 对象没有生命 需要把隐含对象找出来  或者就按照3层结构写接口和代码 
2 基于事件通知的领域驱动设计的设计
public class EventProcesser {
	public static void processEvent(DomainEvent de){
		//可以通过传入领域事件对象 直接调用到对应对象的方法 可用开源框架
	}
}
public class Event {
 String event_id;
 String event_name;
 public void handle(UpsendEvent usevent){
	 //进行持久化(省略)
	  
	 //发邮件通知
	 EventProcesser.processEvent(new EmailSendEvent("地址","内容")); 
	 //发短信通知
	 EventProcesser.processEvent(new TelSendEvent("电话","内容")); 
 }
}
/*
 * 发短信对象
 */
public class TelSender {
	 
	private void send(TelSendEvent esevent){
		//此处发短信
	}
}
public class TelSendEvent  extends  DomainEvent{
	String tel_number;
	String tel_conten;
	TelSendEvent(String tel_number,String tel_conten){}
}
/*
 * 发邮件对象
 */
public class EmailSender extends  DomainEvent{
	
	private void send(EmailSendEvent esevent){
		//此处发邮件
	}
 }
public class EmailSendEvent  extends  DomainEvent{
	String email_address;
	String email_conten;
	EmailSendEvent(String email_address,String email_conten){}
}
/*
 * 上报事件
 */
public class UpsendEvent  extends  DomainEvent{
   public String eventid;
   public Date upsenddate;
   public String userid;
}
public class service {
	/*
	 * service层
	 * 在服务提供中进行逻辑组装
	 */
	public void upsend(){
		//UpsendEvent中参数省略
		EventProcesser.processEvent(new UpsendEvent()); 
	}
}

从上面的例子,我们可以清楚的看到领域对象之间没有相互引用,完全通过事件来实现相互协作。比如父对象通知子对象,子对象通知父对象,一个事件通知一个或多个同类型或不同类型的对象,等等。要实现任何一个业务场景,我们需要做的事情一般是:

1)通知中央事件处理器处理某个事件(如果该事件是框架没有提供特定的业务事件,则需要自己定义);

2)领域对象响应该事件,通过定义私有的响应函数来实现响应;

3)在领域模型内部,告诉框架事件及响应者之间的映射关系,并告诉框架有哪个或哪些对象会去响应,它们的唯一标识是如何从事件中获取的;



通过这三个步骤,我们就可以轻松简单的实现各种领域对象之间的协作了。而且需要强调的是,通过这样的方式,可以充分体现出领域对象是“活”的这个概念。因为所有的领域对象的事件响应函数都是私有的,也就是领域对象自己的行为别的领域对象无法去调用,而都是由一个“中央事件处理器”去统一调用。这样的效果就是,任何一个领域对象都会“主动”去响应某个事件,这样就从分体现出了“活”对象的概念了。在我看来,这才是真正的面向对象编程,因为所有的对象都是主动参与到某个业务场景中去的。

优点:高度可扩展性,因为是基于事件消息机制的,把领域对象之间的耦合度降到了最低
缺点:可维护性方面可能有问题,会出现超大类 还有习惯问题

猜你喜欢

转载自gulufather.iteye.com/blog/1140195