본문 바로가기

프로그래밍/CS 이론

메서드 vs 클래스

기능을 메서드로 정의할지 클래스로 정의할지 결정하는 것은 프로그램의 복잡성, 확장성, 그리고 설계 목표에 따라 다르다. 

계산기 예제

연산을 메서드로 구현

더보기
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()

판단 기준

  1. 단일 책임 원칙:
    • 하나의 기능이 독립적이고 명확한 책임을 가지고 있다면 클래스로 만드는 것이 추천된다.
    • 다른 기능과 밀접하게 연관되어 있다면 메서드로 구현하는 것이 좋을 수 있다.
  2. 상태 관리:
    • 해당 기능이 자체적인 상태(데이터)를 가지고 있어야 한다면 클래스로 만드는 것이 적합하다.
    • 단순히 입력을 받아 출력을 생성하는 경우엔 메서드로 충분할 수 있다.
  3. 재사용성:
    • 여러 곳에서 독립적으로 사용될 수 있는 기능이라면 클래스로 만드는 것이 좋다.
    • 특정 컨텍스트에서만 사용되는 기능이라면 메서드로 구현할 수 있다.
  4. 확장성:
    • 향후 기능이 확장될 가능성이 높다면 클래스로 만드는 것이 유리하다.
    • 변경 가능성이 낮은 간단한 기능은 메서드로 구현해도 된다.
  5. 복잡성:
    • 기능이 복잡하고 여러 하위 작업으로 구성된다면 클래스로 만드는 것이 관리하기 쉽다.
    • 간단하고 직관적인 기능은 메서드로 충분할 수 있다.
  6. 다형성:
    • 여러 다른 구현이 필요한 경우(예: 인터페이스나 추상 클래스를 통한 다형성) 클래스로 만드는 것이 좋다.
  7. 프로그램의 전체 구조:
    • 프로그램의 전반적인 설계 패턴과 일관성을 유지해야 한다.

예를 들어, 계산기 예제에서:

  • 간단한 프로그램이라면 첫 번째 접근법(메서드로 구현)이 충분할 수 있다.
  • 더 복잡한 연산이 추가될 예정이거나, 각 연산이 자체적인 로직과 상태를 가질 필요가 있다면 두 번째 접근법(클래스로 구현)이 더 적합할 수 있다.

결국, 이는 프로그램의 요구사항, 예상되는 변경사항, 그리고 개발 팀의 선호도에 따라 결정되는 경우가 많다.

'프로그래밍 > CS 이론' 카테고리의 다른 글

Circular Queue in Python  (0) 2022.03.29
Example using Stack in Python  (0) 2022.03.19