Item 23: 멤버 함수보다는 비멤버 비프렌드 함수와 더 가까워지자

class WebBrowser {
public:
    ...
    void clearCache();
    void clearHistory();
    void removeCookies();
    ...
};
1. 이 세 동작을 한 번에 해주는 함수를 만든다면 멤버 함수로 해야 할까? 아니면 비멤버 함수로 해야 할까?

class WebBrowser {
public:
    ...
    void clearEverything();
    ...
};

이 코드가 더 좋을까? 아니면

void clearBrower(WebBrower& wb);
{
    wb.clearCache();
    wb.clearHistory();
    wb.removeCookies();
}

이 코드가 더 좋을까?

비멤버 비프렌드 함수가 더 좋다.

  • 캡슐화면에서 더 좋다.
  • 패키징 유연성 제공
  • 컴파일 의존도를 낮추고 WebBrowser의 확장성도 높일 수 있다.
2. 캡슐화의 좋은 점은?

어떤 것을 캡슐화하면 외부에서 이것을 볼 수 없게 된다. 캡슐화하는 것이 늘면 그 만큼 밖에서 볼 수 있는 것들이 줄어든다. 밖에서 볼 수 있는 것이 줄어들면, 그것을 바꿀 때 필요한 유연성이 커진다. 왜냐하면 변경 자체가 줄 수 있는 범위가 줄어들기 때문이다. 이것이 캡슐화의 최대 장점이다.

  1. 멤버함수보다 비멤버 비프렌드 함수가 캡슐화에 더 유리한 이유는?

private 멤버는 멤버 함수 및 프렌드 함수만 접근할 수 있다. 캡슐화가 높다는 말은 데이터들을 접근할 수 있는 것들이 적다는 말이다. 그런데 비멤버 비프렌드 함수도 할 수 있는 일을 멤버함수로 만들게 되면 오히려 private 데이터에 접근할 수 있는 채널이 많아지게 된다. 즉 캡슐화가 떨어진다.

4. 이 말의 주의점은?
  • 멤버함수와 비멤버 비프렌드 함수 사이의 선택이다. 그냥 비멤버가 아니다.
  • 어떤 함수는 어떤 클래스의 비멤버가 되어야 한다는 말은 이 함수가 다른 클래스의 멤버함수가 될 수 없다는 뜻이 아니다.

즉 clearBrowser 함수가 다른 유틸리티 클래스의 정적 멤버함수로 만들어도 된다. 중요한 것은 이 함수가 WebBrowser 클래스의 멤버함수(혹은 프렌드)가 아니기만 하면된다.

5. C++에서 위 두번째 방식을 구현하는 좋은 방법은?

어떤 네임스페이스 안에 구현하는 것이다.

namespace WebBrowserStuff {
    class WebBrowser { ... };
    void clearBrowser(WebBrowser& wb);
    ...
}
  1. 네임스페이스의 장점은?

  2. 클래스와 달리 여러개의 파일에 나누어 만들 수 있다.

예를 들어 WebBrowser 클래스처럼 응용도가 높은 클래스는 편의 함수가 많이 존재할 수 있는데 이런 경우 각각의 성격에 맞는 파일들을 새로 만들고 이 파일들에서 같은 이름의 네임스페이스를 선언해서 만들면된다.

// "webBrower.h" 헤더 --- WebBrower 클래스 자체에 대한 헤더
namespace WebBrowerStuff {
class WebBrowser{ ... };
...
}

// "webbrowerbookmarks.h" 헤더
namespace WebBrowserStuff {
...                        // 즐겨찾기 관련 편의 함수
}

// "webbrowsercookies.h" 헤더
namespace WebBrowserStuff {
...                        // 쿠키 관련 편의 함수
}

표준 C++ 라이브러리가 이러한 구조로 동작한다. std 네임스페이스에 속한 모든 것들이 한 파일에 있는 것이 아니고 기능과 관련된 함수들이 수십 개의 헤더(<vector>, <algorithm>, <memory> 등) 에 흩어져 선언되어 있다.

  • 편의 함수를 여러 개의 파일에, 그러나 하나의 네임스페이스에, 나누어 두면 확장성이 쉬어진다.

해당 네임스페이스 비멤버 비프렌드 함수를 넣으면 된다.

정리

  • 멤버 함수보다는 비멤버 비프렌드 함수를 자주 쓰도록 하자. 캡슐화 정도가 높아지고, 패키징 유연성도 커지며, 기능적인 확장성도 늘어난다.

results matching ""

    No results matching ""