본문 바로가기
Language&Framework&Etc/C++

클래스의 완성(04-2) 캡슐화(Encapsulation)

by 머리올리자 2020. 12. 25.

정보은닉, 캡슐화 → 객체지향 기반의 클래스 설계에서 가장 기본적이면서도 중요한 원칙

 


캡슐화의 중요성

캡슐화가 중요한 이유

 

#include <iostream>
using namespace std;

class snivelcap // 콧물 처지용 캡슐
{
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 takesnivelcap(const snivelcap& cap) const
	{
		cap.take();
	}

	void takesneezecap(const sneezecap& cap) const
	{
		cap.take();
	}

	void takesnufflecap(const snufflecap& cap) const
	{
		cap.take();
	}
};

int main(void)
{
	snivelcap scap;
	sneezecap zcap;
	snufflecap ncap;

	coldpatient patient;

	patient.takesnivelcap(scap);
	patient.takesneezecap(zcap);
	patient.takesnufflecap(ncap);

	return 0;
}

위 예제에 다음의 내용을 가정해버리면, 캡슐화가 무너진 대표적인 사례가 된다.

 

"코감기는 항상 콧물, 재채기, 코막힘을 동반"

 

확인할 수 있는 문제점

 

복용의 절차가 너무 복잡(콧물, 재채기, 코막힘을 따로 호출), 하나의 캡슐로 만들어 놓았다면, 과정이 훨씬 간소화된다.

 

그러나 더 큰 문제는, 만약에 다음과 같은 가정을 한다면, 클래스 설계는 매우 위험한 구조

 

"약의 복용은 반드시 snivelcap, sneezecap, snufflecap 순"

 

이제 약의 복용을 위해서는 snivelcap, sneezecap, snufflecap 클래스들의 상호관계도 매우 잘 알아야 하는 상황에 놓임.

 

만약 순서가 틀어지면 부작용 초래

 

정리,

 

캡슐화가 무너지면...

객체의 활용이 매우 어려워진다.

또한, 클래스 상관관계가 복잡해지기 때문에 이는 프로그램 전체의 복잡도를 높이는 결과로 이어짐


캡슐화의 정확한 이해

 

예제

#include <iostream>
using namespace std;

class snivelcap // 콧물 처지용 캡슐
{
public:
	void take() const
	{
		cout << "콧물 치료" << endl;
	}
};

class sneezecap // 재채기 처치용 캡슐
{
public:
	void take() const
	{
		cout << "재채기 치료" << endl;
	}
};

class snufflecap // 코막힘 처치용 캡슐
{
public:
	void take() const
	{
		cout << "코막힘 치료" << endl;
	}
};

class medicine
{
private:
	snivelcap sni;
	sneezecap sne;
	snufflecap snu;

public:
	void Take() const
	{
		sni.take();
		sne.take();
		snu.take();
	}
};

class coldpatient
{
public: 
	void takemedicine(const medicine& med)
	{
		med.Take();
	}
};

int main(void)
{
	medicine cap;
	coldpatient patient;
	patient.takemedicine(cap);
	return 0;
}

캡슐화를 한다고 해서 하나의 클래스로만 모든 것을 구성해야 하는 것은 아니다.

 

다른 클래스를 활용해도 된다.

 

medicine 클래스가, snivelcap, sneezeccap, snufflecap 객체를 멤버로 둔 것처럼

 


캡슐화의 범위

관련 있는 함수와 변수를 하나의 클래스 안에 묶는 것이 캡슐화이므로, 별로 어렵게 느껴지지 않을 수 있다.

 

그러나 캡슐화는 어려운 개념이다. 왜냐하면 캡슐화의 범위를 결정하는 일이 쉽지 않기 때문

 

참고

 

  • 정보를 은닉시키기는 쉽다. 그러나 캡슐화는 어렵다.
  • 경험 많은 객체지향 프로그래머를 구분하는 첫 번째 기준은 캡슐화이다.
  • 캡슐화는 일관되게 적용할 수 있는 단순한 개념이 아니고, 구현하는 프로그램의 성격과 특성에 따라서 적용하는 범위가 달라지는, 정답이란 딱히 없는 개념이기 때문

참고

  • 캡슐화는 감싸는 개념이다.
  • 그러나 감싸려면 안전하게 감싸야 한ㅁ다.
  • 다시 말해서 이왕이면 멤버변수가 보이지 않게 정보를 은닉해서 감싸는 것이 좋다.
  • 그래서 캡슐화는 기본적으로 정보은닉을 포함하는 개념이라고도 이야기 한다.

참고 : [윤성우 열혈 C++ 프로그래밍] - 대부분의 내용 및 코드는 이 책에서 개인 공부 정리 목적으로 참고하였습니다.