Menu
Coddy logo textTech

라이브러리 수준의 프라이버시

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

Dart에서 프라이버시는 클래스 수준이 아니라 라이브러리 수준에서 적용됩니다. 이는 Java나 C++와 같은 언어와의 주요 차이점입니다. Dart에서 라이브러리는 일반적으로 단일 파일이거나, part 지시어로 연결된 여러 파일입니다.

비공개 멤버(_로 시작하는 멤버)는 동일한 라이브러리 내 어디에서나 접근할 수 있으며, 심지어 다른 클래스에서도 접근이 가능합니다:

// 두 클래스가 동일한 파일(동일한 라이브러리)에 있음
class Engine {
  int _horsepower = 200;  // 이 라이브러리에 대해 비공개(Private)
}

class Car {
  void showPower(Engine engine) {
    print(engine._horsepower);  // 접근 가능! 동일한 라이브러리
  }
}

하지만 다른 파일에서 클래스를 가져오면, 해당 클래스의 private 멤버는 완전히 숨겨집니다:

// file: engine.dart
class Engine {
  int _horsepower = 200;
  int get power => _horsepower;
}

// file: main.dart
import 'engine.dart';

void main() {
  var engine = Engine();
  // print(engine._horsepower);  // 오류! 접근할 수 없습니다
  print(engine.power);           // 정상 작동 - 공개 getter 사용
}

이러한 라이브러리 수준의 프라이버시는 같은 파일에 있는 클래스들이 외부 코드로부터 구현 세부 사항을 숨기면서도 서로 긴밀하게 협력할 수 있음을 의미합니다. 이는 관련된 클래스들을 동일한 라이브러리에 함께 구성하도록 권장하는 의도적인 설계 선택입니다.

challenge icon

챌린지

쉬움

Dart에서 라이브러리 수준의 프라이버시가 어떻게 작동하는지 보여주는 팀 협업 시스템을 구축해 보겠습니다. 동일한 파일에 있는 클래스들이 서로의 프라이빗 멤버에 접근할 수 있는 반면, 별도의 파일에 있는 코드는 접근할 수 없는 방식을 확인하게 될 것입니다.

코드를 두 개의 파일로 구성합니다:

  • team.dart: 이 파일에는 동일한 라이브러리 내에서 밀접하게 작동하는 두 개의 클래스가 포함됩니다:
    • 공개된 String name50으로 초기화된 프라이빗 int _performanceScore를 가진 Member 클래스. 이름을 매개변수로 받는 생성자와 프라이빗 점수를 반환하는 공개 게터 performanceScore를 포함하세요.
    • 동일한 파일에 위치하여 Member의 프라이빗 필드에 직접 접근할 수 있는(동일한 라이브러리에 있기 때문) TeamLead 클래스. 이 클래스는 공개된 String name, 이름을 매개변수로 받는 생성자, 그리고 member._performanceScore에 직접 접근하여 10을 더하고 [leadName] boosted [memberName]'s score to [newScore]를 출력하는 evaluateMember(Member member) 메서드를 가져야 합니다.
  • main.dart: 팀 파일을 임포트하고 접근 권한의 차이를 보여줍니다:
    • 이름이 'Alice'Member를 생성합니다.
    • 이름이 'Bob'TeamLead를 생성합니다.
    • Alice의 공개 게터를 사용하여 Initial score: [score]를 출력합니다.
    • Bob이 evaluateMember를 사용하여 Alice를 평가하도록 합니다.
    • 공개 게터를 사용하여 Updated score: [score]를 출력합니다.
    • Direct access from main: Not allowed를 출력합니다 (이는 main.dart가 다른 라이브러리에 있기 때문에 _performanceScore에 직접 접근할 수 없음을 상기시켜 줍니다).

여기서 핵심 통찰은 TeamLeadMember 클래스가 모두 동일한 파일(동일한 라이브러리)에 있기 때문에 TeamLeadMember의 프라이빗 _performanceScore를 직접 읽고 수정할 수 있다는 점입니다. 그러나 main.dart의 코드는 다른 라이브러리에 있으므로 반드시 공개 게터를 사용해야 합니다.

예상 출력:

Initial score: 50
Bob boosted Alice's score to 60
Updated score: 60
Direct access from main: Not allowed

치트 시트

Dart에서 프라이버시는 클래스 수준이 아니라 라이브러리 수준에서 적용됩니다. 라이브러리는 일반적으로 단일 파일이거나 part 지시어로 연결된 여러 파일입니다.

프라이빗 멤버는 밑줄(_)로 시작하며, 동일한 라이브러리 내 어디에서나 접근할 수 있으며 다른 클래스에서도 접근 가능합니다:

// 두 클래스가 같은 파일(같은 라이브러리)에 있음
class Engine {
  int _horsepower = 200;  // 이 라이브러리에 대해 프라이빗함
}

class Car {
  void showPower(Engine engine) {
    print(engine._horsepower);  // 접근 가능! 같은 라이브러리
  }
}

다른 파일에서 클래스를 임포트하면 해당 클래스의 프라이빗 멤버는 숨겨집니다:

// 파일: engine.dart
class Engine {
  int _horsepower = 200;
  int get power => _horsepower;
}

// 파일: main.dart
import 'engine.dart';

void main() {
  var engine = Engine();
  // print(engine._horsepower);  // 에러! 접근 불가
  print(engine.power);           // 작동함 - 공개 게터(getter) 사용
}

이러한 설계는 관련된 클래스들을 동일한 라이브러리에 함께 구성하도록 권장하며, 외부 코드로부터 구현 세부 사항을 숨기면서 클래스들이 긴밀하게 협력할 수 있도록 합니다.

직접 해보기

import 'team.dart';

void main() {
  // TODO: 'Alice'라는 이름의 Member 생성하기

  // TODO: 'Bob'이라는 이름의 TeamLead 생성하기

  // TODO: Alice의 public getter를 사용하여 "Initial score: [score]" 출력하기

  // TODO: evaluateMember를 사용하여 Bob이 Alice를 평가하게 하기

  // TODO: public getter를 사용하여 "Updated score: [score]" 출력하기

  // TODO: "Direct access from main: Not allowed" 출력하기
  // Note: 여기서 alice._performanceScore에 접근할 수 없습니다. 그 이유는
  // main.dart가 team.dart와 다른 라이브러리에 있기 때문입니다.
}
quiz icon실력 점검

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

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