너굴 개발 일지

자바 디자인 패턴 : Factory Method Pattern 본문

Java

자바 디자인 패턴 : Factory Method Pattern

너굴냥 2021. 6. 7. 22:42

Factory Method Pattern

객체지향 디자인 패턴으로 일반적으로 객체를 만들어내는 부분을 서브 클래스에 위임하는 패턴으로 볼 수 있다.

즉, new 키워드를 호출하는 부분을 서브 클래스에 위임하는 것이다. 결국 팩토리 메소드 패턴은 객체를 만들어내는 공장(Factory 객체)을

만드는 패턴으로 이해하면 된다.

 

 

 

Factory Method Pattern 사용하는 이유 ?

클래스간의 결합도를 낮추기 위함으로 팩토리 메소드 패턴을 사용하는 경우 직접 객체를 생성하는 것이 아닌 서브 클래스에 위임함으로써 보다 효율적인 코드 제어와 의존성을 제거한다. 결과적으로 결합도 또한 낮출 수 있다.

(결합도 : 클래스의 변경점이 생겼을 때 얼마나 다른 클래스에도 영향을 주는지를 의미)

 

 

 

장점

- 생성할 클래스를 미리 알지 못해도 팩토리 클래스가 객체 생성을 담당

- 객체의 자료형이 하위 클래스에 의해서 결정 -> 확장 용이성

- 확장성 있는 전체 프로젝트 구성 가능

 

단점

- 객체가 늘어날 때마다 하위클래스 재정의로 인해 불필요한 많은 클래스 생성 가능성

 

 

 

팩토리 메소드 패턴 예시

Action Interface

Action Interface 
package com.bjy.controller.action;

import java.io.IOException;
import java.rmi.ServerException;

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

public interface Action {
	public void execute(HttpServletRequest request, HttpServletResponse response) throws ServerException, IOException, ServletException;
}

BoardDeleteAction

import java.io.IOException;
import java.rmi.ServerException;

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

import com.bjy.dao.BoardDAO;

public class BoardDeleteAction implements Action {

	@Override
	public void execute(HttpServletRequest request, HttpServletResponse response) throws ServerException, IOException, ServletException {
		String num = request.getParameter("num");
		
		BoardDAO dao = BoardDAO.getInstance();
		dao.deleteBoard(num);
		
		new BoardListAction().execute(request, response);
	}
}

BoardListAction

import java.io.IOException;
import java.rmi.ServerException;
import java.util.List;

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

import com.bjy.dao.BoardDAO;
import com.bjy.dto.BoardVO;

public class BoardListAction implements Action {
	
	@Override
	public void execute(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
		String url="/board/boardList.jsp";
		
		/** BoardDAO를 통해 select한 결과 List를**/
		BoardDAO dao = BoardDAO.getInstance();
		List<BoardVO> boardList = dao.selectAllBoards();
		
		/**request의 attribute에 저장 후 **/
		request.setAttribute("boardList", boardList);
		
		/** RequestDispacther 객체를 통해 forwarding**/
		RequestDispatcher rd = request.getRequestDispatcher(url);
		rd.forward(request, response);
	}
}

ActionFactory

import com.bjy.controller.action.Action;
import com.bjy.controller.action.BoardCheckPassAction;
import com.bjy.controller.action.BoardCheckPassFormAction;
import com.bjy.controller.action.BoardDeleteAction;
import com.bjy.controller.action.BoardListAction;
import com.bjy.controller.action.BoardUpdateAction;
import com.bjy.controller.action.BoardUpdateFormAction;
import com.bjy.controller.action.BoardViewAction;
import com.bjy.controller.action.BoardWriteAction;
import com.bjy.controller.action.BoardWriteFormAction;

/** SingleTone Pattern **/
/** BoardServlet의 요청사항에 따라 ~~Action 객체 생성 -> 서블릿에게 객체 반환 **/
public class ActionFactory {
	private static ActionFactory instance = null;
	public ActionFactory() {
	}
	
	public static ActionFactory getInstance() {
		if(instance == null) {
			instance = new ActionFactory();
		}
		return instance;
	}
	
	public Action getAction(String command) {
		Action action = null;
		System.out.println("ActionFactiory의 getAction() 호출시 전달사항 - "+ command);
		
		if(command.equals("board_list")){
			System.out.println("board_list 요청사항에 대한 객체 생성");
			action = new BoardListAction();
		}else if(command.equals("board_delete")) {
			System.out.println("board_delete 요청사항에 대한 객체 생성");
			action = new BoardDeleteAction();
		}
		return action;
	}
}

 

BoardDeleteAction, BoardListAction 클래스는 Action Interface를 구현하는 클래스로 매개변수인 command값에 따라서 어떤 객체를 생성할지 ActionFactory 클래스에서 정하고 객체 생성이 이뤄진다.

이처럼 팩토리 메소드 패턴을 사용하면 인스턴스를 필요로 하는 Application에서 Action의 sub 클래스에 대한 정보는 모른 채 인스턴스를 생성할 수 있다.

여기서 중요한 점은 두가지이다.

1. Factory class를 위와 같이 singleton으로 구현해도 되고, 서브 클래스를 리턴하는 static 메소드로 구현해도 된다.

2. 위 예제처럼 getAction()와 같이 입력된 파라미터값에 따라 다른 서브 클래스의 인스턴스를 생성하고 리턴한다.

 

'Java' 카테고리의 다른 글

[Java] BufferedReader, BufferedWriter  (0) 2021.09.07
동기 비동기 방식(Asynchronous processing model)  (0) 2021.06.09
자바 디자인 패턴 : SingleTone  (0) 2021.04.29
TIL_210401_네트워킹  (0) 2021.04.04
TIL_210331_Thread (스레드)  (0) 2021.03.31