Dart에서 어노테이션 심층 탐구: 초보자를 위한 가이드

2024. 6. 23. 01:36Flutter/Dart Language

반응형

Dart에서 어노테이션은 코드에 메타데이터를 추가하는 강력한 도구입니다.

마치 책에 책갈피를 달거나 하이라이트를 칠하는 것처럼, 어노테이션은 코드에 추가적인 정보를 제공하여 코드를 더욱 이해하기 쉽고 유지 관리하기 용이하게 만들어줍니다.

이 블로그 게시글에서는 Dart에서 어노테이션의 기본 개념부터 다양한 사용법까지, 초보자도 쉽게 이해할 수 있도록 심층적으로 살펴보겠습니다.

1. 어노테이션이란 무엇일까요?

어노테이션은 클래스, 함수, 변수, 매개변수 등 다양한 코드 요소에 추가할 수 있는 특별한 문자 시퀀스입니다.

어노테이션은 다음과 같은 다양한 목적으로 사용됩니다.

  • 코드 문서화: 어노테이션을 사용하여 코드의 기능, 사용 방법, 제약 조건 등을 명확하게 설명할 수 있습니다. 이는 코드를 이해하고 사용하는 다른 개발자들에게 큰 도움이 됩니다.
  • 코드 구성 및 조직화: 어노테이션을 사용하여 코드를 논리적으로 그룹화하고 분류할 수 있습니다. 이는 코드를 더욱 읽기 쉽고 유지 관리하기 용이하게 만듭니다.
  • 코드 제어 및 자동화: 어노테이션을 사용하여 컴파일러나 다른 도구가 코드를 처리하는 방식을 제어할 수 있습니다. 예를 들어, 테스트 코드를 식별하거나 특정 코드를 최적화하도록 지시하는 데 사용할 수 있습니다.

2. 어노테이션 사용 방법

어노테이션을 사용하려면 다음과 같은 단계를 따릅니다.

  1. 어노테이션 클래스 정의: 어노테이션을 나타내는 클래스를 정의합니다. 이 클래스는 어노테이션의 이름, 매개변수, 기타 속성을 정의합니다.
  2. 코드 요소에 어노테이션 추가: 어노테이션 클래스를 사용하여 코드 요소에 어노테이션을 추가합니다. 어노테이션은 @ 기호로 시작하며, 어노테이션 이름과 괄호 안에 매개변수 값 (있는 경우)을 지정합니다.

예시

// 어노테이션 클래스 정의
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.CLASS, ElementType.FUNCTION})
class MyAnnotation {
  final String message;

  const MyAnnotation(this.message);
}

// 코드 요소에 어노테이션 추가
@MyAnnotation(message: "This is an example annotation.")
class MyClass {
  // ...
}
 

설명

  • @Retention(RetentionPolicy.RUNTIME) 어노테이션은 컴파일 후에도 어노테이션 정보가 유지되도록 합니다.
  • @Target({ElementType.CLASS, ElementType.FUNCTION}) 어노테이션은 이 어노테이션이 클래스와 함수에 사용될 수 있음을 나타냅니다.
  • MyAnnotation 클래스는 message이라는 문자열 매개변수를 가진 어노테이션을 정의합니다.
  • @MyAnnotation(message: "This is an example annotation.") 은 MyClass 클래스에 MyAnnotation 어노테이션을 추가하고, message 매개변수에 "This is an example annotation." 값을 지정합니다.

3. 어노테이션 종류

Dart에서 제공하는 기본 어노테이션 종류는 다음과 같습니다.

  • @Retention: 어노테이션 정보가 유지되는 기간을 지정합니다.
  • @Target: 어노테이션을 사용할 수 있는 코드 요소를 지정합니다.
  • @Deprecated: 코드가 더 이상 사용되지 않음을 나타냅니다.
  • @Optional: 어노테이션 매개변수가 선택적임을 나타냅니다.
  • @Default: 어노테이션 매개변수의 기본값을 지정합니다.

이 외에도 다양한 사용자 정의 어노테이션을 만들 수 있습니다.

4. 어노테이션 활용 사례

  • 코드 문서화
/// This class represents a person.
@deprecated('Use `User` class instead.')
class Person {
  /// The person's name.
  final String name;

  /// The person's age.
  final int age;

  Person(this.name, this.age);
}
 

위 코드에서 @deprecated 어노테이션은 Person 클래스가 더 이상 사용되지 않고 User 클래스를 대신 사용해야 한다는 것을 나타냅니다.

또한, 각 속성에 대한 주석은 코드의 기능을 명확하게 설명합니다.

  • 코드 구성 및 조직화
@Todo('Implement this function')
void doSomething() {
  // ...
}
 

위 코드에서 @Todo 어노테이션은 doSomething 함수가 아직 구현되지 않았음을 나타냅니다.

이는 코드를 논리적으로 그룹화하고, 해야 할 작업을 명확하게 파악하는 데 도움이 됩니다.

  • 코드 제어 및 자동화
@Test()
void testMyFunction() {
  // ...
}
 

위 코드에서 @Test 어노테이션은 testMyFunction 함수가 테스트 코드임을 나타냅니다.

이는 테스트 코드를 자동으로 실행하고 코드 품질을 유지 관리하는 데 도움이 됩니다.

5. 실습 문제

다음 문제를 해결해 봅시다.

 

문제

다음 상황을 모델링하기 위해 어노테이션을 사용하여 클래스를 설계하세요.

  • 도서관을 나타내는 클래스를 만듭니다.
  • 각 도서관에는 이름, 위치, 소장 도서 수 속성이 있어야 합니다.
  • 도서관의 이름, 위치, 소장 도서 수를 출력하는 메서드를 작성합니다.
  • 서로 다른 도서관 유형을 나타내는 클래스를 상속하여 만들고, 각 유형별 특징을 나타내는 속성과 메서드를 추가합니다.
  • 예를 들어, 대중 도서관은 정부에서 운영되고, 대출 가능한 도서 수가 제한될 수 있습니다.
  • 학술 도서관은 대학에서 운영되고, 연구 관련 자료가 풍부할 수 있습니다.

해결 팁

  • Library 클래스를 만들어 도서관의 공통 속성과 메서드를 정의합니다.
  • @Retention(RetentionPolicy.RUNTIME) 어노테이션을 사용하여 어노테이션 정보가 런타임까지 유지되도록 합니다.
  • @Target({ElementType.CLASS}) 어노테이션을 사용하여 어노테이션이 클래스에만 사용될 수 있음을 나타냅니다.
  • PublicLibrary 클래스와 AcademicLibrary 클래스를 만들어 Library 클래스를 상속받고, 각 유형별 특징을 나타내는 속성과 메서드를 추가합니다.
  • @override 어노테이션을 사용하여 상속받은 메서드를 재정의합니다.

이 문제를 통해 어노테이션을 사용하여 코드를 설계하고 구성하는 방법을 연습할 수 있습니다.

 

정답

 

다음은 주어진 상황을 모델링하기 위해 어노테이션을 사용하여 설계한 클래스입니다.

import 'package:meta/meta.dart'; // 어노테이션을 사용하기 위해 meta 패키지를 가져옵니다.

@immutable // 클래스가 변경 불가능함을 나타냅니다.
abstract class Library {
  final String name;
  final String location;
  final int bookCount;

  Library({@required this.name, @required this.location, @required this.bookCount});

  void printInfo() {
    print("Name: $name");
    print("Location: $location");
    print("Book Count: $bookCount");
  }
}

// 대중 도서관 클래스
class PublicLibrary extends Library {
  final String 운영단체;
  final int 대출가능도서수;

  PublicLibrary({
    @required String name,
    @required String location,
    @required int bookCount,
    @required this.운영단체,
    @required this.대출가능도서수,
  }) : super(name: name, location: location, bookCount: bookCount);

  @override
  void printInfo() {
    super.printInfo();
    print("운영단체: $운영단체");
    print("대출가능도서수: $대출가능도서수");
  }
}

// 학술 도서관 클래스
class AcademicLibrary extends Library {
  final String 연구자료수;

  AcademicLibrary({
    @required String name,
    @required String location,
    @required int bookCount,
    @required this.연구자료수,
  }) : super(name: name, location: location, bookCount: bookCount);

  @override
  void printInfo() {
    super.printInfo();
    print("연구자료수: $연구자료수");
  }
}
 

설명

  • Library 클래스:
    • @immutable 어노테이션으로 클래스가 변경 불가능함을 명시합니다.
    • name, location, bookCount 속성을 가지고 일반적인 도서관의 정보를 나타냅니다.
    • printInfo 메서드는 도서관 정보를 출력합니다.
  • PublicLibrary 클래스:
    • Library 클래스를 상속받고, 대중 도서관의 특징인 운영다체대출가능도서수 속성을 추가합니다.
    • printInfo 메서드를 재정의하여 운영단체대출가능도서수 정보도 출력합니다.
  • AcademicLibrary 클래스:
    • Library 클래스를 상속받고, 학술 도서관의 특징인 연구자료수 속성을 추가합니다.
    • printInfo 메서드를 재정의하여 연구자료수 정보도 출력합니다.

사용 예시

void main() {
  PublicLibrary publicLibrary = PublicLibrary(
    name: "Seoul Public Library",
    location: "Seoul, South Korea",
    bookCount: 100000,
    운영단체: "Seoul Metropolitan Government",
    대출가능도서수: 50000,
  );

  AcademicLibrary academicLibrary = AcademicLibrary(
    name: "KAIST Library",
    location: "Daejeon, South Korea",
    bookCount: 500000,
    연구자료수: 1000000,
  );

  publicLibrary.printInfo();
  academicLibrary.printInfo();
}
 

출력

Name: Seoul Public Library
Location: Seoul, South Korea
Book Count: 100000
운영단체: Seoul Metropolitan Government
대출가능도서수: 50000
Name: KAIST Library
Location: Daejeon, South Korea
Book Count: 500000
연구자료수: 1000000

6. 마무리

이 블로그 게시글에서는 Dart에서 어노테이션의 기본 개념부터 다양한 사용법까지, 초보자도 쉽게 이해할 수 있도록 심층적으로 살펴보았습니다.

어노테이션을 활용하여 코드를 더욱 효과적으로 작성하고 유지 관리할 수 있기를 바랍니다.

더 궁금한 점이나 개선할 부분이 있다면 언제든지 코멘트를 남겨주세요.

 

 

수발가족을 위한 일기장 “나비일기장”

 

https://play.google.com/store/apps/details?id=com.maccrey.navi_diary_release

 

구글플레이 앱 배포의 시작! 비공개테스트 20명의 테스터모집을 위한 앱 "테스터 쉐어"

 

https://play.google.com/store/apps/details?id=com.maccrey.tester_share_release

 

Tester Share [테스터쉐어] - Google Play 앱

Tester Share로 Google Play 앱 등록을 단순화하세요.

play.google.com

카카오톡 오픈 채팅방

https://open.kakao.com/o/gsS8Jbzg

반응형