대학에서 C ++을 배울 때 강사와 비슷한 주장을했던 것을 기억합니다. 변수를 공개 할 수있을 때 게터와 세터를 사용하는 요점을 알 수 없었습니다. 나는 수년간의 경험을 통해 더 잘 이해하고 있으며 단순히 캡슐화를 유지하는 것보다 더 나은 이유를 배웠습니다.
게터와 세터를 정의함으로써 구현을 변경하고 싶을 때 의존 코드를 깰 가능성이 없도록 일관된 인터페이스를 제공하게됩니다. 이는 수업이 API를 통해 노출되고 다른 앱이나 타사에서 사용될 때 특히 중요합니다. 게터 나 세터에 들어가는 것은 어떻습니까?
게터는 일반적으로 행동을 예측할 수 있기 때문에 값에 액세스하기위한 단순한 바보 같은 패스 스루로 구현하는 것이 좋습니다. 필자는 일반적으로 게터가 계산이나 조건부 코드로 조작 된 값에 액세스하는 데 사용 된 사례를 보았 기 때문에 일반적으로 말합니다. 일반적으로 디자인 타임에 사용할 시각적 구성 요소를 만드는 것은 좋지 않지만 런타임에는 편리해 보입니다. 그러나 메소드를 사용할 때 코드를 읽을 때 "getter"의 기능이 더 명확 해 지도록 메소드의 이름을 더 적절하게 지정할 수 있다는 점을 제외하면이 메소드와 간단한 메소드를 사용하는 것 사이에는 실질적인 차이가 없습니다.
다음을 비교하십시오.
int aValue = MyClass.Value;
과
int aValue = MyClass.CalculateValue();
두 번째 옵션을 사용하면 값이 계산되고 있음을 알 수 있지만 첫 번째 예에서는 값 자체에 대해 전혀 몰라도 값을 반환하고 있음을 나타냅니다.
다음이 더 명확 할 것이라고 주장 할 수 있습니다.
int aValue = MyClass.CalculatedValue;
그러나 문제는 값이 이미 다른 곳에서 조작되었다고 가정한다는 것입니다. 따라서 getter의 경우 값을 반환 할 때 다른 일이 진행되고 있다고 가정 할 수 있지만 속성의 맥락에서 그러한 것을 명확하게하는 것은 어렵고 속성 이름에는 동사가 포함되어서는 안됩니다 그렇지 않으면 액세스 할 때 사용 된 이름을 괄호로 장식해야하는지 한 눈에 알기가 어렵습니다.
세터는 약간 다른 경우입니다. 값을 설정하면 속성의 정의 된 경계를 위반하는 경우 예외가 발생하여 속성에 제출되는 데이터의 유효성을 검사하기 위해 세터가 추가 처리를 제공하는 것이 전적으로 적절합니다. 그러나 일부 개발자가 세터에 처리를 추가 할 때의 문제점은 세터가 어떤 방식으로 데이터를 계산하거나 조작하는 것과 같이 세터가 조금 더 노력을 기울여야한다는 유혹이 항상 있다는 것입니다. 여기에서 어떤 경우에는 예측할 수 없거나 바람직하지 않은 부작용을 얻을 수 있습니다.
세터의 경우 항상 간단한 경험 법칙을 적용합니다. 예를 들어, 일반적으로 경계 테스트와 반올림을 허용하여 적절한 경우 예외를 발생 시키거나 불필요한 예외를 피할 수있는 예외를 피할 수 있습니다. 부동 소수점 속성은 예외가 발생하지 않도록 과도한 소수 자릿수를 반올림하고 소수의 소수 자릿수로 범위 값을 입력 할 수있는 좋은 예입니다.
setter 입력에 일종의 조작을 적용하는 경우 getter와 같은 문제가 있으므로 다른 사람이 단순히 setter의 이름을 지정하여 setter가 수행하는 작업을 알기가 어렵습니다. 예를 들면 다음과 같습니다.
MyClass.Value = 12345;
이것이 세터에게 주어질 때 그 가치에 어떤 일이 일어날 지에 대해 말해 주는가?
어때요 :
MyClass.RoundValueToNearestThousand(12345);
두 번째 예는 데이터에 어떤 일이 일어날 지 정확하게 알려주는 반면 첫 번째 예는 가치가 임의로 수정 될 것인지 여부를 알려주지 않습니다. 코드를 읽을 때 두 번째 예는 목적과 기능이 훨씬 명확합니다.
이것이 처음에는 게터와 세터를 갖는 목적을 완전히 잃고 검증과 다른 논리 (이상한 부작용없이)가 허용되어야한다는 것이 맞습니까?
getter와 setter를 갖는 것은 "순도"를위한 캡슐화에 관한 것이 아니라 클래스의 인터페이스를 변경하지 않고도 코드를 쉽게 리팩터링하여 클래스의 호출 코드와의 호환성을 손상시킬 수 있도록 캡슐화에 관한 것입니다. 유효성 검사는 세터에서 전적으로 적합하지만 호출 코드가 특정 방식으로 발생하는 유효성 검사에 의존하는 경우 유효성 검사 변경으로 인해 호출 코드와의 호환성이 손상 될 위험이 적습니다. 이것은 일반적으로 드물고 상대적으로 위험이 낮은 상황이지만 완전성을 위해 주목해야합니다.
언제 검증이 이루어져야합니까?
실제로 값을 설정하기 전에 setter 컨텍스트 내에서 유효성 검증이 수행되어야합니다. 이를 통해 예외가 발생하면 객체의 상태가 변경되지 않고 데이터가 무효화 될 수 있습니다. 일반적으로 setter 코드를 비교적 깔끔하게 유지하기 위해 setter 내에서 가장 먼저 호출되는 별도의 메서드에 유효성 검사를 위임하는 것이 좋습니다.
세터가 값을 변경할 수 있습니까 (유효한 값을 표준 내부 표현으로 변환 할 수 있습니까)?
아주 드문 경우 일 수 있습니다. 일반적으로 그렇지 않은 것이 좋습니다. 이것은 다른 방법에 가장 적합한 종류입니다.