首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

用“主线+事件”的模式来编写代码

2012-07-04 
用“主线+事件”的方式来编写代码????? 业务是主线和事件组合。????? 主线是什么?主线就是在完成用户的业务目

用“主线+事件”的方式来编写代码

????? 业务是主线和事件组合。

????? 主线是什么?主线就是在完成用户的业务目标时,所涉及到的活动。

????? 事件是什么?在每一个活动中,相关事物的状态变化。

?

????? 回顾以前的编程经验,我们关注活动,忽略事件。

????? 举一个常见的例子来说。小明在购物网站购物,进行支付并成功后,购物网站要做件事: 1 、更新订单状态, 2 、插入支付记录 3 、更新订单日志。 4 、通知支付系统,回调成功。

public class PurchaseOrder { public void notifyOrderPaid(List<OrderListener> listeners){ for(OrderListener listener:listeners){ listener.onOrderSuccessPaid(listener); } }}public interface OrderListener{ public void onOrderSuccessPaid(PurchaseOrder order);}public class LogListener implements OrderListener{ private LogRepository logRepository; public void onOrderSuccessPaid(PurchaseOrder order){ Log log = OrderFactory.getPaidLog(order); logRepository.insert(log); }}public class FinanceListener implements OrderListener{ private FinanceService financeService; public void onOrderSuccessPaid(PurchaseOrder order){ NotifyLog notifylog= NotifyFacotry.getSuccessNotify(order); nofifyService.notify(notifylog); }}public class OrderService{ public void successToPay(PurchaseOrder order,PayResult result){ //主线 order.setPayStatus(PayStatus.SUCCESS); orderRepository.save(order); PayRecord record = RecordFactory.getSuccessPaidRecord(order,result);? payRecordRepository.sae(record); //事件 List<OrderListener> listeners =new ArrayList<OrderListener>(); listeners.add(new FinanceListener()); listeners.add(new LogListener()); order.notifyOrderPaid(listeners); }}

?

?? 一旦有新的业务增加时,应该考虑到它是属于主线,还是属于事件。我们的代码就不容易走向混乱。

?

?

?

1 楼 freish 2011-06-26   如果所谓的“事件”中的异常能影响主线是否回滚的话,该如何清晰的处理?

如果“事件”用异步方式来做,这种情况又该如何处理 2 楼 sing100star 2011-06-27   同步事件:
    现阶段的Web请求都是基于Request/Response的方式,一次响应对应一个线程,利用Spring的OpenSessionInView,可以 保证 一个线程只有一个数据库连接。不管是【主线】还是【事件】都用同样的数据库连接,事务也会得到统一的控制。

异步事件:
    我还没有特别关注,但是曾经看奥金蝶的Apusic OperaMasks中有关异步事件的案例http://infocenter.apusic.com/help/index.jsp?topic=/operamasks-sdk/output/eclipse/message_bus.html。
    你可以查看下:) 3 楼 agapple 2011-06-27   如果 “主线”和“事件”是必然存在的一种业务关系。例如业务上发生主线,必然会触发事件。那你在设计domain的时候就应该将事件的动作封装到对应的save动作上。
这样,对与Action使用来说都只关系你的save动作。事件动作只不过是domain service中的某段业务代码,这时候在service内部你可以随意设计

如果你所谓的“主线”和“事件”不满足必然的关系,你搞这个就是搬起石头砸自己的脚,过度设计的一种 4 楼 水痕2000 2011-06-28   通常的做法如下
所有人都看得懂
一看就知道系统做了啥.
Listener 看不懂.没办法.
Listener 和 通常做法区别在于:
主线和Listener是否是一个人去写;
如果2个人去写,用Listener,业务代码隔离.
一个人去写,还是通常做法,别人读得懂 5 楼 luzhecheng 2011-06-28   处理一般的业务逻辑可能会有先后顺序,你通过add Listener的先后顺序来控制Listener处理事件,我觉得不符合事件驱动模型。 6 楼 bradwoo8621 2011-06-28   observer 7 楼 sing100star 2011-06-28  
1、业务上发生主线,必然会触发事件。但是事件响应方没有必然的联系。比如iphone4上市,有人会抢购,有人无所谓,但这些都不应影响iphone上市这个主线。

2、add Listener(),并不是用来控制循序。而是把【对OrderPaid事件感兴趣的listener】添加PurchaseOrder ,以便于通知



8 楼 yunchow 2011-06-28   也只是玩玩,没什么实际价值,如果所有业务这么来写,那才叫混乱,不说别的,这样会难以理解,也不好调试等等 9 楼 luzhecheng 2011-06-28   sing100star 写道

2、add Listener(),并不是用来控制循序。而是把【对OrderPaid事件感兴趣的listener】添加PurchaseOrder ,以便于通知




既然不控制执行顺序,你能确保你的业务逻辑里没有这样的需求? 10 楼 Saito 2011-06-28   这样的写法是很冗余的,你需要的其实是一个state-machine.

同步事件其实就是反射调用,真正有意义的是异步事件.

可以看一下这个是否满足你的需求.

1> 支持同步异步调用
2> 支持生成流程状态图
3> 有miniDSL支持
4> signal模式的调用.
5> 每种状态的三个signal插入点.
6> Rihno表达式判断
7> 无jar包依赖,适合你连代码一同co过去.放入项目

非Java style且没什么用的Java有限状态机.

里面有一个example,可以clone下来跑一下.(具体源码去github参考最新.

将主逻辑转移到状态机里面,业务代码主要用于启动特定的状态机.

像通知这样的需求,走异步事件模式是很划得来.

串行的逻辑做上下文参数维持用context贯通. 11 楼 raoliv 2011-06-29   这个贴应该发到jdon去。 12 楼 p4nny 2011-06-29   18行代码变44行代码了

热点排行