본문 바로가기
다트(Dart) 언어 강좌

Getter와 Setter 를 알아보자

by everythingdev 2024. 7. 26.
반응형

Getter와 Setter를 알아보자

  • 플러터를 시작하기 전 다트(Dart) 언어의 개념에 대해 정리를 해보고자 합니다.
  • 다트(Dart) 언어 개념 정리 포스팅 후 플러터(Flutter) 개념 정리로 넘어갈 예정입니다.
  • 플러터(Flutter) 개념 정리 후 실습이 시작 된다고 보시면 될 것 같습니다.

소개

  • 다트(Dart)는 구글이 개발한 현대적이고 강력한 프로그래밍 언어로, 특히 Flutter 프레임워크와 함께 사용되어 크로스 플랫폼 애플리케이션 개발에 널리 활용되고 있습니다.
  • 다트의 주요 특징 중 하나는 객체 지향 프로그래밍(OOP)을 강력하게 지원한다는 점입니다.
  • 이번 포스팅에서는 OOP의 중요한 개념인 Getter와 Setter에 대해 자세히 알아보겠습니다.

Getter와 Setter란?

Getter와 Setter는 객체의 속성(프로퍼티)에 접근하고 수정하는 특별한 메서드입니다. 이들은 캡슐화(encapsulation)를 구현하는 데 중요한 역할을 합니다.

  • Getter : 객체의 속성 값을 읽는 메서드
  • Setter : 객체의 속성 값을 설정하는 메서드

다트에서는 이러한 Getter와 Setter를 매우 간단하고 효율적으로 구현할 수 있습니다.

다트에서의 Getter 구현

다트에서 Getter를 구현하는 방법은 다음과 같습니다:

class Rectangle {
  double _width;
  double _height;

  Rectangle(this._width, this._height);

  // Getter
  double get area => _width * _height;
}
  • 이 예제에서 area는 Getter입니다. _width_height는 private 변수이지만, area Getter를 통해 외부에서 직사각형의 면적을 쉽게 계산하고 접근할 수 있습니다.

다트에서의 Setter 구현

Setter는 다음과 같이 구현할 수 있습니다:

class Circle {
  double _radius;

  Circle(this._radius);

  // Getter
  double get radius => _radius;

  // Setter
  set radius(double value) {
    if (value > 0) {
      _radius = value;
    } else {
      throw ArgumentError('Radius must be positive');
    }
  }
}
  • 이 예제에서 radius Setter는 입력값이 양수인지 확인한 후에 _radius 값을 설정합니다. 이를 통해 객체의 상태를 보호하고 유효성을 검증할 수 있습니다.

Getter와 Setter의 장점

  • 캡슐화 : 객체의 내부 상태를 외부로부터 숨기고, 접근을 제어할 수 있습니다.
  • 유효성 검증 : Setter를 통해 객체의 상태 변경 시 유효성을 검사할 수 있습니다.
  • 계산된 속성 : Getter를 사용하여 다른 속성들을 기반으로 계산된 값을 반환할 수 있습니다.
  • 읽기 전용 속성 : Getter만 제공하고 Setter를 제공하지 않음으로써 읽기 전용 속성을 만들 수 있습니다.
  • 유연성 : 내부 구현을 변경하더라도 외부 인터페이스는 그대로 유지할 수 있습니다.

Getter와 Setter의 고급 사용법

1. 계산된 속성

Getter를 사용하여 다른 속성들을 기반으로 계산된 값을 제공할 수 있습니다:

class Person {
  String firstName;
  String lastName;

  Person(this.firstName, this.lastName);

  String get fullName => '$firstName $lastName';
}

void main() {
  var person = Person('John', 'Doe');
  print(person.fullName); // 출력: John Doe
}
  • 이 예제에서 fullName Getter는 firstNamelastName을 조합하여 전체 이름을 반환합니다.

2. 지연 초기화(Lazy Initialization)

Getter를 사용하여 비용이 많이 드는 연산을 지연 초기화할 수 있습니다:

class HeavyComputation {
  List<int> _cache;

  List<int> get expensiveList {
    if (_cache == null) {
      print('Computing expensive list...');
      _cache = List.generate(1000000, (i) => i * i);
    }
    return _cache;
  }
}

void main() {
  var comp = HeavyComputation();
  print(comp.expensiveList.length); // 첫 호출 시 계산
  print(comp.expensiveList.length); // 캐시된 결과 사용
}
  • 이 예제에서 expensiveList Getter는 처음 호출될 때만 비용이 많이 드는 계산을 수행하고, 이후 호출에서는 캐시된 결과를 반환합니다.

3. 상속과 Getter/Setter

Getter와 Setter는 상속 관계에서도 유용하게 사용될 수 있습니다:

abstract class Shape {
  double get area;
}

class Circle extends Shape {
  double radius;

  Circle(this.radius);

  @override
  double get area => 3.14 * radius * radius;
}

class Rectangle extends Shape {
  double width;
  double height;

  Rectangle(this.width, this.height);

  @override
  double get area => width * height;
}

void printArea(Shape shape) {
  print('The area is: ${shape.area}');
}

void main() {
  var circle = Circle(5);
  var rectangle = Rectangle(4, 6);

  printArea(circle);     // 출력: The area is: 78.5
  printArea(rectangle);  // 출력: The area is: 24.0
}

  • 이 예제에서 Shape 추상 클래스는 area Getter를 정의하고, CircleRectangle 클래스가 이를 구현합니다. 이를 통해 다형성을 구현할 수 있습니다.

Getter와 Setter 사용 시 주의사항

  • 과도한 사용 주의 : 모든 필드에 대해 Getter와 Setter를 만들 필요는 없습니다. 필요한 경우에만 사용하세요.
  • 성능 고려 : Getter와 Setter 내에서 복잡한 연산을 수행하면 성능에 영향을 줄 수 있습니다. 필요한 경우 캐싱을 고려하세요.
  • 일관성 유지 : Getter와 Setter의 이름은 일관성 있게 지어야 합니다. 다트에서는 보통 필드 이름과 동일하게 짓습니다.
  • 불변성 고려 : 가능한 경우 객체를 불변(immutable)으로 만들어 Setter 사용을 최소화하는 것이 좋습니다.

결론

  • 다트의 Getter와 Setter는 객체 지향 프로그래밍의 중요한 개념인 캡슐화를 구현하는 강력한 도구입니다. 이들을 적절히 활용하면 코드의 가독성, 유지보수성, 그리고 안정성을 크게 향상시킬 수 있습니다.
  • Getter를 통해 객체의 내부 상태를 안전하게 노출하고, 계산된 속성을 쉽게 제공할 수 있습니다. Setter를 사용하면 객체의 상태 변경을 제어하고 유효성을 검증할 수 있습니다. 이러한 특성들은 특히 대규모 프로젝트나 팀 단위의 개발에서 매우 유용합니다.
  • 다트와 Flutter를 사용하여 애플리케이션을 개발할 때, Getter와 Setter를 효과적으로 활용하면 더욱 견고하고 유지보수가 용이한 코드를 작성할 수 있습니다. 하지만 과도한 사용은 피하고, 실제로 필요한 경우에만 적용하는 것이 중요합니다.
  • 앞으로의 프로젝트에서 Getter와 Setter를 적절히 활용하여 더 나은 코드를 작성해 보세요. 이를 통해 객체 지향 프로그래밍의 장점을 최대한 활용하고, 더 효율적이고 안정적인 애플리케이션을 개발할 수 있을 것입니다.

맺음말

  • 이번 포스팅에서는 다트의 getter와 setter에 대해 알아보았습니다.
  • 다음 포스팅에서는 다트의 예외 처리에 대해 알아보고자 합니다.
반응형