본문 바로가기

Computer/Python

최소 지식의 원칙과 클래스 메소드

반응형

클래스를 이용하여 이런 저런 멤버 변수 및 인스턴스 메서드를 정의하다 보면 어떤 한 메서드에서 멤버 변수를 바뀐 것이 다른 메서드에 영향을 끼치는 경우가 많습니다. 클래스의 기능이 복잡해지고 변수가 많아질 수록 이런 경우가 종종 발생하게 되는데요, 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 로 선언된 메소드는 클래스 내부에 있는 모든 변수, 메소드에 접근이 가능한 반면, 스태틱 메소드는 파라미터로 들어오는 변수만, 클래스 메소드는 파라키터로 들어오는 변수와 클래스 변수에만 접근이 제한되어 있습니다. 따라서 클래스 메소드 / 스태틱 메소드를 이용해 접근 범위를 적게 가져갈 수록 메소드 간의 결합도가 낮아지게 되어 최소 지식의 원칙에 따른 설계가 어느 정도 가능해지며 디펜던시가 작아 유지/보수 측면에서 유리해지게 됩니다.

반응형