웹브라우저를 나타내는 클래스가 있다고 가정하자. 그렇다면 그 클래스 안에는 여러기능의 함수들이 있을것이다. 웹페이지를 보여준다거나, 다운로드 기능함수등등말이다.
class WebBrowser
{
public:
void clearCache();
void clearHistory();
void removeCookies();
};
한번에 처리하고싶은 사람이 있을것이다. 그러면 여기서 두가지 선택지가 있다.
1. 멤버함수로 묶어서 한번에 처리한다.
class WebBrowser
{
private:
public:
void clearEverything(); //clearCache, clearHistory,
//removeCookies를 호출한다.
};
2. 비멤버 함수로 묶어서 한번에 처리한다.
void clearBrowser(WebBrowser& wb)
{
wb.clearCache();
wb.clearHistory();
wb.removeCookies();
}
어느쪽이 괜찮은 선택이냐라 하면 비멤버 함수로 처리하는 것이 더 좋다.
비 멤버함수로 처리하면 패키지 유연성과 컴파일 의존도, 그리고 확장성을비멤버함수로 처리하면 패키지 유연성과 확장성을 높이고 컴파일 의존도를 낮추는 이점을 얻었 수 있다.
객체지향법칙에 고나련된 이야기를 찾아보면 "그 데이터를 기반으로 동작하는 함수는 한 데 묶여있어야 하며, 멤버함수가 낫다" 라고 하지만 이 같은 상황(편의 함수)에선 쓸모없는 이야기인것같다.
일단 캡슐화에 대해서 봐보자 어떤것을 캡슐화하면 밖에서 볼 수 있는 부분이 줄어들기 때문에 안에서는 유연하게 변경할 수 있다. 밖에서 볼 수 있는 범위가 "변경된것을 볼수 있는것들"이라면 말이다.
그리고 캡슐화의 정도를 높이려면 데이터 멤버에 접근할 수 있는 것들의 수를 줄여야 한다. 하지만 편의상의 이유로 멤버함수를 만들어버리면 스스로 캡슐화를 약하게 만드는것이나 다름이 없다.
이제 어떻게 하면 비멤버 함수를 더 좋게 만들 수 있는지 알아보자
두가지 방법이 있다. 파생클래스를 ㅁ나드는것과 namespace를 이용하는 것이다. 파생클래스를 만드는 것보다 namespace를 만들어서 하는것이 확장성에도 훨씬 좋으니 namespace에 대해서만 보겟다.
namespace WebBrowserStuff
{
class WebBrowser {};
void clearBrowser(WebBrowser& wb);
}
위의 코드와 같이 네임스페이스를 이용하면 컴파일 의존성도 줄일 수 있어서 좋다. 그리고 네임스페이스는 클래스와 다르게 여러개의 소스 파일로 나뉠 수 있다는 것을 이용해 다음과 같이 할 수 있다.
//webbrowser.h 헤더 -- WebBrowser클래스 자체에 대한 헤더
//그리고 WebBrowser에 관련된 "핵심" 기능들이 선언되어있음
namespace WebBrowserStuff
{
class WebBrowser {};
//"핵심" 관련 기능. 이를테면
//거의 모든 사용자가 써야 하는
//비멤버 함수들이 여기에 들어간다.
}
//"webbrowserbookmarks.h 헤더
namespace WebBrowserStuff
{
//즐겨찾기 관련 편의 함수들이
//여기에 들어간다.
}
//Webbrowsercookies.h 헤더
namespace WebBrowserStuff
{
//쿠키 관련 평의 함수들이
//여기에 들어간다.
}
이렇게 하면 확장성도 좋아진다. 만약 여기에 북마크 기능을 넣고 싶다고 하면 사이에다가 북마크 기능만 슬쩍 끼워 맞춰 주면 된다.