캡슐화란 관련있는 모든 것을 클래스 안에 묶어두는 것이다.
using namespace std;
class SinivelCap
{
public:
void Take() const { cout << "콧물약" << endl; }
};
class SneezeCap
{
public:
void Take() const { cout << "재채기약" << endl; }
};
class SnuffleCap
{
public:
void Take() const { cout << "코막힘약" << endl; }
};
class ColdPatient
{
public:
void TakeSinivelCap(const SinivelCap& cap) const { cap.Take(); }
void TakeSneezeCap(const SneezeCap& cap) const { cap.Take(); }
void TakeSnuffleCap(const SnuffleCap& cap) const { cap.Take(); }
};
위와 같은 class 들이 있다면 ColdPatient가 약을 먹는다는 기능을 할려면
int main() {
SinivelCap scap;
SneezeCap zcap;
SnuffleCap ncap;
ColdPatient sufferer;
sufferer.TakeSinivelCap(scap);
sufferer.TakeSneezeCap(zcap);
sufferer.TakeSnuffleCap(ncap);
}
위와 같이 함수호출을 해야 한다.
여기서 문제점은
- TakeCap 함수들의 호출순서가 결과에 영향을 미친다면 오류의 가능성이 높아진다.
- Cap 시리즈 함수가 변경된다면 ColdPatient 객체도 바꿔야하는 가능성이 생긴다.
using namespace std;
class SinivelCap
{
public:
void Take() const { cout << "콧물약" << endl; }
};
class SneezeCap
{
public:
void Take() const { cout << "재채기약" << endl; }
};
class SnuffleCap
{
public:
void Take() const { cout << "코막힘약" << endl; }
};
class CONTA600
{
private:
SinivelCap scap;
SneezeCap zcap;
SnuffleCap ncap;
public:
void Take(){
scap.Take();
zcap.Take();
ncap.Take();
}
}
class ColdPatient
{
public:
void TakeCONTA600(const CONTA600 &cap) const {cap.Take();}
};
위와 같이 CONTA600
으로 약을 먹는다라는 기능을 하나의 Take함수로 캡슐화를 한다면
int main() {
CONTA600 cap;
ColdPatient sufferer;
sufferer.TakeCONTA600(cap);
}
main함수에서 suffer객체는 TakeCONTA600 함수호출만 한다면 기능을 수행할 수 있다.
여기서 캡슐화의 이점은
- ColdPatient객체는 CONTA가 Take함수가 있다는 정보말고는 몰라도 된다.
- 약을 먹는다는 기능을 사용하고 싶다면 CONTA의 Take함수만 이용하면 된다.
- 만약 약을 먹는다는 기능의 구현이 변경되더라도 Take함수만 변경하면 된다.
class Point
{
private:
int xpos, ypos;
public:
void Init(int x, int y)
{
xpos = x;
ypos = y;
}
void ShowPointInfo() const
{
cout << "[" << xpos << "," << ypos << "]" << endl;
}
};
class Circle
{
private:
Point center;
int radius;
public:
int GetRadius() const {
return radius;
}
void Init(int x, int y, int radius) {
this->radius = radius;
center.Init(x, y);
}
void ShowCenter() {
center.ShowPointInfo();
}
};
class Ring
{
private:
Circle circle1;
Circle circle2;
public:
void Init(int inx, int iny, int incen, int outx, int outy, int outcen)
{
circle1.Init(inx, iny, incen);
circle2.Init(outx, outy, outcen);
}
void ShowRingInfo() {
cout << "Inner Circle Info..." << endl << "radius : " << circle1.GetRadius()<< endl;
circle1.ShowCenter();
cout << "Outer Circle Info..." << endl << "radius : " << circle2.GetRadius() << endl;
circle2.ShowCenter();
}
};
int main() {
Ring ring;
ring.Init(1, 1, 4, 2, 2, 9);
ring.ShowRingInfo();
}
보안점
Ring의 ShowRingInfo에서 GetRadius 호출 없이 ShowCircleInfo만 호출하면 되도록 만드는게 좋다. circle이 ShowCircleInfo를 구현한다는 것만 알아도 되기 때문