맨위로가기

캡슐화

"오늘의AI위키"는 AI 기술로 일관성 있고 체계적인 최신 지식을 제공하는 혁신 플랫폼입니다.
"오늘의AI위키"의 AI를 통해 더욱 풍부하고 폭넓은 지식 경험을 누리세요.

1. 개요

캡슐화는 객체 지향 프로그래밍 및 관련 분야에서 사용되는 개념으로, 객체의 구성 요소에 대한 직접 접근을 제한하거나 데이터와 해당 데이터를 조작하는 메서드를 묶는 것을 의미한다. 이는 정보 은닉과 밀접하게 관련되어 있으며, 객체의 내부 표현을 숨겨 데이터의 무결성을 보호하고 시스템의 복잡성을 줄이는 데 기여한다. C++, C#, Java 등과 같은 언어는 접근 지정자를 통해 캡슐화를 지원하며, 파이썬은 이름 맹글링과 같은 관례를 통해 유사한 기능을 제공한다. 또한 디지털 아카이빙 분야에서 캡슐화는 디지털 문헌의 원본과 보존 메타데이터를 함께 보존하는 방식으로 사용되며, 구조적 프로그래밍에서도 알고리즘과 데이터 구조를 묶어 모듈화하는 개념으로 활용된다.

더 읽어볼만한 페이지

  • 기록학 - 기록관
    기록관은 공공기록물 관리에 관한 법률에 따라 설치된 기록물 관리 기관으로, 기관별 고유한 역할을 수행하며 효율적인 기록물 관리 시스템 구축을 위해 협력하고, 특히 특수기록관은 민감한 정보를 다루므로 엄격한 보안 및 관리 체계가 요구된다.
  • 기록학 - 기록연속성
    기록연속성(RCM)은 현대 기록 관리, 규제 기록 관리, 역사 기록 관리를 포괄하는 모델로, 정책, 시스템, 조직, 법률, 사회적 위임을 통해 기록 보존 담당자와 기록 관리자가 기록을 평가하는 방식을 제시하며 기록 관리 활동을 네 가지 축으로 설명하고 기록 관리의 가치를 조명한다.
  • 객체 지향 프로그래밍 - Is-a
    Is-a 관계는 객체 지향 프로그래밍에서 한 유형이 다른 유형의 하위 유형임을 나타내는 관계로, 상속, 서브타이핑, 리스코프 치환 원칙과 관련되며, C++, Python, Java 등에서 표현된다.
  • 객체 지향 프로그래밍 - 객체 (컴퓨터 과학)
    객체는 객체 지향 프로그래밍에서 데이터와 조작을 묶어 메시지를 수신하고, 프로그램의 개념을 표현하며 가시성과 재사용성을 높이는 실체이다.
캡슐화
정보 은닉
정의객체 지향 프로그래밍에서 객체의 내부 데이터와 구현 세부 사항을 외부로부터 숨기고, 객체의 메서드를 통해서만 접근하도록 제한하는 것
목적데이터 무결성 유지, 코드 유지보수 용이성 향상, 시스템 복잡성 감소
구현 방법접근 제한자 (예: private, protected) 사용
관련 개념추상화
모듈화
객체 지향 프로그래밍
장점
데이터 보호외부에서의 직접적인 데이터 접근 및 수정 방지
코드 유지보수내부 구현 변경 시 외부 코드에 미치는 영향 최소화
모듈화시스템을 독립적인 모듈로 분리하여 복잡성 감소
유연성객체 내부 로직 변경이 용이
단점
성능 저하 가능성메서드 호출을 통한 간접 접근으로 인한 오버헤드 발생 가능성
설계 복잡성 증가정보 은닉을 위한 추가적인 설계 고려 필요
예시
캡슐화 예시은행 계좌 객체에서 잔액 정보를 직접 접근하지 못하도록 private으로 선언하고, 입금/출금 메서드를 통해서만 접근하도록 구현
관련 용어
접근 제한자공개 (public)
보호 (protected)
비공개 (private)
게터 (Getter) / 세터 (Setter)객체의 속성에 접근하고 수정하기 위한 메서드 (접근자/설정자)
정보 은닉 (Information Hiding)객체의 내부 구현을 숨기고 필요한 인터페이스만 외부에 제공하는 것
언어별 지원
지원 언어자바 (Java)
C++
C 샤프 (C#)
파이썬 (Python)
기타
주의사항과도한 캡슐화는 코드의 가독성을 저해할 수 있으므로 적절한 수준에서 적용하는 것이 중요함

2. 캡슐화의 의미

객체 지향 프로그래밍 언어 및 관련 분야에서 캡슐화(캡슐화)는 서로 관련 있으면서도 구별되는 두 가지 개념, 또는 이 둘의 조합을 의미한다.[4][5]

첫 번째 의미는 객체의 특정 구성 요소에 대한 직접적인 접근을 제한하는 언어 메커니즘을 가리킨다.[6][7] 이는 정보 은닉과 밀접하게 관련된 개념으로, 객체 내부의 상태를 보호하고 외부로부터의 임의적인 수정을 방지하는 데 목적이 있다.

두 번째 의미는 데이터와 그 데이터를 처리하는 메서드(또는 다른 함수)를 하나로 묶는 것을 용이하게 하는 언어 구조를 의미한다.[8][9] 이 관점에서는 데이터와 관련 로직을 하나의 단위로 관리하여 코드의 구조화와 응집력을 높이는 데 초점을 맞춘다. 많은 객체 지향 언어에서는 이 방식을 통해 클래스를 정의하며, 구성 요소가 반드시 숨겨지는 것은 아니고 필요에 따라 외부에서 접근하거나 재정의(override)될 수 있다. 따라서 이 두 번째 정의를 선호하는 사람들은 정보 은닉을 캡슐화와는 별개의 개념으로 보기도 한다.

일부 프로그래밍 언어 연구자들은 첫 번째 의미(접근 제한)만을 캡슐화로 보거나, 두 의미를 결합하여 객체 지향 프로그래밍의 핵심 특징 중 하나로 간주한다. 반면, 렉시컬 클로저를 지원하는 언어에서는 캡슐화를 객체 지향과는 직교하는 언어의 특징으로 여기기도 한다.

캡슐화 기능은 대부분의 객체 지향 언어에서 클래스를 통해 지원되지만, 다른 대안적인 구현 방식도 존재한다.

또한, 캡슐화는 반복적이거나 복잡한 프로세스를 하나의 단위로 묶어 호출할 수 있도록 만드는 것을 의미하기도 한다. 이는 객체 지향 프로그래밍의 메서드나 클래스 수준에서 잘 나타나지만, 절차적 프로그래밍에서도 함수 등을 통해 유사한 개념을 적용할 수 있다.[10]

2. 1. 정보 은닉

객체 지향 프로그래밍에서 정보 은닉(Information hiding)은 캡슐화의 중요한 개념 중 하나로, 객체의 내부 상태나 구현 세부 사항을 외부로부터 숨기는 것을 의미한다.[4][5] 이는 객체의 구성 요소에 대한 직접적인 접근을 제한하는 언어 메커니즘을 통해 이루어진다.[6][7]

정보 은닉의 주된 목적은 객체의 내부 데이터를 보호하여 무결성을 유지하고, 외부에서 객체의 내부 상태를 직접 조작하여 발생할 수 있는 예기치 않은 오류나 비일관된 상태를 방지하는 데 있다. 객체의 내부 구현이 변경되더라도 외부에 노출된 인터페이스만 동일하게 유지된다면, 해당 객체를 사용하는 다른 코드에 미치는 영향을 최소화할 수 있다. 이를 통해 소프트웨어 구성 요소 간의 의존성을 낮추고 시스템 전체의 복잡성을 줄이며 강건성을 높일 수 있다.

대부분의 객체 지향 언어들은 정보 은닉을 지원하기 위해 접근 지정자(Access Specifier) 또는 접근 제한자(Access Modifier)라는 키워드를 제공한다. 대표적인 접근 지정자로는 `public`, `private`, `protected` 등이 있으며, 이를 통해 클래스의 멤버 변수나 메서드에 대한 접근 권한을 제어할 수 있다.[7]

  • `public`: 어떤 클래스에서든 접근할 수 있다.
  • `private`: 해당 클래스 내부에서만 접근할 수 있다.
  • `protected`: 해당 클래스 내부 또는 상속받은 하위 클래스에서만 접근할 수 있다.


C++, C#, 자바, 델파이 등 많은 언어가 이러한 접근 지정자를 통해 프로그래머가 정보 은닉의 수준을 제어할 수 있도록 지원한다. 반면, 스몰토크루비와 같은 일부 언어는 기본적으로 모든 인스턴스 변수를 비공개(private)로 취급하고 오직 객체의 메서드를 통해서만 접근하도록 강제하기도 한다.

하지만 대부분의 언어에서는 리플렉션 API를 사용하거나, 파이썬의 이름 맹글링 기법, C++의 `friend` 키워드 등을 통해 이러한 접근 제한을 우회할 수 있는 방법을 제공하기도 한다.

정보 은닉 개념은 객체 지향 언어에만 국한되지 않는다. 예를 들어, C 언어에서는 헤더 파일에 구조체의 선언만 노출하고 실제 정의는 소스 파일 내부에 숨기는 방식으로 불투명 자료형을 구현하여 정보 은닉을 달성할 수 있다.[12] 이 경우, 외부 모듈은 제공된 함수 API를 통해서만 해당 데이터 구조를 조작할 수 있으며 내부 구현에 직접 접근할 수 없다.

2. 1. 1. C++ 에서의 접근 지정자

C++ 언어에서는 정보 은닉을 위해 접근 지정자를 사용한다. 접근 지정자는 클래스의 멤버 변수나 멤버 함수에 대한 외부 접근을 제어하는 키워드이다.

C++에서 사용하는 주요 접근 지정자는 다음과 같다.

접근 지정자설명
`private`해당 멤버에 대한 접근을 자기 클래스 내부의 메서드로만 제한한다. 외부에서는 직접 접근할 수 없다.
`protected`해당 멤버에 대한 접근을 자기 클래스 내부 또는 해당 클래스를 상속받은 자식 클래스에서만 허용한다.
`public`해당 멤버에 대한 접근을 어디서든 허용한다. 클래스 외부에서도 자유롭게 접근할 수 있다.



일반적으로 클래스의 데이터 멤버는 `private` 또는 `protected`로 선언하여 외부로부터의 직접적인 접근을 막고, 데이터의 무결성을 보호한다. 이렇게 접근이 제한된 데이터를 변경하거나 조회해야 할 경우에는 `public`으로 선언된 메서드(접근자/설정자 메서드 등)를 통해 간접적으로 상호작용하도록 설계한다.

아래는 C++에서 접근 지정자를 사용하는 예시 코드이다.



class Car {

// 데이터 필드 ///////////////

public: // 지금부터 선언되는 멤버변수와 함수는 모두 접근 허용.

int year;

char maker[50];

protected: // 지금부터 선언되는 멤버변수와 함수는 자기 클래스와 상속 클래스에서만 접근 허용.

int capEngine;

private: // 지금부터 선언되는 멤버변수와 함수는 자기 클래스에서만 접근 허용.

char ecu[20];

char colorCode[30];

/// 메서드 ///////////////////////////////////

public:

// 생성자는 일반적으로 외부에서 객체를 생성해야 하므로 public으로 선언한다.

Car() { }

// 소멸자도 public으로 선언하는 것이 일반적이다.

~Car() { }

// public 메서드를 통해 외부에서 데이터에 접근할 수 있도록 한다.

int getMkYear() { return year; } // public 멤버 변수 year에 접근

int getCapEngine() { return capEngine; } // protected 멤버 변수 capEngine에 접근

protected: // 자기 클래스 내부와 상속클래스에서 접근 허용한다.

// protected 메서드는 상속 관계에서 활용될 수 있다.

char* getEcuType() { return ecu; } // private 멤버 변수 ecu에 접근

char* getColorCode() { return colorCode; } // private 멤버 변수 colorCode에 접근

// ....

};



위 코드에서 `year`와 `maker`는 `public`이므로 외부에서 직접 접근할 수 있다. 반면 `capEngine`은 `protected`이므로 `Car` 클래스 내부 또는 `Car`를 상속받는 클래스에서만 접근 가능하며, `ecu`와 `colorCode`는 `private`이므로 오직 `Car` 클래스 내부에서만 접근할 수 있다. 외부에서는 `getMkYear()`, `getCapEngine()`과 같은 `public` 메서드를 통해서만 해당 정보에 접근할 수 있다.

2. 1. 2. C#, Java 에서의 접근 제한

C#, Java와 같은 여러 객체 지향 프로그래밍 언어들은 클래스 멤버에 대한 접근을 제어하는 기능을 제공한다. 이는 주로 `public`, `private`과 같은 접근 지정자 키워드를 사용하여 구현된다.[7] 이러한 접근 제어를 통해 정보 은닉을 실현하여 객체 내부 데이터의 무결성을 보호하고, 시스템의 복잡성을 줄이며 강건성을 높일 수 있다.

캡슐화를 나타내는 UML 다이어그램


다음은 C#에서 `private` 키워드를 사용하여 데이터 필드에 대한 접근을 제한하는 방법을 보여주는 예시이다. `_accountBalance` 필드는 `private`으로 선언되어 클래스 외부에서 직접 접근할 수 없으며, 오직 `public`으로 선언된 `CheckBalance` 메서드를 통해서만 접근이 가능하다.



class Program

{

public class Account

{

private decimal _accountBalance = 500.00m; // private 필드로 외부 접근 제한

public decimal CheckBalance() // public 메서드를 통해 잔액 확인 가능

{

return _accountBalance;

}

}

static void Main()

{

Account myAccount = new Account();

decimal myBalance = myAccount.CheckBalance(); // CheckBalance 메서드를 통해 접근

/* Main 메서드는 Account 클래스의 public 메서드 CheckBalance를 통해

  • 잔액을 확인할 수 있지만, private 필드인 _accountBalance의 값을
  • 직접 조작할 수는 없다. */

}

}



Java에서도 비슷한 방식으로 캡슐화를 구현한다. 아래 예시에서 `salary` 필드는 `private`으로 선언되어 외부 접근이 차단되고, `public` 메서드인 `getSalary`를 통해서만 값을 얻을 수 있다.



import java.math.BigDecimal;

public class Employee {

private BigDecimal salary = new BigDecimal(50000.00); // private 필드

public BigDecimal getSalary() { // public getter 메서드

return this.salary;

}

public static void main(String[] args) {

Employee e = new Employee();

BigDecimal sal = e.getSalary(); // getter 메서드를 통해 접근

System.out.println("Employee Salary: " + sal); // 예시 출력

}

}


2. 1. 3. 파이썬에서의 이름 맹글링

파이썬은 C++자바와 같은 언어에서 사용되는 `public`, `private`과 같은 명시적인 접근 지정자를 통해 변수 접근 제한을 강제하는 기능을 제공하지 않는다. 대신, 이름 맹글링(Name Mangling)이라는 메커니즘과 프로그래밍 관례를 통해 정보 은닉의 효과를 얻는다.

일반적으로 파이썬에서는 밑줄(`_`)로 시작하는 변수나 메서드는 클래스 외부에서 직접 접근하지 않아야 하는 비공개(private) 멤버로 간주하는 관례가 있다. 이는 강제적인 제한이 아니므로 기술적으로는 외부 접근이 가능하지만, 개발자 간의 약속으로 내부 구현에 해당함을 나타낸다.[13]

다음은 파이썬에서 밑줄 관례를 사용한 예시이다.



class Car:

def __init__(self) -> None:

self._maxspeed = 200 # 밑줄(_)로 시작하여 비공개처럼 취급되는 변수

def drive(self) -> None:

print(f"Maximum speed is {self._maxspeed}.")

redcar = Car()

redcar.drive() # 출력: 'Maximum speed is 200.'

# 관례상 권장되지 않지만, 외부에서 직접 접근 및 수정이 가능하다.

redcar._maxspeed = 10

redcar.drive() # 출력: 'Maximum speed is 10.'



이처럼 파이썬의 이름 맹글링이나 밑줄 관례는 완전한 정보 은닉을 보장하기보다는, 해당 멤버가 클래스 내부용임을 알려주고 외부에서의 직접적인 사용을 지양하도록 유도하는 역할을 한다.

2. 2. 캡슐화와 상속

디자인 패턴의 저자들은 상속과 캡슐화 사이의 관계에 대해 상세히 논의한다. 그들은 경험적으로 프로그래밍 설계자들이 상속을 지나치게 많이 사용하는 경향이 있다고 지적한다. 상속은 하위 클래스에게 부모 클래스 구현의 세부적인 내용을 노출시키기 때문에, 종종 캡슐화를 깨뜨릴 수 있다고 주장한다.[11] 요요 문제에서 설명하는 것처럼, 상속을 과도하게 사용하면 캡슐화가 깨지고 프로그램 구조가 너무 복잡해져서 디버깅이 어려워질 수 있다.

3. 디지털 아카이빙에서의 캡슐화

디지털 아카이빙 분야에서 캡슐화는 디지털 문헌의 원본을 그대로 유지하며 원본을 해석하는 데 필요한 세부 절차에 관한 정보, 즉 보존 메타데이터를 함께 보존하는 방식을 의미한다. 이는 보존처리 기술 방식의 하나이다.[25]

4. 구조적 프로그래밍과 캡슐화

객체 지향 프로그래밍 언어 및 관련 분야에서 캡슐화는 서로 관련이 있지만 구별되는 두 가지 개념 중 하나 또는 둘의 조합을 의미한다.[4][5]

첫째는 일부 객체의 구성 요소에 대한 직접 접근을 제한하는 언어 메커니즘이다.[6][7] 둘째는 해당 데이터에 대해 작동하는 메서드 (또는 다른 함수)와 데이터를 함께 묶는 것을 용이하게 하는 언어 구조이다.[8][9]

일부 프로그래밍 언어 연구자 및 학자들은 첫 번째 의미만을 사용하거나 두 번째 의미와 결합하여 캡슐화를 객체 지향 프로그래밍의 특징으로 간주한다. 반면, 렉시컬 클로저를 제공하는 일부 프로그래밍 언어에서는 캡슐화를 객체 지향과는 직교하는, 즉 독립적인 언어의 특징으로 간주한다.

두 번째 정의는 많은 객체 지향 언어에서 구성 요소가 자동으로 숨겨지지 않으며 이를 재정의할 수 있다는 점을 반영한다. 따라서 이 정의를 따르는 경우, 정보 은닉은 캡슐화와는 별개의 개념으로 정의된다.

캡슐화의 기능은 대부분의 객체 지향 언어에서 클래스를 사용하여 지원되지만, 다른 대안적인 방법들도 존재한다.

캡슐화는 반복적이거나 복잡한 프로세스를 호출할 수 있는 단일 단위로 포함하는 것을 의미할 수도 있다. 객체 지향 프로그래밍은 메서드 및 클래스 수준에서 이를 용이하게 하며, 이러한 정의는 절차적 프로그래밍에도 적용될 수 있다.[10]

5. 정보 은닉의 중요성

캡슐화는 데이터 멤버와 멤버 함수를 외부로부터 숨기는 데 사용될 수 있으며, 이는 정보 은닉이라는 중요한 개념과 밀접하게 연관된다. 정보 은닉은 객체의 내부 상태(데이터)를 외부에서 직접 접근하거나 수정하지 못하도록 보호하는 것을 목표로 한다.[6][7] 일반적으로 객체 자신의 메서드를 통해서만 내부 데이터에 접근하고 조작할 수 있도록 제한한다.

이렇게 객체 내부를 숨기는 것은 여러 가지 중요한 장점을 가진다.


  • 데이터 무결성 보호: 외부에서 객체 내부 데이터를 임의로 변경하여 유효하지 않거나 일관성 없는 상태로 만드는 것을 방지한다.
  • 복잡성 감소: 소프트웨어 구성 요소 간의 불필요한 의존성을 줄여 시스템 전체의 복잡성을 낮춘다.
  • 강건성 향상: 예기치 않은 오류 발생 가능성을 줄여 프로그램이 오류에 잘 견디도록(강건성) 만든다.


대부분의 객체 지향 프로그래밍 언어는 클래스를 통해 정보 은닉을 지원한다. C++, C#, 델파이, 자바와 같은 언어들은 프로그래머가 정보 은닉의 수준을 제어할 수 있도록 public(공개), private(비공개), protected(보호)와 같은 접근 지정자 키워드를 제공한다.[7] 예를 들어, private으로 선언된 멤버는 해당 클래스 내부에서만 접근할 수 있다. 반면, 스몰토크루비 같은 언어는 기본적으로 모든 내부 상태를 숨기고 오직 메서드를 통해서만 접근하도록 강제하는 경향이 있다.

C++의 경우, ISO 표준에서는 protected, private, public을 단순히 "접근 지정자"로 정의하며, 이것 자체가 정보를 완전히 숨기는 것은 아니라고 설명한다. 실제 정보 은닉은 헤더 파일을 통해 인터페이스만을 공개하고, 구현 세부 사항이 담긴 소스 코드는 컴파일된 형태로 제공하는 방식으로 이루어지기도 한다.

하지만 대부분의 언어에서는 리플렉션 API(루비, 자바, C# 등), 이름 맹글링(파이썬), 또는 C++friend 키워드처럼 이러한 접근 제한을 우회할 수 있는 방법을 제공한다. 예외적으로, 객체 역량 모델을 따르는 시스템은 외부의 임의 접근을 원천적으로 차단하여 강력한 캡슐화를 보장한다.

참조

[1] 웹사이트 What is Object-Oriented Programming (OOP)? https://www.techtarg[...] 2024-03-02
[2] 웹사이트 Encapsulation in Object Oriented Programming (OOPS) https://www.enjoyalg[...] 2024-03-02
[3] 기타
[4] 서적 Programming language pragmatics Morgan Kaufmann
[5] 서적 Programming and problem solving with Java Jones & Bartlett
[6] 서적 Concepts in programming languages Cambridge University Press
[7] 서적 Types and Programming Languages MIT Press
[8] 웹사이트 Encapsulation is not information hiding https://www.infoworl[...] 2020-07-20
[9] 서적 Database systems: a practical approach to design, implementation, and management Pearson Education
[10] 서적 Object-Oriented Design with ABAP: A Practical Approach "[[Apress]]" 2017
[11] 서적 Design Patterns https://archive.org/[...] Addison-Wesley 1994
[12] 서적 C Programming: A Modern Approach W. W. Norton & Company 2008
[13] 웹사이트 The Meaning of Underscores in Python https://dbader.org/b[...] 2019-11-01
[14] 서적 プリンシプル オブ プログラミング 3年目までに身につけたい 一生役立つ101の原理原則 秀和システム 2016-03-29
[15] 서적 プリンシプル オブ プログラミング 3年目までに身につけたい 一生役立つ101の原理原則 秀和システム 2016-03-29
[16] 문서 구조화프로그래밍
[17] 문서 구조화프로그래밍
[18] 문서 산崎(1990)
[19] 기타 Programming language pragmatics Morgan Kaufmann
[20] 기타 Programming and problem solving with Java Jones & Bartlett Publishers
[21] 웹사이트 Encapsulation is not information hiding http://www.javaworld[...] 2001-05-18
[22] 기타 Database systems: a practical approach to design, implementation, and management Pearson Education
[23] 서적 Concepts in programming languages Cambridge University Press
[24] 서적 Types and Programming Languages MIT Press
[25] 웹인용 한국도서관협회 문헌정보학용어사전 - 캡슐화 https://www.kla.kr/j[...] null



본 사이트는 AI가 위키백과와 뉴스 기사,정부 간행물,학술 논문등을 바탕으로 정보를 가공하여 제공하는 백과사전형 서비스입니다.
모든 문서는 AI에 의해 자동 생성되며, CC BY-SA 4.0 라이선스에 따라 이용할 수 있습니다.
하지만, 위키백과나 뉴스 기사 자체에 오류, 부정확한 정보, 또는 가짜 뉴스가 포함될 수 있으며, AI는 이러한 내용을 완벽하게 걸러내지 못할 수 있습니다.
따라서 제공되는 정보에 일부 오류나 편향이 있을 수 있으므로, 중요한 정보는 반드시 다른 출처를 통해 교차 검증하시기 바랍니다.

문의하기 : help@durumis.com