DRPを通してMVCアーキテクチャをさらに認識する(二)


ビジネスロジック層は永続化ロジック層に依存し,この依存関係をさらに弱めるために抽象ファクトリ+反射モードを採用し,Dao層に関するクラスをxmlファイルに配置し,ファクトリを介してオブジェクトを作成し,後期に修正が必要な場合はxmlファイルを修正するだけで,コードを修正する必要はない.まずクラス名を保存するxmlファイルbeans-configを作成する.xml.コードは次のとおりです.
<?xml version="1.0" encoding="UTF-8"?>
<beans>
	<service-class>
		<service id="com.snail.drp.basedata.manager.ItemManager" class="com.snail.drp.basedata.manager.ItemManagerImpl"></service>
		<service id="com.snail.drp.flowcard.manager.FlowCardManager" class="com.snail.drp.flowcard.manager.impl.FlowCardManagerImpl"></service>
		<service id="com.snail.drp.statreport.manager.StatReportManager" class="com.snail.drp.statreport.manager.impl.StatReportManagerImpl"/>	
	</service-class>
	<dao-class>
		<dao id="com.snail.drp.basedata.dao.ItemDao" class="com.snail.drp.basedata.dao.ItemDao4OracleImpl"></dao>
		<dao id="com.snail.drp.flowcard.dao.FlowCardDao" class="com.snail.drp.flowcard.dao.impl.FlowCardDaoImpl"></dao>
	</dao-class>
</beans>

Daoレイヤのオブジェクトを作成する抽象ファクトリを作成します.コードは次のとおりです.
package com.snail.drp.util;

import java.util.HashMap;
import java.util.Map;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import com.snail.drp.basedata.dao.ItemDao;

/**
 *     
 * @author yuanfubiao
 *
 */
public class BeanFactory {

	private static BeanFactory instance = new BeanFactory();
	
	private final String beansConfigFile = "beans-config.xml";
	
	//  Service    
	private Map serviceMap = new HashMap();
	
	//  dao    
	private Map daoMap = new HashMap();
	
	private Document doc;
	
	private BeanFactory(){
		try {
			doc = new SAXReader().read(Thread.currentThread().getContextClassLoader().getResourceAsStream(beansConfigFile));
		} catch (DocumentException e) {
			e.printStackTrace();
			throw new RuntimeException();
		}		
	}
	
	public static BeanFactory getInstance(){
		return instance;
	}
	
	/**
	 *         Service    
	 * @param c
	 * @return
	 */
	public synchronized Object getServiceObject(Class c){
		//          ,  
		if(serviceMap.containsKey(c.getName())){
			return serviceMap.get(c.getName());
		}
		
		Element beanElt = (Element)doc.selectSingleNode("//service[@id=\"" + c.getName() + "\"]");
		String className = beanElt.attributeValue("class");
		Object service = null;

		try {
			service = Class.forName(className).newInstance();
			
			//        Service
			TransactionHandler transactionHandler = new TransactionHandler();
			service = transactionHandler.newProxyInstance(service);
			
			//         Map 
			serviceMap.put(c.getName(), service);
		} catch (Exception e) {
			throw new RuntimeException();
		}
		
		return service;			
	}
	
	/**
	 *         Dao    
	 * @param c
	 * @return
	 */
	public synchronized Object getDaoObject(Class c){
		//          ,  
		if(daoMap.containsKey(c.getName())){
			return daoMap.get(c.getName());
		}
		
		Element beanElt = (Element)doc.selectSingleNode("//dao[@id=\"" + c.getName() + "\"]");
		String className = beanElt.attributeValue("class");
		Object dao = null;
		System.out.print(className);
		try {
			dao = Class.forName(className).newInstance();
			
			//         Map 
			daoMap.put(c.getName(), dao);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return dao;		
	}
}

共通性を維持するために、ビジネスロジックは依然としてインタフェース向けのプログラミングを採用しています.
package com.snail.drp.flowcard.manager;

import java.util.Date;

import com.snail.drp.flowcard.domain.FlowCard;
import com.snail.drp.util.ApplicationException;
import com.snail.drp.util.PageModel;

/**
 *           
 * @author yuanfubiao
 *
 */
public interface FlowCardManager {

	/**
	 *      
	 * @param flowCard
	 * @throws ApplicationException
	 */
	public void addFlowCard(FlowCard flowCard) throws ApplicationException;
}

実装クラスコード:
package com.snail.drp.flowcard.manager.impl;

import java.sql.Connection;
import java.util.Date;
import java.util.List;

import com.snail.drp.flowcard.dao.FlowCardDao;
import com.snail.drp.flowcard.domain.FlowCard;
import com.snail.drp.flowcard.manager.FlowCardManager;
import com.snail.drp.util.ApplicationException;
import com.snail.drp.util.BeanFactory;
import com.snail.drp.util.ConnectionManager;
import com.snail.drp.util.DaoException;
import com.snail.drp.util.PageModel;

/**
 *           
 * @author yuanfubiao
 *
 */
public class FlowCardManagerImpl implements FlowCardManager {

	private FlowCardDao flowCardDao;
	
	public FlowCardManagerImpl(){
		this.flowCardDao = (FlowCardDao)BeanFactory.getInstance().getDaoObject(FlowCardDao.class);
	}
	
	@Override
	public void addFlowCard(FlowCard flowCard) throws ApplicationException {
		
		try{			
			//       
			String flowCardVouNo = flowCardDao.generateVouNo();
			//        
			flowCardDao.addFlowCardMaster(flowCardVouNo, flowCard);
		}catch(DaoException e){
			throw new ApplicationException("       ");
		}
	}
}

Controllerレイヤでは、多くのサーブレットでBeanFactoryファクトリクラスが使用されるため、特定のデータを初期化するサーブレットを作成し、サーバの起動時にBeanFactoryと一般的な定数を作成します.
package com.snail.drp.util.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;

import com.snail.drp.util.BeanFactory;
import com.snail.drp.util.Constants;

/**
 *      Server      
 * @author yuanfubiao
 *
 */
public class InitServlet extends HttpServlet {

	@Override
	public void init() throws ServletException {
		//      
		//BeanFactory beanFactory = new DefaultBeanFactory();
		
		//      ServletContext 
		//this.getServletContext().setAttribute("beanFactory", beanFactory);
		
		//       ServletContext 
		BeanFactory beanFactory = BeanFactory.getInstance();
		this.getServletContext().setAttribute("beanFactory", beanFactory);
		//    
		getServletContext().setAttribute("add", Constants.ADD);
		getServletContext().setAttribute("showAdd", Constants.SHOW_ADD);
	}
}

多くのサーブレットは共通の方法を持っているため、サーブレットは抽象的なプログラミングを採用し、サーブレットの中のいくつかの共通の方法を抽出し、コードは以下の通りである.
package com.snail.drp.util.servlet;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.snail.drp.sysmgr.domain.User;
import com.snail.drp.util.BeanFactory;

public class BaseServlet extends HttpServlet {

	private String command;
	
	private User user;
	
	private BeanFactory beanFactory;
	
	protected String getCommand(){
		return command;
	}
	
	protected User getCurrentUser(){
		return user;
	}
	
	protected BeanFactory getBeanFactory(){
		// servletContext   BeanFactory
		beanFactory = (BeanFactory)this.getServletContext().getAttribute("beanFactory");
		return beanFactory;
	}
	
	@Override
	protected void service(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		command = request.getParameter("command");
		user = (User)request.getSession().getAttribute("user_info");
		super.service(request,response);
	}
}

サーブレットは、柔軟性を維持するためにビジネスロジックレイヤを呼び出し、抽象ファクトリ+反射モードを採用します.抽象ファクトリは異なるシリーズの製品を作成することができます.そのため、このプロジェクトではBeanFactoryがDaoレイヤオブジェクトとビジネスロジックレイヤオブジェクトの生産を担当します.単一サーブレットに流れる実装コードを追加し、
package com.snail.drp.flowcard.web;

import java.io.IOException;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.snail.drp.basedata.domain.AimClient;
import com.snail.drp.basedata.domain.Client;
import com.snail.drp.basedata.domain.FiscalYearPeriod;
import com.snail.drp.basedata.domain.Item;
import com.snail.drp.flowcard.domain.FlowCard;
import com.snail.drp.flowcard.domain.FlowCardDetail;
import com.snail.drp.flowcard.manager.FlowCardManager;
import com.snail.drp.util.ApplicationException;
import com.snail.drp.util.Constants;
import com.snail.drp.util.PageModel;
import com.snail.drp.util.servlet.BaseServlet;

/**
 *      Servlet
 * @author yuanfubiao
 *
 */
public class FlowCardServlet extends BaseServlet {

	private FlowCardManager flowCardManager;
	
	@Override
	public void init() throws ServletException {
		flowCardManager = (FlowCardManager)getBeanFactory().getServiceObject(FlowCardManager.class);
	}

	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doPost(request,response);
	}

	@Override
	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		if(Constants.SHOW_ADD.equals(getCommand())){
			showAdd(request,response);
		}else if(Constants.ADD.equals(getCommand())){
			add(request,response);
		}else{
			//    
			search(request,response);
		}
	}

	/**
	 *       
	 * @param request
	 * @param response
	 * @throws ServletException
	 * @throws IOException
	 */
	private void showAdd(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException{
		request.getRequestDispatcher("/flowcard/flow_card_add.jsp").forward(request, response);
	}
	
	/**
	 *   
	 * @param request
	 * @param response
	 * @throws ServletException
	 * @throws IOException
	 */
	private void add(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException{
		//       
		String clientId = request.getParameter("clientInnerId");
		//      
		String[] aimIds = request.getParameterValues("aimInnerId");
		//    
		String[] itemNos = request.getParameterValues("itemNo");
		//    
		String[] qty = request.getParameterValues("qty");
		
		FlowCard flowCard = new FlowCard();
		//    
		flowCard.setOptType("A");
		
		//       ,        session   
		FiscalYearPeriod fiscalYearPeriod = new FiscalYearPeriod();
		fiscalYearPeriod.setId(1);
		
		flowCard.setFiscalYearPeriod(fiscalYearPeriod);
		
		//   
		Client client = new Client();
		client.setId(Integer.parseInt(clientId));
		
		flowCard.setClient(client);
		
		//     
		flowCard.setRecorder(getCurrentUser());

		//    
		flowCard.setOptDate(new Date());
		
		//    
		flowCard.setVouSts("N");
		
		List<FlowCardDetail> flowCardDetailList = new ArrayList();
		for(int i=0;i<aimIds.length;i++){
			FlowCardDetail flowCardDetail = new FlowCardDetail();
			
			//    
			AimClient aimClient = new AimClient();
			aimClient.setId(Integer.parseInt(aimIds[i]));
			flowCardDetail.setAimClient(aimClient);
			
			//  
			Item item = new Item();
			item.setItemNo(itemNos[i]);
			flowCardDetail.setItem(item);
			
			//    
			flowCardDetail.setOptQty(new BigDecimal(qty[i]));
			
			//    
			flowCardDetail.setAdjustFlag("N");
			
			flowCardDetailList.add(flowCardDetail);
		}
		
		flowCard.setFlowCardDetailList(flowCardDetailList);
		
		//            
		FlowCardManager flowCardManager = (FlowCardManager)getBeanFactory().getServiceObject(FlowCardManager.class);
		
		try{
			flowCardManager.addFlowCard(flowCard);
		}catch(Exception e){
			throw new ApplicationException("    ,     !");
		}
		response.sendRedirect(request.getContextPath() + "/servlet/flowcard/FlowCardServlet");
	}
}

MVCは現在流行している開発アーキテクチャモデルであり、StrutsはMVCに基づいてさらにパッケージ化されているため、MVCを食べることは後のフレームワークの学習に非常に役立つ.