plain old란 평범한, 순수한이란 뜻이다. POJO는 Java로 생산한 순수한 객체를 의미한다. POJO 프로그래밍에는 두 가지 규칙이 존재한다.
public class MessageForm extends ActionForm{ // (1)
String message;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
public class MessageAction extends Action{ // (2)
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
MessageForm messageForm = (MessageForm) form;
messageForm .setMessage("Hello World");
return mapping.findForward("success");
}
}
(1)번 코드의 ActionForm 클래스나 (2)번 코드의 Action 클래스의 상속의 경우, Struts라는 웹 프레임워크에서 지원하는 클래스이다. 특정 기술의 코드를 상속받게 되어 애플리케이션의 요구사항이 변경되면 이를 일일이 제거하거나 수정해야한다.
POJO 프로그래밍을 위해서는 코드 작성시, 코드가 객체지향스러운가에 대한 고민을 하는 습관을 가지는 것이 중요하다.
애플리케이션 흐름의 주도권이 뒤바뀐 상황(제어의 역전)
일반적인 자바 코드의 경우, main 메서드 안에서 다른 객체의 메서드를 호출하는 흐름이 일반적이다. 하지만 웹 프레임워크의 경우, 별도의 main 메서드가 없기 때문에 호출 흐름이 역전된다고 볼 수 있다.
IoC의 개념을 구체화시킨 것으로 해석할 수 있다. 직역하면 의존성 주입으로 객체지향 프로그래밍에서 객체간의 의존 관계를 느슨하게 해주는 것이다. 여기서 의존 관계란 한 클래스가 다른 클래스의 메소드를 사용하거나 호출하는 경우를 의미한다.
Client 클래스
public class Client {
public static void main(String[] args) {
MenuService menuService = new MenuService();
MenuController controller = new MenuController(menuService); // 의존성 주입
List<Menu> menuList = controller.getMenus();
}
}
MenuController 클래스
public class MenuController {
private MenuService = menuService;
// 생성자의 파라미터를 MenuService의 객체로 입력받음
public MenuController(MenuService menuService) {
this.menuService = menuService;
}
public List<Menu> getMenus() {
return menuService.getMenuList();
}
}
MenuService 클래스
public class MenuService {
public List<Menu> getMenuList() {
return null;
}
}
한 클래스의 생성자의 파라미터를 객체로 입력받는 경우를 의존성 주입이라 한다.
클래스 간에는 느슨한 결합(Loose Coupling)이 필요하다. 하지만 객체를 생성할 때, new 키워드를 사용하여 생성하면 클래스들 간에 강한 결합이 된다. 해당 클래스의 이름을 변경하면 해당 코드를 전부 고쳐야 하기 때문이다. 이는 Spring이 대신하도록 설정할 수 있다.
Client 클래스
public class Client {
public static void main(String[] args) {
GenericApplicationContext context = new AnnotationConfigApplicationContext(Config.class);
MenuController controller = context.getBean(MenuController.class);
List<Menu> menuList = controller.getMenus();
}
}
MenuController 클래스
public class MenuController {
private MenuService = menuService;
@Autowired
public MenuController(MenuService menuService) {
this.menuService = menuService;
}
public List<Menu> getMenus() {
return menuService.getMenuList();
}
}
Config
@Configuration
@ComponentScan(basePackageClasses = Client.class)
public class Config {
@Bean
public MenuService getMenuService() {
return new MenuServiceStub();
}
@Bean
public MenuController getMenuController(MenuService menuService) {
return new MenuController(menuService);
}
}
@Autowired나 @Bean같은 어노테이션을 통해 new 키워드 없이 생성자를 대신 생성할 수 있다.