Study/디자인패턴

팩토리 메서드(Factory Method Pattern)

ABCD 2023. 4. 4.

팩토리 메서드(Factory Method Pattern)

  • 객체를 생성할 때 어떤 클래스의 인스턴스를 만들 지 서브 클래스에서 결정하게 함
  • 인스턴스 생성을 서브 클래스에게 위임
  • 부모 추상 클래스는 인터페이스에만 의존하고 실제로 어떤 클래스를 호출할 지는 서브 클래스에서 구현
  • 새로운 구현 클래스가 추가되어도 기존 Factory코드의 수정 없이 새로운 Factory를 추가하면 됨ex) 컴퓨터를 예로 들면 키보드, 마우스, 모니터, 스피커 등을 다 따로따로 만들어주는 방법

예제) 사용자 관리 프로그램이 있고 네이버 계정으로 가입할 수 있다고 가정


1. Product(User)

public interface User {
    void signup();
}
  • User 인터페이스 정의
public class NaverUser implements User {
    @Override
    public void signup() {
        System.out.println("네이버 아이디로 가입");
    }
}
  • User 인터페이스를 구현하는 NaverUser 클래스 정의
  • 오버라이드한 메서드에는 네이버 유저 전용 로직 추가

3. Creator(UserFactory)

public abstract class UserFactory {

    public User newInstance(){
        User user = createUser();
        user.signup();
        return user;
    }

    protected abstract User createUser();
}
  • 추상 클래스로 UserFactory를 정의
  • 외부에서 User 객체를 생성할 때는 newInstance() 메서드를 호출
  • 실제로 어떤 객체를 생성할 지는 추상 메서드로 정의해서 하위 클래서에서 정의
  • Java 8 부터는 인터페이스에서 default 메서드를 사용 할 수 있기 때문에 인터페이스로 정의 할 수 있지만 protected 키워드를 사용해 접근을 제한
public class NaverUserFactory extends UserFactory {
    @Override
    protected User createUser(){
        return new NaverUser();
    }
}
  • UserFactory를 상속받는 NaverUserFactory를 정의
  • NaverUsr를 반환하도록 오버라이드

3. Client

UserFactory userFactory = new NaverUserFactory();
User user = userFactory.newInstance();

스펙 확장) 카카오 사용자가 많아져 카카오 계정으로도 가입할 수 있게 확장되었다 가정

  • 확장할 때 기존 코드의 변경이 없어도 되다는 장점을 이용
  • Simple Factory에서는 UserFactory의 코드를 수정해야함
  • 깜빡하고 switch - case 문을 추가하지 않으면 오류 발생
  • Enum으로 어느정도 방어는 가능하지만 수정에도 열려있다는 단점은 여전히 존재

1. 새로운 Product와 Creator

public class KakaoUser implements User {
    @Override
    public void signup(){
        System.out.println("카카오 아이디로 가입");
    }
}
  • NaverUser 클래스와 동일하게 User 인터페이스를 구현하는 KakaoUser 클래스 추가
public class KakaoUserFactory extends UserFactory {
    @Override
    protected User createUser() {
        return new KakaoUser();
    }
}
  • NaverUserFactory 클래스와 동일하게 KakaoUserFactory정의
UserFactory userFactory = new NaverUserFactory();
User user = userFactory.newInstance();

//위 클라이언트 코드 수정 없이 다른 곳에서 사용 가능
UserFactory KakaoUserFactory = new KakaoUserFactory();
User user = KakaoUserFactory.newInstance();
  • 기존 코드의 변경 없이 새로 선언한 클래스만 사용하여 확장 가능

장단점

  • 장점
    • 수정에 닫혀있고 확장에는 열려있는 OCP원칙을 지킬 수 있다는 점
    • OCP(Open-Closed Principle) : 기존코드를 변경하지 않으면서 기능을 추가 할 수 있도록 하는 원칙
  • 단점
    • 간단한 기능을 사용할 때보다 많은 클래스를 정의해야 하기 때문에 코드량이 증가함
728x90
반응형

댓글

💲 추천 글