Computer Science

Factory Method Pattern | 팩토리 메서드 패턴

연_우리 2022. 7. 29. 21:36
반응형

목차

     

     

     

    어떤 상황에서 쓰일까?

    하얀배는 하얀색깔에, 하얀마크에, whiteship이라는 이름을 가지고있다.

    검정배는 검정색깔에, 검정마크에, blackship이라는 이름을 가지고있다.

    노란배는 하얀배, 검정배와 동일한 작업에 내용물만 바꾸어 만들 수 있다.

     

    배를 만드는 코드가 if문으로 분기처리 되어있으면

    초록배를 만들어야할 경우 분기처리가 4개나 이루어지게되어 깔끔한 코드가 아닐것이고,

    계속 코드를 수정해야하니 확장에 유연하지도 않게된다.

     

    배의 공통적인 color, mark, name을 지정할 수 있도록 팩토리를 지정하고,

    팩토리로부터 하얀배, 검정배, 노란배를 만들 수 있도록 하면 어떨까??

     

     

     

    팩토리 메서드 패턴이란?

    구체적으로 어떤 인스턴스를 만들지는 서브 클래스가 정하게하는 패턴이다

     

    장점

    - 확장에 열려있고 변경에 닫혀있는 객체지향원칙 OCP를 지킬 수 있다

    - 기존의 코드, 특히 인스턴스를 만드는 코드를 건들이지 않고 새로운 인스턴스를 만들 수 있다

     

     

    단점

    - 인스턴스가 추가될때마다 클래스 파일이 계속 생성된다

     

     

     

    구현방법

    기존코드

    public class ShipFactory {
    
        public static Ship orderShip(String name, String email) {
        
            //validate
            if (name == null || name.isBlank()) {
                throw new IllegalArgumentException("배 이름을 지어주세요.");
            }
            if (email == null || email.isBlank()) {
                throw new IllegalArgumentException("연락처를 남겨주세요.");
            }
        
        
            Ship ship = new Ship();
            ship.setName(name);
    
            // Customizing for specific name
            if (name.equalsIgnoreCase("whiteship")) {
                ship.setLogo("\uD83D\uDEE5️");
            } else if (name.equalsIgnoreCase("blackship")) {
                ship.setLogo("⚓");
            }
    
            // coloring
            if (name.equalsIgnoreCase("whiteship")) {
                ship.setColor("white");
            } else if (name.equalsIgnoreCase("blackship")) {
                ship.setColor("black");
            }
    
            return ship;
        }
    }

     

     

     

    변경코드

    ShipFactory 클래스를 인터페이스로 변경하고

    이름, 로고, 색깔을 지정하는 것은 인터페이스를 상속받은 클래스로 변경한다

    public interface ShipFactory {
    
        default Ship orderShip(String name, String email) {
            validate(name, email);
            Ship ship = createShip();
            return ship;
        }
        
        
        //구현 클래스에서 구현할 메서드
        Ship createShip();
    
        //공통적으로 쓰이는 유효성검사 메서드
        private void validate(String name, String email) {
            if (name == null || name.isBlank()) {
                throw new IllegalArgumentException("배 이름을 지어주세요.");
            }
            if (email == null || email.isBlank()) {
                throw new IllegalArgumentException("연락처를 남겨주세요.");
            }
        }
        
    }
    public class WhiteshipFactory implement ShipFactory {
    
        @Override
        public Ship createShip() {
            return new Whiteship();
            
            //해당 예제코드에서는 new Whiteship()을 만들어서 반환해주기만 하면되지만
            //만약 나중에 하얀색 배는 100kg까지 적재해야하고, 검정색 배는 150kg까지 적재해야한다는 조건이 추가되면 
            //WhiteshipFactory클래스에서 validation처리를 해주어야한다!
        }
    }
    public class Whiteship extends Ship {
    
        public Whiteship() {
            setName("whiteship");
            setLogo("\uD83D\uDEE5️");
            setColor("white");
        }
        
    }
    public class Client {
    
        public static void main(String[] args) {
            Client client = new Client();
            client.print(new WhiteshipFactory(), "whiteship", "keesun@mail.com");
            client.print(new BlackshipFactory(), "blackship", "keesun@mail.com");
        }
    
        //ShipFactory를 받기때문에 YellowshipFactory가 생긴다해도 print메서드는 변함이 없다
        private void print(ShipFactory shipFactory, String name, String email) {
            System.out.println(shipFactory.orderShip(name, email));
        }
    
    }

     

     

    여기서 Blackship을 만들때, Whiteship의 코드를 수정할 이유가 있을까??? 없다!

    Whiteship과 동일하게 BlackshipFactory, Blackship을 생성해주기만 하면 된다!

    변경에는 닫혀있고 확장에는 열려있는 코드가 완성되었다~!

     

     

     

     

     

     

     

     

     

     

    반응형

    'Computer Science' 카테고리의 다른 글

    Prototype Pattern | 프로토타입 패턴  (0) 2022.08.14
    Abstract Factory | 추상 팩토리 패턴  (0) 2022.08.14
    Singleton pattern | 싱글톤패턴  (3) 2022.07.29
    운영체제 개요  (0) 2022.03.25
    프로세스? 스레드?  (0) 2022.02.17
    • 네이버 블러그 공유하기
    • 페이스북 공유하기
    • 트위터 공유하기
    • 구글 플러스 공유하기
    • 카카오톡 공유하기