Study/TIL(Today I Learned)

24.08.29 CS, C++

에린_1 2024. 8. 29. 15:38
728x90

CS

템플릿 메소드(Template Method)

  • 템플릿 메서드 패턴은 여러 클래스에서 공통으로 사용하는 메서드를 템플릿화 하여 상위 클래스에서 정의하고, 하위 클래스마다 세부 동작을 다르게 구현하는 패턴이다.
  • 즉, 변하지 않는 기능(템플릿)은 상위 클래스에 만들어두고 자주 변경되며 확장할 기능은 하위 클래스에서 만들도록 하여, 상위의 메소드 실행 동작 순서는 고정하면서 세부 실행 내용은 다양화 될 수 있는 경우에 사용된다.
  • 템플릿 메소드 패턴은 상속이라는 기술을 극대화하여, 알고리즘의 뼈대를 맞추는 것에 초점을 둔다. 이미 수많은 프레임워크에서 많은 부분에 템플릿 메소드 패턴 코드가 우리도 모르게 적용되어 있다.

템플릿 메서드 패턴 구조

  • AbstractClass(추상 클래스)
    • 템플릿 메소드를 구현하고, 템플릿 메소드에서 돌아가는 추상 메소드를 선언한다. 이 추상 메소드는 하위 클래스인 ConcreteClass 역할에 의해 구현된다.
  • ConcreteClass(구현 클래스)
    • AbstractClass를 상속하고 추상 메소드를 구체적으로 구현한다. ConcreteClass에서 구현한 메소드는 AbstractClass의 템플릿 메소드에서 호출된다.

hook 메서드

  • 훅(hook) 메소드는 부모의 템플릿 메서드의 영향이나 순서를 제어하고 싶을때 사용되는 메서드 형태를 말한다. 이를 통해 자식 클래스에서 좀 더 유연하게 템플릿 메서드의 알고리즘 로직을 다양화할 수 있다는 특징이 있다.
  • 훅 메서드는 추상 메소드가 아닌 일반 메소드로 구현하는데, 선택적으로 오버라이드 하여 자식 클래스에서 제어하거나 아니면 놔두거나 하기 위해서 이다.

템플릿 메소드 패턴 특징

  • 패턴 사용 시기
    • 클라이언트가 알고리즘의 특정 단계만 확장하고, 전체 알고리즘이나 해당 구조는 확장하지 않도록 할 때
    • 동일한 기능은 상위 클래스에서 정의하면서 확장, 변화가 필요한 부분만 하위 클래스에서 구현할 때
  • 패턴 장점
    • 클라이언트가 대규모 알고리즘의 특정 부분만 재정의하도록 하여, 알고리즘의 다른 부분에 발생하는 변경 사항의 영향을 덜 받도록 한다.
    • 상위 추상 클래스로 로직을 공통화하여 코드의 중복을 줄일 수 있다.
    • 서브 클래스의 역할을 줄이고, 핵심 로직을 상위 클래스에서 관리하므로서 관리가 용이해진다.
      • 헐리우드 원칙(Hollywood Principle) : 고수준 구성요소에서 저수준을 다루는 원칙
  • 패턴 단점
    • 알고리즘의 제공된 골격에 의해 유연성이 제한될 수 있다.
    • 알고리즘 구조가 복잡할수록 템플릿 로직 형태를 유지하기 어려워진다.
    • 추상 메소가드가 많아지면서 클래스의 생성, 관리가 어려워질 수 있다.
    • 상위 클래스에서 선언된 추상 메소드를 하위 클래스에서 구현할 때, 그 메소드가 어느 타이밍에서 호출되는지 클래스 로직을 이해해야 할 필요가 있다.
    • 로직 변화가 생겨 상위 클래스를 수정할 때, 모든 서브 클래스의 수정이 필요 할수도 있다.
    • 하위 클래스를 통해 기본 단계 구현을 억제하여 리스코프 치환 법칙을 위반할 여지가 있다.

할리우드 원칙 준수

  • 할리우드 원칙(Hollywood Priciple) 이란 고수준 모듈(추상클래스, 인터페이스)에 의존하고 고수준 모듈에서 연락(메소드 실행) 하라는 원칙이다.
  • 객체 끼리 이상하게 얼키고 설켜, 의존성이 복잡하게 꼬여있는 것을 의존성 부패(dependency rot)라고 부르는데, 헐리우드 원칙을 활용하면 의존성 부패를 방지할 수 있게 된다.

비슷한 디자인 패턴 비교 - Strategy vs Temaplate Method

  • 전략 패턴은 합성(composition)을 통해 해결책을 강구하며, 템플릿 메서드 패턴은 상속(inheritance)을 통해 해결책을 제시한다.
  • 그래서 전략 패턴은 클라이언트와 객체 간의 결합이 느슨한 반면, 템플릿 메서드 패턴에서는 두 모듈이 더 밀접하게 결합된다. (결합도가 높으면 안좋다)
  • 전략 패턴에서는 대부분 인터페이스를 사용하지만, 템플릿 메서드 패턴에서는 주로 추상 클래스나 구체적인 클래스를 사용한다.
  • 전략 패턴에서는 전체 전략 알고리즘을 변경할 수 있지만, 템플릿 메서드 패턴에서는 알고리즘의 일부만 변경되고 나머지는 변경되지 않은 상태로 유지된다.(템플릿에 종속)

참조

https://inpa.tistory.com/entry/GOF-💠-템플릿-메소드Template-Method-패턴-제대로-배워보자

C++

함수의 오버로딩(Overloading)

  • C++에서는 같은 이름을 가진 함수가 여러개 존재해도 된다. C++에서는 같은 이름의 함수를 호출했을때 사용하는 인자를 보고 결정하게 된다. 함수의 이름이 같더라도 인자가 다르면 다른 함수라고 판단하기 때문에 오류가 발생하지 않는다.

C++ 컴파일러에서 함수를 오버로딩하는 과정

  1. 자신과 타입이 정확히 일치하는 함수를 찾는다.
  2. 정확히 일치하는 타입이 없는 경우 아래와 같은 형변환을 통해서 일치하는 함수를 찾아본다.
    • Char, unsigned char, short 는 int 로 변환된다.
    • Unsigned short 는 int 의 크기에 따라 int 혹은 unsigned int 로 변환된다.
    • Float 은 double 로 변환된다.
    • Enum 은 int 로 변환된다.
  3. 위와 같이 변환해도 일치하는 것이 없다면 아래의 좀 더 포괄적인 형변환을 통해 일치하는 함수를 찾는다.
    • 임의의 숫자(numeric) 타입은 다른 숫자 타입으로 변환된다.
      • ex) float → int
    • Enum 도 임의의 숫자 타입으로 변환된다.
      • ex) Enum → double
    • 0은 포인터 타입이나 숫자 타입으로 변환된다.
    • 포인터는 void 포인터로 변환된다
  4. 유저 정의된 타입 변환으로 일치하는 것을 찾는다.
  • 만약에 컴파일러가 위 과정을 통하더라도 일치하는 함수를 찾을 수 없거나 같은 단계에서 두 개 이상이 일치하는 경우에 모호하다(ambiguous) 라고 판단해서 오류를 발생하게 된다.

생성자(Constructor)

  • 생성자는 기본적으로 객체 생성시 자동으로 호출되는 함수라고 볼 수 있다. 이 때 자동으로 호출되면서 객체를 초기화 해주는 역할을 담당하게 된다.

디폴트 생성자(Default Constructor)

  • 디폴트 생성자는 인자를 하나도 가지지 않는 생성자인데, 클래스에서 사용자가 어떠한 생성자도 명시적으로 정의하지 않았을 경우에 컴파일러가 자동으로 추가해주는 생성자이다.
  • 물론 컴파일러가 자동으로 생성할 때에는 아무런 일도 하지 않게 된다. 그렇기에 쓰레기 값이 나온다.
  • C++ 11 이전에는 디폴트 생성자를 사용하고 싶을 경우 그냥 생성자를 정의하지 않는 방법 밖에 없었다. C++ 11 부터는 명시적으로 디폴트 생성자를 사용하도록 명시할 수 있다.
  • 생성자의 선언 바로 뒤에 = default 를 붙여준다면, 디폴트 생성자를 정의하라고 컴파일러에게 명시적으로 알려줄 수 있다.

생성자 오버로딩

  • 생성자 역시 함수이기 때문에 함수의 오버로딩이 적용될 수 있다.
  • 해당 클래스의 객체를 여러가지 방식으로 생성할 수 있게 된다.
728x90

'Study > TIL(Today I Learned)' 카테고리의 다른 글

24.09.02 CS, 언리얼  (1) 2024.09.02
24.08.30 CS, C++  (0) 2024.08.30
24.08.27 CS, C++  (0) 2024.08.27
24.08.26 CS, C++  (0) 2024.08.26
24.08.23 CS  (0) 2024.08.23