이번 항목에선 C++ 프로그래밍에서 사용되는 캡슐화(encapsulation)에 대한 이야기들이다. 철학적인 이야기도 나오기 때문에, 보는 중간에 졸음까지 잤었지만, 자다가 일어나서 다시 읽을 때의 신선함 때문이라도, 꽤 재미있는 항목이라 나는 생각한다.

스타일데로 캡슐화에 대한 질문들을 시작해 보자,.

1 ) "캡슐화"가 뜻하는 바는 무엇이며, 객체지향적 설계와 프로그래밍에서 그것이 얼마나 중요한가?

책에선 "캡슐화" 라는 뜻부터 풀어 보는데, 캡슐화란 "내부 구현을 숨기고 감싸서 보호하는 것" 이다. 즉, 외부와 연결된 인터페이스가 내부에 의존하지 않는다면, 클래스 내부의 변화는 외부와 연결된 인터페이스에 영향을 미치지 않음으로써, 보호 되는 것이다.


그렇다면, 객체지향적 설계와 프로그래밍에서 그것이 얼마나 중요 할까?

객체지향을 먼저 풀어 보면, "자료와 그 자료에 기반된 함수들의 결합" 으로 풀어 볼 수 있다. 캡슐화는 "내부 구현을 숨기고 감싸서 보호하는 것" 라고 위에서 정의 했었다.

여기서 객체지향을 구현 함에 있어, 캡슐화를 사용 한다는 것은, "자료나 그 자료에 기반된 함수들의 결합은 객체의 응집도(cohesion)를 높이고, 이 내부 구현을 숨기고 감싸서 보호하므로써, 내부 구현과, 외부 인터페이스의 결합도를 낮춤으로써 객체지향을 극대화" 시키는 것이다.

높은 응집도는 객체지향의 본질을 더 높여주고, 낮은 결합도는 더 자유로운 코딩을 할 수 있게 하는 것이다.

이제 이 질문에 대답할 수 있을거 같다. "객체지향의 유용성을 높이는 만큼, 중요하다"


2 ) 비정적 클래스 자료 멤버들은 어떤 경우에 어떤 접근 지시자(access specifier)로 만들어야 하는가?

우선적으로 설명되어야 하는건, 어떤 경우엔 접근 지시자 자체를 public 으로만 써야 할 때가 있다. 여러 이유가 있지만, 대부분 단순한 struct를 요구할 때이다. 이런 특별한 경우를 제외하곤, "자료 멤버는 반드시 비공개여야 한다"

만약 자료 멤버가 public 으로 된다면, 어디에선 값을 변경할 수도 있다. 이는 현실과 비교되는데, 책 내용을 그대로 인용하여 "내 배를 갈라서 내장을 주무르게 해주는 것과 같다"로 표현 될 수 있다.

가끔 외과 의사에게 수술(set 함수들)을 허용할 수 있지만, 그런 일은 자주 있지 않고, 외과 의사를 내 의지로 고른다는 점에서, public 과 크게 다르다.

결국 접근 지시자로 "public은 매우 불안하다"


그렇다면 "protected"는 어떨까?

이 역시도 불안하다. 왜냐하면, 상속된 클래스에선 무자비하게 사용 될 여지가 충분히 있기 때문이다. 클래스로 만든다는 것 자체는 "단순한 자료가 아닌, 무엇인가 행하는 객체"이기 때문에, 충분히 보호해 줄 필요가 있다.

대부분 편의상 "protected" 사용하지만, protected를 만들자고 건의했던 사람들 조차 지금은 나쁜 생각이였다고 인정한다고 한다.(Exceptional C++ Style 161 페이지에서, The Design and Evolution of C++ 에 나왔다고 함)


결국 대답은 "모든 자료는 private 지시자를 사용하고, struct의 목적이라면 public 사용하여, 만든다"


3 ) std::pair 클래스 템플릿은 캡슐화된 클래스가 아니라 그냥 자료를 묶는 수단일 뿐이기 때문에 public 자료 멤버들을 사용한다. 이와 비슷한 클래스 템플릿을 아래와 같이 만들었다.


이 예제처럼 다른 자료 멤버들은 public으로 두어되 되는가? 또는 안되나? public 과 private 자료를 섞는 것이 경우에 따라서 좋은 설계일 수 있다는 점에 대한 좋은 사례 인가?

결론을 말하자면, 좋은 사례일 수 있는 부분이 없으므로, 해서는 안된다. 쉽게 말하면, "이점이 없는 이상, private으로 반드시 두어야 한다" 라고 설명해도 좋을 듯 하다.

만약 인터페이스 없이 바로 접근한다면, 나중에 디버깅 정보의 추가나, 약간의 인터페이스 변경만으로도, 많은 곳을 수정해야 할 경우가 생길 수 있다는 단점이 이 클래스에 존재한다고 지적한다. 역시 최고의 단점은 디버깅이 어렵다는 것이 아닐까?


총평

부득이한 경우가 아니라면, private 으로 멤버 변수들을 모셔주어야 할 것으로 생각 된다. 개인적으로 protected 의 경우 쓸만하기도 한데, 예를 들자면, 특정 클래스에서만 소멸자를 호출해 주어야 하는 구조로 가야 할 경우에 요기나게 사용했었다.

하지만 몇몇 서적에서는 그럴 것이라면 friend 선언을 통해서 하는것이 보다 더 좋지 않을까? 란 글을 보게 되는데, 아직 경험이 부족해서인지 보다 더 좋은것이 무엇인지 아직 판단이 서지 않는다.



  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 라이프코리아트위터 공유하기
  • shared
  • 카카오스토리 공유하기