클래스를 이용하여 이런 저런 멤버 변수 및 인스턴스 메서드를 정의하다 보면 어떤 한 메서드에서 멤버 변수를 바뀐 것이 다른 메서드에 영향을 끼치는 경우가 많습니다. 클래스의 기능이 복잡해지고 변수가 많아질 수록 이런 경우가 종종 발생하게 되는데요, self 를 이용한 멤버 변수는 어떠한 인스턴스 메서드에서 접근 가능하다보니 이러한 가능성을 최대한 배제시킬 수 있는 설계 원칙이 필요합니다. 이때 머리 속에 담아두어야 할 것은 디미터의 법칙 혹은 최소 지식의 원칙입니다.
최소 지식의 원칙
최소 지식의 원칙은 객체 지향 구현 시 각 모듈 간의 결합도를 최소화하여 설계한다는 원칙입니다. 만일 어떤 한 메소드에 강한 결합도를 가진 변수, 다른 메소드 등이 있다면 결합도가 높은 메소드가 수정될 경우 다른 많은 곳에서 수정이 일어나야 하고 유지/보수 측면에서 매우 복잡해집니다. 즉, 메소드 간의 결합성을 낮추고 메소드가 데이터에 접근할 수 있는 액세스 범위를 줄이자는 원칙입니다. 최소 지식의 원칙에 따르면 모든 종류의 메소드는 다음에 해당하는 메소드 들만 호출이 가능합니다.
- 클래스 자기 자신의 메소드 (파이썬에서는 self로 선언된 메소드)
- 메소드의 인자로 넘어온 메소드
- 메소드 내부에서 생성된 메소드
- 클래스의 멤버 변수 및 전역 변수
파이썬에서
파이썬에서 클래스를 구현하고 이런 저런 기능을 추가하다 보면 self 로 붙은 많은 변수와 메소드들이 구현되게 됩니다. 이때 classmethod와 staticmethod를 적절히 사용하게 되면 최소 지식의 원칙을 적용할 수 있습니다.
classmethod (클래스 메소드)
클래스 메소드는 메소드 선언 시 @classmethod decorator를 붙인 메소드를 말합니다. 클래스 메소드의 중요한 특징인 일반 메소드가 self 로 시작하여 인스턴스를 첫 번째 인자로 받는 것과 달리 cls 라는 인자로 클래스 자기 자신을 전달합니다. 클래스 자기 자신을 통해 클래스 메소드 안에서 새로운 인스턴스를 생성할 수 있으며, 인스턴스가 공유하는 클래스 변수를 사용할 수 있습니다. (밑의 예제에서는 클래스 "Test" 로부터 바로 호출되나, Test 클래스의 인스턴스로부터도 호출이 가능합니다)
class Test(object):
def __init__(self, a, b):
self.a = a
self.b = b
def summation(self):
return self.a + self.b
@classmethod
def classmethod_summation(cls, a, b):
return Test(a, b)
Test.classmethod_summation(a, b)
여기서 주목해야할 점은 클래스 메소드는 self 대신 cls로 인자를 받기에 일반 인스턴스 멤버 변수에는 접근이 제한되고 static 한 클래스 변수에만 접근이 가능하다는 점입니다. 따라서 인스턴스 변수 및 메소드를 수정할 때 클래스 메소드는 영향력이 없게 되니 유지/보수 측면에서 더 편한 점이 많겠죠.
staticmethod (스태틱 메소드)
스태틱 메소드는 한 술 더떠 self, cls 모든 인자를 받지 않습니다. 메소드 선언 시 @staticmethod decorator를 붙여 선언이 가능한데, 보통 기능 상으로 클래스에 속해 있으나 클래스나 인스턴스에 종속되지 않은 함수를 구현할 때 주로 사용합니다. (저 같은 경우는 일반적인 계산 로직에 대해 스태틱 메소드를 사용합니다, 실제로 일반 함수와 거의 차이가 없는데, 클래스와의 연관성을 표현할 필요가 있을 때 주로 사용합니다) 따라서 스태틱 메소드는 self, cls 모든 인자를 받지 않기에 접근할 수 있는 변수는 메소드 인자로 받은 파라미터 뿐이라 클래스 메소드에 비해서도 변수에 대한 접근이 매우 제한됩니다.
Summary
정리하면, 일반 self 로 선언된 메소드는 클래스 내부에 있는 모든 변수, 메소드에 접근이 가능한 반면, 스태틱 메소드는 파라미터로 들어오는 변수만, 클래스 메소드는 파라키터로 들어오는 변수와 클래스 변수에만 접근이 제한되어 있습니다. 따라서 클래스 메소드 / 스태틱 메소드를 이용해 접근 범위를 적게 가져갈 수록 메소드 간의 결합도가 낮아지게 되어 최소 지식의 원칙에 따른 설계가 어느 정도 가능해지며 디펜던시가 작아 유지/보수 측면에서 유리해지게 됩니다.
'Computer > Python' 카테고리의 다른 글
프로파일링 (2) - 함수 실행 시간 계산하기 (0) | 2022.08.13 |
---|---|
프로파일링 (1) - 줄리아 집합 (Julia set) (0) | 2022.08.13 |
파이썬 dataclasses 표준 라이브러리 (3) | 2022.03.31 |
정규표현식을 이용해 문자열에서 숫자 찾기 (0) | 2022.03.25 |
Property와 descriptor (디스크립터) (0) | 2021.08.27 |