기능을 메서드로 정의할지 클래스로 정의할지 결정하는 것은 프로그램의 복잡성, 확장성, 그리고 설계 목표에 따라 다르다.
계산기 예제
연산을 메서드로 구현
더보기
class Calculator: def __init__(self): self.operations = { '+': self.add, '-': self.subtract, '*': self.multiply, '/': self.divide } def add(self, a, b): return a + b def subtract(self, a, b): return a - b def multiply(self, a, b): return a * b def divide(self, a, b): if b == 0: raise ValueError("Cannot divide by zero") return a / b def calculate(self, a, operator, b): if operator not in self.operations: raise ValueError(f"Unsupported operator: {operator}") return self.operations[operator](a, b) def main(): calculator = Calculator() while True: try: user_input = input("Enter calculation (e.g., 5 + 3) or 'q' to quit: ") if user_input.lower() == 'q': print("Goodbye!") break a, operator, b = user_input.split() a, b = float(a), float(b) result = calculator.calculate(a, operator, b) print(f"Result: {result}") except ValueError as e: print(f"Error: {e}") except Exception as e: print(f"An error occurred: {e}") if __name__ == "__main__": main()
연산을 클래스로 구현
더보기
from abc import ABC, abstractmethod class Operation(ABC): @abstractmethod def execute(self, a, b): pass class Addition(Operation): def execute(self, a, b): return a + b class Subtraction(Operation): def execute(self, a, b): return a - b class Multiplication(Operation): def execute(self, a, b): return a * b class Division(Operation): def execute(self, a, b): if b == 0: raise ValueError("Cannot divide by zero") return a / b class Calculator: def __init__(self): self.operations = { '+': Addition(), '-': Subtraction(), '*': Multiplication(), '/': Division() } def calculate(self, a, operator, b): if operator not in self.operations: raise ValueError(f"Unsupported operator: {operator}") return self.operations[operator].execute(a, b) def main(): calculator = Calculator() while True: try: user_input = input("Enter calculation (e.g., 5 + 3) or 'q' to quit: ") if user_input.lower() == 'q': print("Goodbye!") break a, operator, b = user_input.split() a, b = float(a), float(b) result = calculator.calculate(a, operator, b) print(f"Result: {result}") except ValueError as e: print(f"Error: {e}") except Exception as e: print(f"An error occurred: {e}") if __name__ == "__main__": main()
판단 기준
- 단일 책임 원칙:
- 하나의 기능이 독립적이고 명확한 책임을 가지고 있다면 클래스로 만드는 것이 추천된다.
- 다른 기능과 밀접하게 연관되어 있다면 메서드로 구현하는 것이 좋을 수 있다.
- 상태 관리:
- 해당 기능이 자체적인 상태(데이터)를 가지고 있어야 한다면 클래스로 만드는 것이 적합하다.
- 단순히 입력을 받아 출력을 생성하는 경우엔 메서드로 충분할 수 있다.
- 재사용성:
- 여러 곳에서 독립적으로 사용될 수 있는 기능이라면 클래스로 만드는 것이 좋다.
- 특정 컨텍스트에서만 사용되는 기능이라면 메서드로 구현할 수 있다.
- 확장성:
- 향후 기능이 확장될 가능성이 높다면 클래스로 만드는 것이 유리하다.
- 변경 가능성이 낮은 간단한 기능은 메서드로 구현해도 된다.
- 복잡성:
- 기능이 복잡하고 여러 하위 작업으로 구성된다면 클래스로 만드는 것이 관리하기 쉽다.
- 간단하고 직관적인 기능은 메서드로 충분할 수 있다.
- 다형성:
- 여러 다른 구현이 필요한 경우(예: 인터페이스나 추상 클래스를 통한 다형성) 클래스로 만드는 것이 좋다.
- 프로그램의 전체 구조:
- 프로그램의 전반적인 설계 패턴과 일관성을 유지해야 한다.
예를 들어, 계산기 예제에서:
- 간단한 프로그램이라면 첫 번째 접근법(메서드로 구현)이 충분할 수 있다.
- 더 복잡한 연산이 추가될 예정이거나, 각 연산이 자체적인 로직과 상태를 가질 필요가 있다면 두 번째 접근법(클래스로 구현)이 더 적합할 수 있다.
결국, 이는 프로그램의 요구사항, 예상되는 변경사항, 그리고 개발 팀의 선호도에 따라 결정되는 경우가 많다.
'프로그래밍 > CS 이론' 카테고리의 다른 글
Circular Queue in Python (0) | 2022.03.29 |
---|---|
Example using Stack in Python (0) | 2022.03.19 |