一起学习
b. 建议的解决方法
解决这个问题的方法是,把客户端和他们使用的EJB分割开。建议适用Session Fa?ade模式。这个模式通过一个Session Bean,为一系列的EJB提供统一的接口来实现流程。事实上,当客户端只是使用这个接口来触发流程。这样,所有关于EJB实现流程所需要的改变,都和客户端无关。
看下面这个例子。这段代码用来控制与客户相关的订单的处理方法。
// All imports required
// Exception handling not shown in the sample code
public class OrderSessionFacade implements SessionBean {
// all EJB specific methods like ejbCreate defined here
// Here is the business method that does the workflow
// required when a customer places a new order
public int placeOrder(String customerId, Details orderDetails)
throws RemoteException {
// Get reference to the required EJBs
InitialContext ctxt = new InitialContext();
Object obj = ctxt.lookup("java:comp/env/ejb/UserAccount");
UserAccountHome acctHome = (UserAccountHome)
PortableRemoteObject.narrow(obj, UserAccountHome.class);
UserAccount acct = acctHome.create();
obj = ctxt.lookup("java:comp/env/ejb/CreditCheck");
CreditCheckHome creditCheckHome = (CreditCheckHome)
PortableRemoteObject.narrow(obj, CreditCheckHome.class);
CreditCheck credit = creditCheckHome.create();
obj = ctxt.lookup("java:comp/env/ejb/Approvals");
ApprovalsHome apprHome = (ApprovalsHome)
PortableRemoteObject.narrow(obj, ApprovalsHome.class);
Approvals appr = apprHome.create();
obj = ctxt.lookup("java:comp/env/ejb/CommitOrder");
CommitOrderHome orderHome = (CommitOrderHome)
PortableRemoteObject.narrow(obj, CommitOrderHome.class);
CommitOrder order = orderHome.create();
// Now do the required workflow to place the order
int result = acct.checkStatus(customerId);
if(result != OK) {
// stop further steps
}
result = credit.checkCreditWorth(customerId, currentOrder);
if(result != OK) {
// stop further steps
}
result = appr.getApprovals(customerId, currentOrder);
if(result != OK) {
// stop further steps
}
// Everything OK; place the order
int orderId = order.placeOrder(customerId, currentOrder);
// Do other processing required
return(orderId);
}
// Implement other workflows for other order related functionalities (like
// updating an existing order, canceling an existing order etc.) in a
// similar way
}
在模式允许的情况下,Servlet代码将很容易实现。
// all required imports
// exceptions to be caught appropriately wherever applicable
public class OrderHandlingServlet extends HttpServlet {
// all required declarations, definitions
public void init() {
// all inits required done here
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
// other logic as required
// Get reference to the session facade
InitialContext ctxt = new InitialContext();
Object obj = ctxt.lookup("java:comp/env/ejb/OrderSessionFacade");
OrderSessionFacadeHome facadeHome = (OrderSessionFacadeHome)
PortableRemoteObject.narrow(obj, OrderSessionFacadeHome.class);
OrderSessionFacade facade = facadeHome.create();
// trigger the order workflow
int orderId = facade.placeOrder(customerId, currentOrder);
// do further processing as required
}
}
就象上面显示的,客户端的逻辑变得非常简单。流程中的任何改变只要修改模式中的一处地方就可以了。客户端可以仍旧使用原来的接口,而不必做任何修改。同样,这个模式可以用来响应其他处理器的流程处理。这让你能用同样的模式来处理不同客户端的不同流程。在这个例子中,模式提供了很好的伸缩性和可维护性。
J2EE中的设计模式之一
J2EE中的设计模式之二
J2EE中的设计模式之三
J2EE中的设计模式之四
J2EE中的设计模式之五
下载本文示例代码
J2EE中的设计模式之四J2EE中的设计模式之四J2EE中的设计模式之四J2EE中的设计模式之四J2EE中的设计模式之四J2EE中的设计模式之四J2EE中的设计模式之四J2EE中的设计模式之四J2EE中的设计模式之四J2EE中的设计模式之四J2EE中的设计模式之四J2EE中的设计模式之四
阅读(126) | 评论(0) | 转发(0) |