본문 바로가기

Flutter/Skills

제네릭 <T> 를 사용할때, 착각하기 쉬운 경우

 

 

요즘은 컴포넌트화, 모듈화, 캐싱에 대한 관심이 지대하게 높다.

이런과정들을 공부하는 과정에서 '제네릭' 에 대한 이해도가 높아야 좋은 퀄리티의 코드를 작성할 수 있다.

 

이번에는 그중 착각하기 쉬운 상황 1개를 설명하고자 한다.

class Pagination<T> {
  final List<T> data;
  
  ...

 

보통 다양하게 대응하기 위해 제네릭을 사용하는데,

위의 코드를 통해, 보통 T 에 itemModel 이 들어간다고 생각하면,

class Pagination<itemModel> {
  final List<itemModel> data;
  
  ...

이렇게 작성되어 있는 것처럼 동작하겠지 라고 생각하는 친구들이 많다.

 

맞다! 그렇게 동작한다.

그런데, 여기서 더 나아가서

class ItemModel {
  final String id;
  final String name;
  final String description;

  ItemModel({
    required this.id,
    required this.name,
    this.description = '',
  });

  @override
  String toString() {
    return 'ItemModel(id: $id, name: $name, description: $description)';
  }
}



class SubItem extends ItemModel {
  final double price;
  final String category;

  SubItem({
    required String id,
    required String name,
    String description = '',
    required this.price,
    required this.category,
  }) : super(id: id, name: name, description: description);

  bool isOnSale() {
    // 예: 10달러 미만의 아이템은 세일 중으로 간주
    return price < 10.0;
  }

  @override
  String toString() {
    return 'SubItem(id: $id, name: $name, description: $description, price: $price, category: $category)';
  }
}

이렇게

  • 부모 ItemModel 클래스
  • 자식 SubItem 클래스

가 있다고 가정하자.

 

다시 돌아가서,  itemModel 만 들어 갈수 있을까??

class Pagination<itemModel> {
  final List<itemModel> data; //  itemModel 만 들어 갈수 있을까??
  
  ...

 

 

여기서 OOP 에 대한 개념을 잘 이해하고 있는지 확인할수 있다.

  1. 다형성과 제네릭:
    • List<ItemModel> data에는 ItemModel 타입의 객체뿐만 아니라 SubItem 같은 ItemModel의 하위 클래스 객체도 포함될 수 있습니다.
    • 이는 OOP의 다형성 원칙 때문입니다.
  2. 리스코프 치환 원칙:
    • 이는 "자식 클래스의 인스턴스는 부모 클래스의 인스턴스를 대체할 수 있어야 한다"는 원칙입니다.
    • 따라서 List<ItemModel>에 SubItem 객체를 추가해도 문제가 없습니다.

 

위의 OOP 개념에 따라

이렇게 List 의 자료형 인스턴스(itemModel)가 그대로 들어가는것은 당연하고,

List<itemModel> data = [itemModel, itemModel, itemModel]

itemModel 자식 클래스의 인스턴스가 들어 갈수도 있는것이다.

List<itemModel> data = [itemModel, SubItem, itemModel]

 

만약 실제로 데이터가 들어가게 된다면, 이렇게 표현될것이다.

List<ItemModel> data = [
  ItemModel(id: "1", name: "Item 1"),
  SubItem(id: "2", name: "Sub Item", price: 9.99, category: "Electronics"),
  ItemModel(id: "3", name: "Item 3")
];

 

 

이로써 '제네릭'은 자유도가 상당히 높다.

그러므로 로직에 대한 이해와 검토를 반복해서 해야 실수를 줄일수 있을 것이다.

'Flutter > Skills' 카테고리의 다른 글

Throttle 과 Debounce  (0) 2024.12.01
Pagination  (0) 2024.11.05
Unit Test  (0) 2022.12.01
gskinner  (0) 2022.11.22
Dio + Retrofit + JsonSerializable 통한 서버 통신  (0) 2022.11.18