개발 알다가도 모르겠네요

Factory Method Pattern 을 알아보자 본문

디자인패턴

Factory Method Pattern 을 알아보자

이재빵 2021. 12. 17. 23:02
728x90

객체 생성 처리를 서브 클래스로 분리,  캡슐화해 주는 패턴

 

객체 생성 처리를 서브 클래스로 분리 해 처리하도록 캡슐화

전체적인 알고리즘의 코드를 재사용하는데 유용하게 쓰입니다.

전체적으로 동일하면서 부분적으로 상이한 문장을 가지는 메소드의 코드 중복을 최소화할 때 유용합니다.

 

 

Example - 사과를 디저트로 제공하는 식당 클래스 만들기

public class Restaurant {
public Apple servingApple() {
Apple apple = new Busa();
apple.wash();
apple.peel();
apple.slice();
return apple;
}
}

 

public abstract class Apple {
public abstract void wash();
public abstract void peel();
public abstract void slice();
}


public class Busa extends Apple {
@Override
public void wash() {
System.out.println("부사: 물로 씻기");
}
@Override
public void peel() {
System.out.println("부사: 껍질 벗기기");
}
@Override
public void slice() {
System.out.println("부사: 자르기");
}
}


public class Hongok extends Apple {
@Override
public void wash() {
System.out.println("홍옥: 물로 씻기");
}
@Override
public void peel() {
System.out.println("홍옥: 껍질 벗기기");
}
@Override
public void slice() {
System.out.println("홍옥: 자르기");
}
}

 

Example- 사과를 아침으로 먹는 Home 클래스 만들기

public class Home {
public Apple getAppleForBreakFast() {
Apple apple = new Hongok();
apple.wash();
return apple;
}
}

 

문제점- 사과의 종류가 변경되거나 추가될 수 있음.

public class Restaurant {
public Apple servingApple() {
Apple apple = new Busa();
apple.wash();
apple.peel();
apple.slice();
return apple;
}
} 

//사과 인스턴스를 생성하는 모든 코드에서 이러한 작업을 반복할 필요가 있다. (ex Restaurant, Home)

public class Restaurant {
public Apple servingApple(String kind) {
Apple apple = null;
if (kind.equals("busa")) apple = new Busa();
else if (kind.equals("hongok")) apple = new Hongok();
apple.wash();
apple.peel();
apple.slice();
return apple;
}
}

 

따라서 변경이 자주 일어나는 부분은 분리하여 클래스로 캡슐화할 필요가 있습니다.

public class AppleFactory {
public static Apple getApple(String kind) {
Apple apple = null;
if(kind.equals("busa"))apple =new Busa();
else if(kind.equals("hongok"))apple =new Hongok();
else if (kind.equals("hongro"))apple =new Hongro();
return apple;
}
}


public class Restaurant {
public Apple servingApple(String kind) {
Apple apple = null;
apple = AppleFactory.getApple(kind);
apple.wash();
apple.peel();
apple.slice();
return apple;
}
}


public class Home {
public Apple getAppleForBreakFast(String kind) {
Apple apple = null;
apple = AppleFactory.getApple(kind);
apple.wash();
return apple;
}
}

 

새로운 사과 종류가 추가되어도 Factory method만 변경할 필요가 있고 실제 사과를 사용하는 클래스는 영향을 받지 않습니다.

public class AppleFactory {
public static Apple getApple(String kind) {
Apple apple = null;
if(kind.equals("busa"))apple =new Busa();
else if(kind.equals("hongok"))apple =new Hongok();
else if (kind.equals("hongro"))apple =new Hongro();
return apple;
}
}

 

Singleton Pattern 적용

public class AppleFactory {
	private AppleFactory instance = null;
    private AppleFactory() {};
    
    public static AppleFactory getInstance() {
    	if(instance == null) instance = new AppleFactory();
        return instance; 
    }


public class Restaurant {
	publuc Apple ServingApple(String kind) {
    AppleFactory factory = AppleFactory.getInstance();
    Apple apple = factory.getApple(kind);
    }

 

 

 

GoF Factory Method Pattern

  • 객체를 생성하기 위해 인터페이스를 정의하지만, 어떤 클래스의 인스턴스를 생성할지에 대한 결정은 하위클래스가 담당.
  • 전체적인 흐름은 Template Method 이용하지만 객체 생성은 하위클래스가 재정의함.

 

Example- 식당에서 사과를 디저트로 제공하는 것을 서울 지점과 뉴욕 지점으로 확대

 

사과를 서빙하기 위해 수행하는 단계는 어느 지점이나 공통이 되도록 함.

- getApple

- Wash

- Peel

- Slice 

반면에 사과의 종류는 지역(지점)마다 달리할 수 있음. (Template Method 이용)

 

public abstract class Restaurant {
public Apple servingApple(String kind) {
Apple apple = getApple(kind);
apple.wash();
apple.peel();
apple.slice();
return apple;
}
public abstract Apple getApple(String kind);
}
public class SeoulRestaurant extends Restaurant {
@Override
public Apple getApple(String kind) {
Apple apple = null;
if(kind.equals("busa"))apple =new Busa();
else if(kind.equals("hongok"))apple =new Hongok();
else if (kind.equals("hongro"))apple =new Hongro();
return apple;
}
}
public class NewYorkRestaurant extends Restaurant {
@Override
public Apple getApple(String kind) {
Apple apple = null;
if(kind.equals(“koru"))apple =new Koru();
else if(kind.equals(“crispy"))apple =new Evercrispy();
else if (kind.equals(“pl"))apple =new Pinklady();
return apple;
}
}

'디자인패턴' 카테고리의 다른 글

Bridge Pattern 을 알아보자  (0) 2021.12.20
Abstract Pattern 을 알아보자  (0) 2021.12.19
Template Method Pattern 을 알아보자  (0) 2021.12.15
Decorator Pattern 을 알아보자  (0) 2021.12.14
Observer Pattern 을 알아보자  (0) 2021.12.13