소스 코드를 기록하는 남자

'추상 메소드'에 해당되는 글 2건

  1. 팩터리 메소드 패턴(Factory Method Pattern)
  2. 템플릿 메소드 패턴 (Template Method Pattern)

팩터리 메소드 패턴(Factory Method Pattern)

디자인 패턴

팩터리의 의미는 공장이다. 공장은 무언가를 생산하는 장소이다. 객체 지향에서의 팩터리는 객체를 생성하고, 팩터리 메소드는 객체를 생성 반환하는 메소드를 말한다.

 

팩터리 메소드 패턴은 무엇을 의미하는 것인가? 하위 클래스에서 팩터리 메소드를 오버라이딩해서 객체를 반환하는 것을 의미한다. 코드를 살펴보며, 이해를 해보자.

package 팩토리메소드패턴;

public abstract class 동물 {
    abstract 동물장난감 getToy();
}

public abstract class 동물장난감 {
    abstract void identify();
}

public class 강아지 extends 동물 {
    @Override
    동물장난감 getToy() {
    	return new 강아지장난감();
    }
}

public class 강아지장난감 extends 동물장난감 {
    public void identify() {
    	System.out.println("강아지 장난감입니다");
    }
}

public class 고양이 extends 동물 {
    @Override
    동물장난감 getToy() {
    	return new 고양이장난감();
    }
}

public class 고양이장난감 extends 동물장난감 {
    @Override
    public void identify() {
    	System.out.println("고양이 장난감입니다");
     }
}


 

위 코드는 매우 억지처럼 보일 수 있지만, 그래도 중점에 대해서 파악해보자.

여기서 동물의 팩토리 메소드를 구현하여 각 동물이 각자의 장난감을 반환하도록 구현되는 모습을 볼 수 있다.

 

위와 같은 코드 방식으로 구성된다. 아직 미비된 부분이 많은 것 같다. 내가 공부한 책에서 다루는 팩토리 메소드 패턴은 매우 간단하다. 한 마디로 정의된다

"오버라이드된 메소드가 객체를 반환하는 패턴"

 

guy-who-writes-sourcecode.tistory.com/30

 

템플릿 메소드 패턴 (Template Method Pattern)

디자인 패턴

템플릿 메소드는 템플릿을 제공하는 메소드, 하위 클래스에게 구현을 강제하는 추상 메소드, 하위 클래스가 선택적으로 오버라이딩할 수 있는 Hook 메소드를 두는 패턴을 템플릿 메소드 패턴이라 한다.

 

이해가 되지 않는다면, 코드를 보는 것이 좋다.

 

억지스럽게 코드를 한번 작성해보겠다. 너무 불편해하지 않았으면 좋겠다.

 

public class Bmw {
    public void driveOnRoad() {
    	System.out.println("자동차 시동 부릉");
        System.out.println("수동 기어로 시작");
        System.out.println("정지");
        System.out.println("자동차 시동 끄기");
    }
 }
 
 public class Audi {
    public void driveOnRoad() {
    	System.out.println("자동차 시동 부릉");
        System.out.println("자동 기어로 시작");
        System.out.println("정지");
        System.out.println("자동차 시동 끄기");
    }
 }

위와 같은 코드가 있다고 하자. 객체 지향의 특징을 조금이나마 이해하고 있다면, 위에서 반복적하는 코드에 대한 리팩토링 의지가 불타오를 것인다. 따라서 이를 템플릿 메소드 패턴을 적용하여 개선해보자.

 

package 템플릿메소드패턴;

public abstract class Car {
    public void driveOnRoad() {
        System.out.println("자동차 시동 부릉");
        drive();
        stop();
        System.out.println("자동차 시동 끄기");
    }
    
    abstract drive();
    
    void stop() {
    	System.out.println("정지");
    }
}
        
        
package 템플릿메소드패턴;

public class Bmw extends Car {
    @Override
    void drive() {
    	System.out.println("자동 주행");
    }
    
    @Override
    void stop() {
    	System.out.println("Bmw 정지");
    }
 }
 
 
package 템플릿메소드패턴;

public class Audi extends Car {
    @Override
    void drive() {
    	System.out.println("수동 주행");
    }
    
    @Override
    void stop() {
    	System.out.println("Audi 정지");
    }
 }

 

코드만 봐서 이해가 안될 것인다. 하나 하나 짚어서 설명해보겠다.

 

템플릿 메소드 패턴 구성 요소 상위 클래스 Car 하위 클래스 (Bmw, Audi)
템플릿 메소드는 공통 로직을 수행하는 부분, 공통 로직 안에서 하위 클래스에서 오버라이딩한 추상 메소드/훅 메소드를 호출 driveOnRoad()  
템플릿 메소드에서 호출하는 추상 메소드, 하위 클래스가 반드시 오버라이딩하도록 만든다. drive() 오버라이딩 필수
템플릿 메소드에서 호출하는 훅 메소드를 하위 클래스에서 선택적으로 오버라이딩합니다. stop() 오버라이딩 선택

 

"상위 클래스의 견본 메서드에서 하위 클래스가 오버라이딩한 메소드를 호출하는 패턴"

 

템플릿 메소드 패턴이 의존 역전 법칙(DIP)을 활용하고 있음을 알 수 있다. 이 패턴을 통해서 중복되는 공통 로직을 리팩토링하고, 개별로 다르게 진행되는 로직은 추상 메소드와 훅 메소드를 사용하여 강제로 오버라이딩하거나 선택적으로 오버라이딩할 수 있습니다.

 

guy-who-writes-sourcecode.tistory.com/30