Menu
Coddy logo textTech

정보 은닉

Coddy Dart 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨 — 110개 중 34번째.

정보 은닉은 캡슐화의 핵심 원칙으로, 클래스가 내부 동작을 숨기고 필요한 것만 노출해야 한다는 개념입니다. 여러분은 이미 그 메커니즘(private fields, getters, setters)을 배웠지만, 진정한 목표는 사용하기 쉽고 오용하기 어려운 클래스를 설계하는 것입니다.

사용자의 비밀번호를 관리하는 클래스를 생각해 봅시다. 내부 저장 및 해싱 로직은 완전히 숨겨져야 합니다:

class UserAccount {
  String _username;
  String _passwordHash;
  
  UserAccount(this._username, String password) 
      : _passwordHash = _hashPassword(password);
  
  static String _hashPassword(String password) {
    return 'hashed_$password';  // 단순화된 예제
  }
  
  bool verifyPassword(String password) {
    return _passwordHash == _hashPassword(password);
  }
  
  String get username => _username;
}

외부 코드는 비밀번호 해시를 보거나 그것이 어떻게 저장되는지 알 수 없습니다. 그저 verifyPassword()를 호출할 뿐입니다. 이러한 분리는 이 클래스를 사용하는 코드에 영향을 주지 않고 해싱 알고리즘을 완전히 변경할 수 있음을 의미합니다.

핵심적인 통찰은 클래스를 외부에서 내부를 바라보는 관점으로 생각하는 것입니다.

스스로에게 물어보세요: "이 클래스를 사용하는 사람에게 실제로 필요한 것은 무엇인가?" 필요한 것만 노출하고 나머지는 모두 비공개(private)로 유지하세요. 이렇게 하면 클래스가 무엇을 하는지(공개 인터페이스)와 그것을 어떻게 수행하는지(비공개 구현) 사이에 명확한 경계가 생성됩니다.

challenge icon

챌린지

쉬움

정보 은닉이 실제로 어떻게 작동하는지 보여주는 안전한 지갑 시스템을 구축해 보겠습니다. 사용자의 잔액과 거래 내역을 관리하는 디지털 지갑을 만들게 되며, 모든 민감한 내부 세부 정보는 외부 코드로부터 완전히 숨겨집니다.

코드는 두 개의 파일로 구성됩니다:

  • wallet.dart: 돈을 안전하게 관리하는 Wallet 클래스를 만듭니다. 지갑은 소유자의 이름을 공개적으로 저장해야 하지만, 그 외의 모든 것은 깔끔한 공개 인터페이스 뒤에 숨겨야 합니다:
    • 내부 잔액과 거래 로그는 비공개(private)여야 합니다. 외부 코드에서 돈을 어떻게 저장하거나 추적하는지 알 수 없어야 합니다.
    • 비공개 메서드는 내부적으로 거래를 기록하는 역할을 해야 합니다 ("Deposit: $50.0" 또는 "Withdrawal: $30.0"와 같은 항목 저장).
    • 금액이 양수인 경우에만 돈을 추가하고 내부적으로 거래를 기록하는 공개 deposit(double amount) 메서드를 제공합니다.
    • 잔액이 충분하고 금액이 양수인 경우에만 돈을 인출하고 내부적으로 거래를 기록하는 공개 withdraw(double amount) 메서드를 제공합니다. 성공하면 true를, 그렇지 않으면 false를 반환합니다.
    • 현재 잔액을 반환하는 공개 게터(getter) balance를 제공합니다 (읽기 전용 접근).
    • 실제 거래 리스트를 노출하지 않고 기록된 거래 횟수를 반환하는 공개 메서드 getTransactionCount()를 제공합니다.
    • 가장 최근의 거래 문자열을 반환하거나, 거래가 없는 경우 "No transactions"를 반환하는 공개 메서드 getLastTransaction()을 제공합니다.
    • 지갑 상태를 표시하는 printSummary() 메서드를 포함합니다.
  • main.dart: 지갑을 임포트하고 정보 은닉이 어떻게 깔끔하고 안전한 인터페이스를 만드는지 보여줍니다:
    • 소유자가 "Sarah"인 지갑을 생성합니다.
    • 100.0을 입금합니다.
    • 50.0을 입금합니다.
    • 200.0 인출을 시도하고 결과에 따라 "Withdrawal of 200.0: [success/failed]"를 출력합니다.
    • 30.0을 인출하고 "Withdrawal of 30.0: [success/failed]"를 출력합니다.
    • printSummary()를 호출합니다.
    • "Transaction count: [count]"를 출력합니다.
    • "Last transaction: [transaction]"을 출력합니다.

printSummary() 메서드는 다음과 같이 출력해야 합니다:

=== Wallet Summary ===
Owner: [ownerName]
Balance: $[balance]

외부 코드가 잔액이 어떻게 저장되는지 또는 거래가 내부적으로 어떻게 추적되는지 전혀 알지 못해도, 명확하고 목적이 분명한 메서드를 통해 지갑과 상호작용하는 방식에 주목하세요. 구현 세부 사항은 완전히 숨겨져 있으므로, 지갑을 사용하는 코드에 영향을 주지 않고 거래 저장 방식을 변경할 수 있습니다.

예상 출력:

Withdrawal of 200.0: failed
Withdrawal of 30.0: success
=== Wallet Summary ===
Owner: Sarah
Balance: $120.0
Transaction count: 3
Last transaction: Withdrawal: $30.0

치트 시트

정보 은닉은 캡슐화의 핵심 원칙으로, 클래스의 내부 동작을 숨기고 필요한 부분만 노출하는 것을 의미합니다.

클래스를 설계할 때는 외부에서 내부로 접근하는 방식을 취하세요. 사용자에게 필요한 것만 노출하고 나머지는 모두 비공개(private)로 유지하십시오. 이는 공개 인터페이스(클래스가 하는 일)와 비공개 구현(그 일을 처리하는 방식) 사이에 명확한 경계를 만듭니다.

비밀번호 관리자를 통한 정보 은닉의 예시입니다:

class UserAccount {
  String _username;
  String _passwordHash;
  
  UserAccount(this._username, String password) 
      : _passwordHash = _hashPassword(password);
  
  static String _hashPassword(String password) {
    return 'hashed_$password';
  }
  
  bool verifyPassword(String password) {
    return _passwordHash == _hashPassword(password);
  }
  
  String get username => _username;
}

외부 코드는 비밀번호 해시나 저장 메커니즘을 절대 볼 수 없으며, 오직 verifyPassword()만을 사용합니다. 이를 통해 외부 코드에 영향을 주지 않고 내부 구현을 변경할 수 있습니다.

직접 해보기

import 'wallet.dart';

void main() {
  // TODO: 소유자 "Sarah"를 위한 지갑 생성
  
  // TODO: 100.0 입금
  
  // TODO: 50.0 입금
  
  // TODO: 200.0 출금을 시도하고 결과 출력
  // 형식: "Withdrawal of 200.0: [success/failed]"
  
  // TODO: 30.0 출금 및 결과 출력
  // 형식: "Withdrawal of 30.0: [success/failed]"
  
  // TODO: printSummary() 호출
  
  // TODO: 거래 횟수 출력
  // 형식: "Transaction count: [count]"
  
  // TODO: 마지막 거래 출력
  // 형식: "Last transaction: [transaction]"
}
quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

객체 지향 프로그래밍의 모든 레슨