본문 바로가기

Develop/Flutter

Enum을 더 편하게 사용하기

반응형

개발중에 Enum class를 자주 사용하는 편입니다.

Dart Enum Class

 

열거 타입

Dart의 열거 타입에 대해 학습합니다.

dart-ko.dev

간단하게 열거만 하려면 다른 언어들과 마찬가지로 사용해도 되지만 좀 더 발전된 형태로 추가를 하고 싶을때는 문서와 같이 일반 Class를 사용하는 느낌으로 사용할 수 있습니다.

/**
*	일반적으로 열거만 하는 방법
*/
enum Color { red, green, blue }

//단순히 category화를 위한 값으로 사용
//Log 찍으면 나오는 값
Color.red		//Color.red
Color.red.index	//0
Color.red.name	//red



/**
*	발전된 형태의 enum class
*	선언해두는 category 내부에 값들을 정해두는 방법
*
*	car, bus, bicycle이 red,green, blue와 같이 열거되는 값들
*/
enum Vehicle {
  car(tires: 4, passengers: 5, carbonPerKilometer: 400),
  bus(tires: 6, passengers: 50, carbonPerKilometer: 800),
  bicycle(tires: 2, passengers: 1, carbonPerKilometer: 0);

  const Vehicle({
    required this.tires,
    required this.passengers,
    required this.carbonPerKilometer,
  });

  final int tires;
  final int passengers;
  final int carbonPerKilometer;

  int get carbonFootprint => (carbonPerKilometer / passengers).round();

  bool get isTwoWheeled => this == Vehicle.bicycle;
}

//Log 찍으면 나오는 값
Vehicle.car.tires	//4
Vehicle.car.passengers	//5
Vehicle.bus.tires	//6
Vehicle.bus.name	//bus
Vehicle.bus.index	//1

 

개인적으로 음식점에서 메뉴판을 주는데 목차없이 금액이랑 한번에 쓰여있는 느낌이 들기도 하고 UI작업에서 긴 문자열이 들어가야할 때 enum class에 너무 많은 데이터가 들어가 가독성이 떨어지는 경우도 있어서 다른 방법을 주로 사용합니다.

Extension Types

 

Extension types

Learn how to write a static-only interface for an existing type.

dart.dev

 

enum Vehicle {
  car, bus, bicycle
}

extension VehicleExtension on Vehicle {
  int get tires {
    switch (this) {
      case Vehicle.car: return 4;
      case Vehicle.bus: return 6;
      case Vehicle.bicycle: return 2;
    }
  }
  
  int get passengers {
    switch (this) {
      case Vehicle.car: return 5;
      case Vehicle.bus: return 50;
      case Vehicle.bicycle: return 1;
    }
  }
  
  int get carbonPerKilometer {
    switch (this) {
      case Vehicle.car: return 400;
      case Vehicle.bus: return 800;
      case Vehicle.bicycle: return 0;
    }
  }
  
  int get carbonFootprint => (this.carbonPerKilometer / this.passengers).round();
  bool get isTwoWheeled => this.tires == 2;
}

가이드문서의 예제 코드를 똑같은 기능을 하도록 구현했습니다.

큰 차이점은 기존 enum을 그대로 사용하는 것이고 각 변수별로 switch 접근으로 값을 가져오는 것이고 나머지는 거의 똑같이 구현이 가능합니다.

switch문으로 각 값을 정의해두다보니 코드의 길이는 길어질 수 있지만 enum class와 분리되어 있어 Vehicle이라는 class는 같이 사용하지만 value들을 다르게 사용하는 경우 등과 같이 재사용성이 좋고 초기화코드가 필요없다는 장점이 있어 경우에 따라서 선택하기 좋은 방법이라고 생각합니다.

  enum extension
장점
  • 직접적인 속성 추가: Enum에 변수나 필드를 직접 추가하여 더 많은 정보를 포함할 수 있음
  • 기능 확장: Enum 내에서 추가된 속성을 기반으로 다양한 로직을 직접 구현할 수 있음
  • 표현력 강화: Enum 자체가 더 많은 정보를 담을 수 있게 되어, 사용 시 더 직관적일 수 있음
  • 기존 Enum 변경 없이 확장: Enum 자체를 변경하지 않고도 기능을 추가할 수 있습니다. 이는 특히 Enum이 외부 라이브러리나 패키지에 정의되어 있는 경우 유용
  • 코드 분리: Enum과 확장 기능이 분리되어 있어서, 더 모듈화된 코드를 작성할 수 있음
  • 유지보수성 향상: 확장 메서드를 통해 Enum의 기능을 분리하여, 각각의 책임을 더 명확하게 할 수 있음
단점
  • Enum의 복잡성 증가: Enum에 많은 변수를 추가하면 복잡성이 증가할 수 있음
  • 일관성 유지 어려움: 많은 변수를 추가할 경우, 관리와 일관성을 유지하기 어려울 수 있음
  • 초기화 코드 필요: Enum에 변수를 추가하면, 각 Enum 값에 대한 초기화 코드를 작성해야 함
  • 범용성 제한: Extension으로는 Enum의 기본 동작을 변경할 수 없고, 새로운 속성(필드)을 추가할 수 없습니다. 단지 메서드 추가만 가능
  • 클래스나 다른 타입의 확장 어려움: Extension은 주로 메서드를 추가하는 데 사용되며, 복잡한 상태나 구조를 가진 확장은 어려움
반응형