📜 제목으로 보기

템플릿메소드패턴 to 전략패턴

  1. 만약, 템플릿메소드의 자식이 주입되는 전략주입 구상클래스가 이미 존재하는 상황이고, 템플릿추상클래스가 [훅구현 자식들의 기능]외에 공통로직이 없는 상황이면, 추상클래스를 인터페이스로 변경후, 훅메서드 정의부(proteceted abstract) -> 전략메서드 정의부로 변경(public)로 변경해서 남기고 다 지운 뒤, 바로 5번으로 가면 된다.
  2. 추상class를 일반클래스로 변경 및 훅메서드 정의부 삭제
    • 훅메서드를 alt+del로 삭제하면, 구상체들의 개별로직이 재활용안되므로 그냥 삭제한다.
  3. 내수용 private훅메서드 호출부를, 주입된 전략객체.전략메서드()호출로 변경
    • 전략객체명은, 전략메서드(구 훅메서드)를 바탕으로 or로 만드는게 일반적이다.
  4. 전략 인터페이스 만들고, 전략메서드를 올린다.
  5. 전략객체를 생성자 주입받는다 (생성자 or 확장(좋은 상속 가능성)있으면 setter로 받기)
    • 일단은 1개만 필수로 받도록 생성자 주입 받는다.(base)
  6. 훅메서드구현 개별자식들을 [구상내용+전략인페명]으로 변경하고, 전략인터페이스 구현시킨다.
  7. @Override 개별구현 proected훅메서드 -> public전략메서드로 시그니쳐 변경

  8. 전략주입 구상클래스가 된 부모클래스의 템플릿메소드 공통로직 with 내부 context변수들 -> 전체를 전략메서드에 인자로 context위임
    • 내부context변수들(보라색)을 지역변수로 추출 이후 -> 제외하고 메서드 추출 -> 인라인으로 메서드인자로 context 넘겨주기
  9. delegate로 추출한 전체로직을 전략메서드에 default메서드로 위임
  10. 위임된 default메서드 로직에서, default를 지우고 로직을 개별 전략객체들에게 구현->전달후, 기존 전략메서드(context인자X)는 삭제

  11. 전략주입 구상클래스가 여러개의 전략을 받는다면, Set컬렉션 전략객체 필드를 만들고
    1. 1번째 전략객체는 필수로서 생성자 주입 받되, add해준다.
    2. 2번째 전략객체부터는 setter로 add하여 받는다.(setNext())
      • 만약, 메서드 체이닝으로 받고 싶다면, add 후 return this로 컬렉션필드를 가진 구상클래스를 반환해서, 체이닝하여 계속 받도록 하면 된다.
  12. 전략객체를 사용하는 기존 템플릿메서드에서, for문으로 컬렉션필드를 돌면서 누적적용해준다.
  13. client에서 전략주입 구상클래스에 1번째 전략객체는 생성자 주입 -> 2번재부터는 setNext의 메서드체이닝으로 전략객체들을 받아준다.
    • 전략적용객체에는 전략주입 구상클래스를 set해줘야한다.

전략패턴 to 템플릿메소드패턴

  1. 전략인터페이스를 추상클래스로 변경하고, 전략메서드를 삭제한다.
  2. 구상체(전략객체) 1개를 택하여, 추상클래스를 상속후, 중복되는 필드(next)를 생성자 삭제후 setter 먼저 만들어 같이 올린다. 올라온 필드는 privte을, 템플릿메소드도 final을 달아준다.
  3. 다른 전략객체들도, 추상클래스를 상속하고, 삭제된 중복필드 및 생성자주입부를 삭제한다.
  4. 구상체들을 compare files이후, 인자로 넘어온 객체context를 많이 사용하는 구상체를 택하여, 예비훅메서드를 private내수용 메서드로 추출한 뒤, 공통로직을 가진 전략메서드를 템플릿메서드로 올린다.
  5. 다른 구상체들은 올라간 템플릿메서드와 훅메서드에 대해, 훅메서드를 구현하여, 전략메서드 중 개별로직을 붙여넣고, 전략메서드를 삭제한다.
  6. 추상클래스가 좋은 부모인지 확인한다. (private필드, final메서드 or protected abstract 메서드)
  7. 연결되는 합성객체인 경우, setter에 return this + 추상체 응답이후, client에서는 생성자체이닝처럼 setter를 체이닝한다.