Flutter에서의 상속

Carl's Space·2023년 7월 3일

Flutter

목록 보기
1/4
post-thumbnail

들어가며

객체 지향 프로그래밍에서 상속은 중요한 개념이다.
상속을 사용하여 코드의 재사용성과 구조화를 촉진시킨다.

Flutter도 객체 지향 언어로써 상속을 사용한다.
Flutter에서의 상속이란 한 Class에서 다른 Class의 특성과 동작을 받는것을 말한다.
이것으로 인해 자식 Class는 부모 Class의 변수나 메서드 등을 사용하고 확장할 수 있다.

상속을 사용하는 경우

코드의 재사용: 부모 클래스에서 정의한 속성과 동작을 자식 클래스에서 그대로 활용할 수 있다. 자식 클래스는 부모 클래스의 멤버를 재사용하여 반복적인 코드 작성을 줄일 수 있다.

구조화와 모듈화: 상속은 코드를 구조화하고 모듈화하는 데 도움이 된다. 관련된 기능과 속성을 부모 클래스로 그룹화하여 코드의 가독성과 유지보수성을 향상시킨다.

확장성: 상속은 소프트웨어의 확장성을 제공한다. 새로운 요구사항이나 기능이 추가될 경우, 기존 클래스를 수정하지 않고 새로운 자식 클래스를 만들어 기존 동작을 유지하면서 새로운 기능을 추가할 수 있다.

따라서 상속을 사용하면 유지보수가 용이해지며, 확장성 있는 앱을 개발할 수 있고, 전체 코드의 길이가 줄어든다.

상속 위젯의 예시

InheritedWidget

InheritedWidget은 부모 위젯에서 자식 위젯까지 데이터를 상속하고 업데이트하는 위젯이다. 일반적으로 앱의 전역 상태 관리에 사용된다.

class MyData extends InheritedWidget {
  final int value;
  
  MyData({required this.value, required Widget child})
      : super(child: child);

  
  bool updateShouldNotify(covariant MyData oldWidget) {
    return value != oldWidget.value;
  }
}

class MyWidget extends StatelessWidget {
  
  Widget build(BuildContext context) {
    final value = MyData.of(context)?.value ?? 0;
    
    return Text('Value: $value');
  }
}

위 코드에서 statelesswidget은 inheritedwidget의 mydata 클래스를 상속받아서 value값을 만들었다.
아래 코드

MyData.of(context)?.value ?? 0;

가 해당 상속의 구문이다.

Provider

Provider 위젯은 일반적으로 앱의 상위 위젯으로 배치되며, 그 하위에 있는 모든 자식 위젯들에게 상태를 제공한다. 이를 통해 상태 관리를 한 곳에서 중앙 집중적으로 처리할 수 있다. 즉 main.dart(위젯트리의 최상단)에서 아래 자식들에게 상태를 상속할 수 있다. 또한 changenotifier나 valuenotifier등을 사용하여 변동값에 대해 반응할 수 있다.

아래 예시 코드를 보자

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

class Counter with ChangeNotifier {
  int _count = 0;

  int get count => _count;

  void increment() {
    _count++;
    notifyListeners();
  }
}

class MyApp extends StatelessWidget {
  
  Widget build(BuildContext context) {
    return ChangeNotifierProvider(
      create: (context) => Counter(),
      child: MaterialApp(
        home: MyHomePage(),
      ),
    );
  }
}

class MyHomePage extends StatelessWidget {
  
  Widget build(BuildContext context) {
    final counter = Provider.of<Counter>(context);

    return Scaffold(
      appBar: AppBar(
        title: Text('Counter App'),
      ),
      body: Center(
        child: Text(
          'Count: ${counter.count}',
          style: TextStyle(fontSize: 24),
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () => counter.increment(),
        child: Icon(Icons.add),
      ),
    );
  }
}

void main() {
  runApp(MyApp());
}

위 코드에서 ChangeNotifierProvider 위젯은 Counter 클래스의 인스턴스를 생성하여 상태 관리를 제공한다.
해당 상태는

Provider.of<Counter>(context)

Provider구문을 통해 상태를 가져올 수 있고, 해당 상태를 사용하여 UI를 업데이트할 수 있다.

Provider 위젯은 일반적으로 앱의 최상위 위젯인 MaterialApp 또는 CupertinoApp으로 감싸지며, 하위 위젯에서는 Provider.of 또는 Consumer를 사용하여 상태를 사용하거나 갱신한다.

InheritedWidget보다 변화에 능동적이며, 코드를 더 줄이고 싶으면 Provider위젯을 사용하는것이 좋다.

Riverpod

Riverpod은 Provider위젯의 좀 더 세련된 버전이며 원래는 Provider version2로 만드려 했지만 Provider보다 많은것이 달라졌기 때문에 Provider의 철자를 애나그램하여 Riverpod으로 만들었다고 한다.

Riverpod은 상태 관리와 종속성 주입을 위젯 트리 바깥에서 사용할 수 있도록 설계되었다는 것이다. Provider 패키지와는 달리, Riverpod은 상태 및 종속성을 위젯 트리 외부에서도 접근할 수 있게 해준다.

Riverpod의 핵심 개념은 ProviderContainer이다. ProviderContainer는 상태를 관리하고, 상태를 제공하거나 업데이트하는 역할을 수행한다. ProviderContainer는 위젯 트리의 일부로 전달되지 않으며, 위젯 트리 외부에서 생성하고 사용할 수 있다.

이것은 결과적으로 Provider보다 코드의 재사용성을 향상시킨다.

결론

상속을 사용하지 않을수도 있다. 모든 내용을 부모, 자식 클래스에 복사 붙여넣기 하면 된다. 하지만 이런 방식은 개발자를 성장시키지 않는다. 보다 빠른 처리를 위해, 한눈에 알아보기 쉬운 코드를 만들기 위해 상속을 사용해야 한다. 특히 객체 지향 언어인 Dart에서는 특히 그러하다. 좀 더 세련된 위젯을 사용하려고 노력하자.

profile
성장중...

0개의 댓글