정보 은닉과 경계 설정
모듈화 설계에서 정보 은닉Information Hiding과 경계 설정은 시스템의 유지보수성, 확장성을 높이는 중요한 원칙입니다. 정보 은닉은 객체의 세부 구현을 감추고, 외부에 노출되는 인터페이스를 통해 상호작용함으로써 모듈 간 의존성을 최소화합니다. 경계 설정은 각 모듈이 독립적으로 변화할 수 있도록 경계를 명확하게 구분하고, 불필요한 결합을 방지하는 설계 전략입니다. 이 글에서는 정보 은닉을 중심으로 모듈 경계를 설정하고 관리하는 방법을 실무적 관점에서 설명합니다.
정보 은닉
정보 은닉Information Hiding은 객체의 내부 구현을 외부에서 볼 수 없도록 숨기고, 필요한 정보인터페이스만 외부에 제공하는 원칙입니다. 이를 통해 모듈 간 불필요한 의존성을 줄이고, 각 모듈의 독립성을 유지할 수 있습니다. 정보 은닉은 객체지향 설계에서 내부 구현과 외부 인터페이스를 분리함으로써, 시스템의 복잡성을 줄이고 유지보수성을 향상시킵니다.
정보 은닉과 캡슐화의 차이
정보 은닉Information Hiding과 캡슐화는 객체지향 설계에서 자주 혼용되지만, 서로 다른 개념입니다. 두 개념은 상호 보완적인 관계에 있으며, 시스템의 복잡성을 줄이고 유지보수성을 높이는 데 중요한 역할을 합니다. 각각의 차이점과 역할을 명확히 이해하는 것이 객체지향 설계를 효율적으로 적용하는 데 필요합니다.
캡슐화
캡슐화Encapsulation는 객체의 속성과 메서드를 하나의 단위로 묶어 외부에서 객체 내부에 직접 접근하지 못하게 보호하는 개념입니다. 캡슐화는 주로 데이터 보호에 중점을 두며, 객체의 상태(데이터)를 외부에서 직접 수정할 수 없도록 하고, 오직 객체 내부의 메서드를 통해서만 접근하게 합니다. 즉, 캡슐화는 데이터의 무결성을 유지하고, 객체가 의도치 않게 잘못 사용되는 것을 방지합니다.
정보 은닉
정보 은닉은 캡슐화보다 더 넓은 개념으로, 객체의 내부 동작을 외부에서 알 필요 없도록 하고, 객체가 어떻게 동작하는지보다는 무엇을 할 수 있는지에만 집중하게 만듭니다. 이를 통해 외부 모듈이 객체의 세부 구현에 의존하지 않게 하고, 객체의 내부 구현이 변경되더라도 외부에 영향을 미치지 않도록 합니다.
차이점 정리
구분 | 캡슐화 Encapsulation | 정보 은닉Information Hiding |
---|---|---|
목적 | 데이터를 보호하고, 객체 상태의 무결성 유지 | 객체의 세부 구현을 감추고, 필요한 정보만 외부에 노출 |
적용 범위 | 주로 데이터 보호에 중점 | 모듈 간 상호작용과 구현 세부 사항 감추기에 중점 |
초점 | 외부에서 객체의 데이터를 직접 수정할 수 없도록 막음 | 객체의 인터페이스를 통해서만 상호작용하도록 하고, 내부 동작 감춤 |
연관성 | 정보 은닉의 한 부분으로, 객체의 상태를 보호하는 역할 | 캡슐화를 포함한 더 넓은 개념으로, 객체의 구현을 감추고 경계를 설정함 |
예시를 통한 이해
public class Person
{
// 캡슐화: 외부에서 직접 접근할 수 없는 private 필드
private string name;
// 캡슐화: 데이터를 보호하고, 내부 상태에 접근할 수 있는 메서드를 제공
public string GetName()
{
return name;
}
public void SetName(string newName)
{
name = newName;
}
}
public class Employee : Person
{
// 정보 은닉: 외부에서 세부 구현을 알 필요 없이, 필요한 메서드만 제공
public double CalculateSalary()
{
// 급여 계산 로직 (구현 세부 사항은 외부에 숨겨짐)
return baseSalary + bonus;
}
}
- 캡슐화:
Person
클래스의name
필드는 private로 선언되어 외부에서 직접 접근할 수 없습니다. 이 필드는GetName()
및SetName()
메서드를 통해서만 접근할 수 있습니다. 이렇게 데이터를 보호하는 것이 캡슐화의 핵심입니다. - 정보 은닉:
Employee
클래스는 급여 계산 로직을 외부에 노출하지 않고,CalculateSalary()
메서드를 통해서만 급여 계산 결과를 반환합니다. 내부에서 어떤 방식으로 급여가 계산되는지는 외부에서 알 필요가 없으며, 이는 정보 은닉을 통해 구현 세부 사항을 감추는 예입니다.
모듈 경계 설정과 정보 은닉
모듈 경계 설정은 시스템 내에서 각 모듈이 다른 모듈과 어떻게 상호작용 할 지를 정의하는 과정입니다. 정보 은닉은 이러한 경계 설정에서 중요한 역할을 합니다. 모듈이 외부에 노출하는 것은 명확하게 정의된 인터페이스뿐이며, 내부 구현은 감춰져 있어야 합니다. 이를 통해 모듈 간 결합도를 낮추고, 각 모듈이 독립적으로 변경될 수 있습니다.
예제: 모듈 경계 설정
다음은 도서 관리 시스템의 Library
와 BorrowingService
클래스에서 정보 은닉과 모듈 경계 설정이 어떻게 구현되는지를 설명하는 예시입니다.
public class Library
{
private List<Book> books = new List<Book>();
// 외부에서 직접 접근하지 않고, 인터페이스를 통해 접근
public List<Book> SearchBooks(string title)
{
return books.Where(b => b.Title.Contains(title)).ToList();
}
public void AddBook(Book book)
{
books.Add(book);
}
}
public class BorrowingService
{
private Library library;
// 정보 은닉: Library 내부 구현은 감추고, 필요한 메서드만 인터페이스를 통해 사용
public BorrowingService(Library library)
{
this.library = library;
}
public List<Book> GetAvailableBooks(string title)
{
// 모듈 경계 설정: Library의 구현 세부 사항을 알 필요 없이, 메서드를 통해 상호작용
return library.SearchBooks(title);
}
}
Library
클래스는 책 목록(books
)을 private으로 선언하여 외부에서 직접 접근하지 못하게 하고, 책 검색이나 추가는 메서드를 통해서만 가능하게 합니다. 외부에서는books
의 세부 구조나 구현에 접근할 수 없습니다.BorrowingService
는 Library의 내부 구현에 의존하지 않고SearchBooks
메서드를 사용하여 필요한 책 정보를 가져옵니다. 이로 인해Library
클래스가 내부적으로 변경되더라도,BorrowingService
는 그 변화에 영향을 받지 않습니다.
정보 은닉과 경계 설정의 중요성
정보 은닉과 모듈 경계 설정은 실무에서 모듈 간 결합도를 줄이고, 독립적인 모듈 설계를 가능하게 합니다. 이를 통해 각 모듈이 독립적으로 변경될 수 있으며, 시스템의 복잡성을 줄여 유지보수성과 확장성을 높일 수 있습니다. 특히, 대규모 시스템에서는 모듈 경계가 명확해야 시스템 전반에 미치는 영향을 최소화하고, 각 모듈의 책임과 역할이 분명하게 구분되어야 합니다.
예시: 사용자 대여 정보 관리
BorrowingService
가 사용자의 대여 기록을 관리할 때, 정보 은닉과 모듈 경계 설정이 어떻게 중요한 역할을 하는지 살펴보겠습니다.
public class BorrowingService
{
private Dictionary<int, List<Book>> borrowingRecords = new Dictionary<int, List<Book>>();
// 정보 은닉: 외부에서는 대여 기록 전체에 접근할 수 없고, 특정 사용자 기록만 가져올 수 있음
public List<Book> GetBorrowingRecords(int userId)
{
if (borrowingRecords.ContainsKey(userId))
{
return new List<Book>(borrowingRecords[userId]);
}
return new List<Book>();
}
// 캡슐화: 대여 기록 추가는 메서드를 통해서만 가능
public void AddBorrowingRecord(int userId, Book book)
{
if (!borrowingRecords.ContainsKey(userId))
{
borrowingRecords[userId] = new List<Book>();
}
borrowingRecords[userId].Add(book);
}
}
정보 은닉과 모듈 경계 설정의 실무적 적용
BorrowingService
클래스는 사용자 대여 기록을 private 필드로 관리하고, 외부에서 직접 접근할 수 없도록 합니다. 대신, 특정 사용자의 대여 기록을 반환하는 메서드만 외부에 제공하여 필요한 정보만 노출합니다.- 대여 기록 추가는 외부에서 직접 리스트를 수정할 수 없고,
AddBorrowingRecord
메서드를 통해서만 가능합니다. 이는 정보 은닉과 경계 설정을 통해 모듈 간의 상호작용을 제한하고, 모듈의 독립성을 보장하는 방식입니다.
정보 은닉과 모듈 경계 설정을 통한 유지보수성 향상
정보 은닉과 경계 설정을 잘 적용하면, 모듈 간의 결합도를 낮추고, 변경이 필요한 경우에도 다른 모듈에 영향을 최소화할 수 있습니다. 이는 시스템의 유지보수성을 크게 향상시키고, 확장성 있는 설계를 가능하게 합니다. 모듈의 경계를 명확하게 설정하면, 각 모듈이 자신만의 역할을 독립적으로 수행할 수 있고, 변경이 필요할 때도 다른 모듈과 충돌을 일으키지 않습니다.
맺음말
정보 은닉과 모듈 경계 설정은 객체지향 설계에서 매우 중요한 원칙으로, 시스템을 보다 견고하고 유연하게 만드는 데 기여합니다. 각 모듈의 내부 구현을 감추고, 명확한 경계를 통해 상호작용을 제한하면, 시스템은 더 독립적이고 유지보수성이 높은 구조로 발전할 수 있습니다.