Dart 3.0.0 출시
23년 5월 10일, dart 3.0이 출시되었다.
switch에서 break 제거라던지
multiple return 가능,
tuple 형태 추가,
interface, final class 등
흥미로운 것들이 많이 생겼는데,
그 중 눈에 가장 띈 것은
sealed class였다.
카페자리 플러터앱의 프론트를 건드리다보니
아무래도 원시 타입보다는 category용 class를
만들어 일이 많아졌다.
그때마다 static으로 구현했으나..
이 방법은 switch문 사용시 버그 우려가 있었다.
그렇다고 enum을 사용하기엔
각 타입이 가질 수 있는 정보에 한계가 있어
2%.. 아니 10%정도 부족한 느낌이었다.
이 때, 혜성같이 sealed class 등장
나의 불편을 일순에 없애줄 sealed class가
등장했으니 안써볼 이유가 없다.
바로 사용했던 부분을 정리해보겠다.
기존 enum 방식
한가지 예를 들어보자.
다음과 같이 아이템의 카테고리를 나누는 경우다.
enum ItemType { coffee, bread, icecream }
이 타입에 따라 상황에 맞는 무언갈 할 것이다.
switch(ItemType.bread) {
case ItemType.coffee:
print("해당 상품은 커피고, 1번째로 진열되어 있습니다.");
case ItemType.bread:
print("해당 상품은 빵이고, 2번째로 진열되어 있습니다.");
case ItemType.icecream:
print("해당 상품은 아이스크림이고, 3번째로 진열되어 있습니다.");
}
// 해당 상품은 빵이고, 2번째로 진열되어 있습니다.
(참고로 이제 break를 안써줘도 된다. 개꿀!!)
뭐 당장은 문제가 없어보인다.
하지만, 해당 상품의 이름인 커피, 빵, 아이스크림
이 정보를 여기에서만 쓸까..??
마찬가지로 진열되어 있는 순서도
여기저기서 쓰일 수 있고,
이 순서가 바뀔때마다 모든 텍스트를
고쳐줄 수는 없는 노릇이다.
뭐 순서까지야 아래처럼 쓸수도 있겠지만..
switch(ItemType.bread) {
case ItemType.coffee:
print("해당 상품은 커피고, ${ItemType.coffee.index + 1}번째로 진열되어 있습니다.");
case ItemType.bread:
print("해당 상품은 빵이고, ${ItemType.bread.index + 1}번째로 진열되어 있습니다.");
case ItemType.icecream:
print("해당 상품은 아이스크림이고, ${ItemType.icecream.index + 1}번째로 진열되어 있습니다.");
}
// 해당 상품은 빵이고, 2번째로 진열되어 있습니다.
잘 모르는 사람이 내 코드를 가져다가
실수로 ItemType의 순서를 바꿔버리면
진열된 순서가 뒤죽박죽이 될것이다.
새로운 sealed class 방식
이러한 불편함을 sealed class를 통해 해결할 수 있다!!
아래처럼 구현해보자.
sealed class ItemType {
final int index;
final String name;
ItemType(this.index, this.name);
factory ItemType.coffee() => Coffee(1, "커피");
factory ItemType.bread() => Bread(2, "빵");
factory ItemType.icecream() => Icecream(3, "아이스크림");
}
class Coffee extends ItemType {
Coffee(super.index, super.name);
}
class Bread extends ItemType {
Bread(super.index, super.name);
}
class Icecream extends ItemType {
Icecream(super.index, super.name);
}
void main() {
final ItemType item = ItemType.bread();
print(
switch(item) {
Coffee() => "해당 상품은 ${ItemType.coffee().name}이고, ${ItemType.coffee().index}번째로 진열되어 있습니다.",
Bread() => "해당 상품은 ${ItemType.bread().name}이고, ${ItemType.bread().index}번째로 진열되어 있습니다.",
Icecream() => "해당 상품은 ${ItemType.icecream().name}이고, ${ItemType.icecream().index}번째로 진열되어 있습니다."
}
);
}
// 해당 상품은 빵이고, 2번째로 진열되어 있습니다.
(switch의 새로운 표현방법이 있길래 써봤다)
위와 같이 구성하면, 다음 두가지 이점을
모두 가져갈 수 있다.
얼핏 봤을 때는 굳이 써야하나 싶지만,
써본 사람은 안다. sealed class가
개발할 때 발생할 수 있는 예상치 못한 상황을
꽤나 잘 잡아줄 수 있다는 것을.
다른 유용한 기능도 다뤄봐야지
앞으로도 몇편정도 바뀐 부분과
신기능에 대해 포스팅을 다뤄봐야겠다.
좋은글 감사합니다. 참조해서 제 블로그에 글을 써도 될까요