배경
결제 관련된 페이지를 만드는 도중 이런 상황과 마주했다.
- 결제(이하 멤버십)에는 세 가지 단계가 존재(베이식, 스탠다드, 프리미엄)
- 각 결제 단계마다 1) 해당 단계의 이미지 2) 해당 단계의 문구 3) 해당 단계 신청 api 가 존재
위와 같은 상황에서 베이직, 스탠다드, 프리미엄 멤버십 객체는 어떻게 구성되어야 할까?
class Membership {
}
class Basic extends Membership {
image = require('basic.png')
description = '배이직 멤버십 입니다'
apply() {
// 베이직 멤버십 신청 함수
}
}
class Standard extends Membership {
image = require('standard.png')
description = '스탠다드 멤버십 입니다'
apply() {
// 스탠다드 멤버십 신청 함수
}
}
각 멤머십 단계는 분명 Membership이라는 Class를 상속받는 형태여야 할 텐데...
상속받은 각 객체인 Basic, Standard, Premium은 각 속성과 메서드가 비슷하면서도 약간의 차이가 존재하는 상황이다!
흠... 그렇다면 각 멤버십 단계가 상속받는 Membershipd이란 Class에는 아무것도 정의할 수가 없는 걸까?
각 멤버십 단계들은 분명 공통적인 알고리즘 구조를 갖고 있는데, 이를 명시적으로 표현할 방법은 없을까?
Template Method pattern
이러한 상황에서 Template Method 패턴을 사용할 수 있다.
Template Method 패턴은 알고리즘의 골격을 정의하고 세부 구현을 서브클래스에 위임하는 패턴입니다.
공통의 알고리즘 구조를 정의하고 각 단계의 구체적인 구현을 서브클래스에서 제공합니다.
상위 클래스는 추상 메서드와 구체 메서드를 포함하며, 추상 메서드는 서브클래스에서 오버라이딩해야 합니다.
주로 알고리즘의 일부분이 변할 때 사용됩니다.
아하!
즉 각 멤버십이 공통적으로 갖는 알고리즘 구조는 상위 클래스에서 정의하고
상위 클래스에서 정의된 추상 메서드는 서브 클래스에서 구체적으로 구현해 사용한다면
→ 각 하위 클래스 별로 속성과 메서드를 정의하는 동시에, 상위 클래스를 통해 각 객체들의 공통된 알고리즘을 명확하게 표현할 수 있겠다!
특히 위 상황에서는 상위 클래스를 구현한 서브 클래스(Basic, Standard, Premium)의 인스턴스만 존재할 뿐,
상위 클래스인 Membership을 인스턴스화할 필요가 없으므로
→ 이를 추상 클래스로 구현한다면 의도를 좀 더 명시적으로 전달할 수 있을 테다.
// 상위 Class인 Membership을 추상 Class로 작성
abstract class Membership {
constructor(
protected image: string,
protected description: string
) {}
abstract apply(): void; // 추상 메서드 -> 반드시 서브 클래스에서 구현
}
Membership은 '멤버십' 객체가 가져야 할 구조만 정의한 채, 구체적인 구현은 서브 클래스에 위임할 수 있도록 작성했다.
// 서브 클래스에서, 각 객체에 맞는 로직 구현
class Basic extends Membership {
constructor() {
super('basic-image.jpg', 'Basic Membership Description');
}
apply(): void {
// Basic Membership에 특화된 제출 로직을 구현
}
}
class Standard extends Membership {
constructor() {
super('standard-image.jpg', 'Standard Membership Description');
}
apply(): void {
// Standard Membership에 특화된 제출 로직을 구현
}
}
class Premium extends Membership {
constructor() {
super('premium-image.jpg', 'Premium Membership Description');
}
apply(): void {
// Premium Membership에 특화된 제출 로직을 구현
}
}
각 서브 클래스에서 추상 메서드를 오버라이딩해, 각 멤버십 별 동작을 구현한 모습!
'source-code > software' 카테고리의 다른 글
프로그래머의 뇌 (0) | 2023.08.30 |
---|---|
Singleton Pattern을 통한 axios 쿠키 허용 (0) | 2023.08.20 |
Postgresql date_trunc 함수를 통한 날짜별 조회 (0) | 2023.08.20 |
첫 실무 test code 작성 및 고민 (0) | 2023.08.20 |
클린 코드 (0) | 2023.08.20 |