토니의 연습장
Strategy Design Pattern 본문
🧩 전략 패턴이란?
전략 패턴이란, 알고리즘이나 로직을 여러 가지로 정의하고, 이것들을 상황에 따라 바꿔가며 사용할 수 있도록 만드는 디자인 패턴이야.
전략 패턴은 크게 3가지 구성 요소로 이루어져 있어.
Strategy (전략): 기능의 인터페이스를 정의하는 역할
Concrete Strategy (구체적 전략): Strategy를 구체적으로 구현한 클래스
Context (컨텍스트): Strategy를 사용하는 클래스. 전략을 상황에 따라 교체할 수 있도록 관리해.
🎯 1단계: 전략 인터페이스 정의 (PaymentMethod)
python
복사
편집
from abc import ABC, abstractmethod
class PaymentMethod(ABC):
@abstractmethod
def pay(self, amount):
pass
추상 클래스(PaymentMethod)는 각 전략이 공통으로 구현해야 하는 메서드를 명시해. 여기서는 pay(amount) 메서드야.
실제로 PaymentMethod 자체로는 인스턴스를 생성할 수 없어. 반드시 하위 클래스에서 pay 메서드를 구현해야 해.
🚩 2단계: 구체적인 전략 구현 (Concrete Strategies)
python
복사
편집
class CreditCardPayment(PaymentMethod):
def pay(self, amount):
return f"Paying {amount} using Credit Card."
class PayPalPayment(PaymentMethod):
def pay(self, amount):
return f"Paying {amount} using PayPal."
class BitcoinPayment(PaymentMethod):
def pay(self, amount):
return f"Paying {amount} using Bitcoin."
인터페이스(PaymentMethod)를 상속하여 다양한 전략(결제 방식)을 구체적으로 구현한 클래스들이야.
각각의 클래스는 동일한 pay 메서드를 갖지만, 결제 방법이 다르게 구현된 것을 볼 수 있어.
새로운 결제 방식이 추가될 때 이 부분만 수정하면 돼.
🛒 3단계: Context 클래스 구현 (ShoppingCart)
python
복사
편집
class ShoppingCart:
def __init__(self, payment_method: PaymentMethod):
self.payment_method = payment_method
def checkout(self, amount):
return self.payment_method.pay(amount)
ShoppingCart 클래스는 전략을 사용하는 클래스(Context)로, 결제 방식을 외부에서 전달받아서 상황에 맞는 전략을 사용하도록 해.
생성자에서 결제 방식을 받아서 객체에 저장하고, 나중에 checkout 메서드를 호출하면 그 전략을 사용해 결제를 처리하지.
여기서 전략을 바꾸려면 다른 전략을 전달하기만 하면 돼.
⚙️ 4단계: Context에서 전략 사용하기 (Main 실행 부분)
python
복사
편집
if __name__ == "__main__":
cart = ShoppingCart(CreditCardPayment())
print(cart.checkout(100)) # Paying 100 using Credit Card.
cart = ShoppingCart(PayPalPayment())
print(cart.checkout(200)) # Paying 200 using PayPal.
cart = ShoppingCart(BitcoinPayment())
print(cart.checkout(300)) # Paying 300 using Bitcoin.
이 부분이 실제 전략 패턴을 활용하는 부분으로,
ShoppingCart에 각각 다른 전략(CreditCardPayment, PayPalPayment, BitcoinPayment)을 전달하여 다양한 결제 방식을 사용할 수 있음을 보여주고 있어.
같은 ShoppingCart라는 클래스의 인터페이스를 유지하면서도 결제 전략만을 변경하여 다양한 동작을 수행하도록 만든 것이 핵심이야.
📌 전략 패턴의 장점:
코드의 유지 보수가 쉬워져.
새로운 전략이 추가되더라도 기존 코드는 변경할 필요가 없어.
실행 시간에도 손쉽게 전략을 변경할 수 있어.
예를 들어 나중에 "카카오페이 결제"를 추가하고 싶다면, 아래와 같이 클래스를 하나 더 만들어서 전략만 추가하면 간단하게 확장할 수 있어:
python
복사
편집
class KakaoPayPayment(PaymentMethod):
def pay(self, amount):
return f"Paying {amount} using KakaoPay."
# 사용 예시
cart = ShoppingCart(KakaoPayPayment())
print(cart.checkout(400)) # Paying 400 using KakaoPay.
이런 방식으로 전략 패턴은 유연한 시스템 확장과 유지보수를 도와줘.
활용 예시 - Data Statistics Inspection
from abc import ABC, abstractmethod
import pandas as pd
# Abstract Base Class for Data Inspection Strategies
# --------------------------------------------------
# This class defines a common interface for data inspection strategies.
# Subclasses must implement the inspect method.
class DataInspectionStrategy(ABC):
@abstractmethod
def inspect(self, df: pd.DataFrame):
"""
Perform a specific type of data inspection.
Parameters:
df (pd.DataFrame): The dataframe on which the inspection is to be performed.
Returns:
None: This method prints the inspection results directly.
"""
pass
# Concrete Strategy for Data Types Inspection
# --------------------------------------------
# This strategy inspects the data types of each column and counts non-null values.
class DataTypesInspectionStrategy(DataInspectionStrategy):
def inspect(self, df: pd.DataFrame):
"""
Inspects and prints the data types and non-null counts of the dataframe columns.
Parameters:
df (pd.DataFrame): The dataframe to be inspected.
Returns:
None: Prints the data types and non-null counts to the console.
"""
print("\nData Types and Non-null Counts:")
print(df.info())
# Concrete Strategy for Summary Statistics Inspection
# -----------------------------------------------------
# This strategy provides summary statistics for both numerical and categorical features.
class SummaryStatisticsInspectionStrategy(DataInspectionStrategy):
def inspect(self, df: pd.DataFrame):
"""
Prints summary statistics for numerical and categorical features.
Parameters:
df (pd.DataFrame): The dataframe to be inspected.
Returns:
None: Prints summary statistics to the console.
"""
print("\nSummary Statistics (Numerical Features):")
print(df.describe())
print("\nSummary Statistics (Categorical Features):")
print(df.describe(include=["O"]))
# Context Class that uses a DataInspectionStrategy
# ------------------------------------------------
# This class allows you to switch between different data inspection strategies.
class DataInspector:
def __init__(self, strategy: DataInspectionStrategy):
"""
Initializes the DataInspector with a specific inspection strategy.
Parameters:
strategy (DataInspectionStrategy): The strategy to be used for data inspection.
Returns:
None
"""
self._strategy = strategy
def set_strategy(self, strategy: DataInspectionStrategy):
"""
Sets a new strategy for the DataInspector.
Parameters:
strategy (DataInspectionStrategy): The new strategy to be used for data inspection.
Returns:
None
"""
self._strategy = strategy
def execute_inspection(self, df: pd.DataFrame):
"""
Executes the inspection using the current strategy.
Parameters:
df (pd.DataFrame): The dataframe to be inspected.
Returns:
None: Executes the strategy's inspection method.
"""
self._strategy.inspect(df)
# Example usage
if __name__ == "__main__":
# Example usage of the DataInspector with different strategies.
# Load the data
# df = pd.read_csv('../extracted-data/your_data_file.csv')
# Initialize the Data Inspector with a specific strategy
# inspector = DataInspector(DataTypesInspectionStrategy())
# inspector.execute_inspection(df)
# Change strategy to Summary Statistics and execute
# inspector.set_strategy(SummaryStatisticsInspectionStrategy())
# inspector.execute_inspection(df)
pass
'기타 > Miscellaneous' 카테고리의 다른 글
오픈소스 AI 툴/스택/프레임워크 (0) | 2025.03.27 |
---|---|
Factory Design Pattern (2) | 2025.03.27 |
CUDA와 cuda-toolkit 버전 차이? (1) | 2024.11.21 |