프로그래밍 & IT 정보/Flutter|Dart

Flutter(Dart) 위젯 간 통신을 위한 델리게이트 디자인 패턴 예제

아미넴 2020. 12. 6.
반응형

플러터에서 위젯 간에 데이터 전달이나 상호 통신 또는 이벤트 리스너와 같은 역할을 어떻게 할 수 있을까

고민을 하다가 가장 효과적으로 구현할 수 있는 방법을 찾았습니다.

 

바로 Dart 언어에서 제공하는 mixin을 활용하여

델리게이트 디자인 패턴을 구현하면 시원하게 해결이 가능합니다.

 

objective-c나 swift의 delegate와도 거의 동일한 패턴입니다.

 

다음은 실제 활용한 예제이므로 참고 바랄게요.

 

목차

     

     

    mixin 클래스 생성

    gameTimerDelegate.dart :

    mixin GameTimerDelegate {
      void gameOver();
    }

    mixin 키워드 GameTimerDelegate 클래스를 생성하고 내부에 gameOver 메서드를 선언해 보겠습니다.

     

    믹스인인터페이스 또는 추상클래스와 비슷하게 사용이 가능합니다.

    내부에는 추상 메서드를 포함할 수 있습니다.

    여기서는 이 정도로만 이해해도 무리가 없습니다.

     

    믹스인을 좀 더 깊이 이해하고 싶은 분은 참고 바랄게요.

     

    [출처] https://medium.com/flutter-community/dart-what-are-mixins-3a72344011f3

    여러 클래스 공유 및 재사용 특성을 활용하여 이와 같은 계층 구조를 가질 수 있습니다.

     

    아래 링크에서 좀 더 상세한 설명을 볼 수 있습니다.

    medium.com/flutter-community/dart-what-are-mixins-3a72344011f3

     

    Dart: What are mixins?

    It’s a kind of magic ✨

    medium.com

     

    +내용 추가

    다음과 같이 추상 클래스로 선언해도 가능합니다.

    abstract class GameTimerDelegate {
      void gameOver();
    }

    상속을 위한 키워드는 with, implements 둘 다 가능합니다.

     

    둘의 차이가 궁금하신 분은 아래 링크 참고 바랍니다.

    snowdeer.github.io/flutter/2020/06/13/flutter-extends-and-with/

     

    Flutter extends vs implements vs with · snowdeer's Code Holic

    Flutter extends vs implements vs with 13 Jun 2020 | Flutter extends extends는 상속을 위해 사용하는 키워드입니다. Dart 언어에서 상속은 오직 하나의 부모만 가질 수 있습니다. 우리가 일반적으로 생각하고 있는

    snowdeer.github.io

     

     

    추상 메서드 구현

    gameBoard.dart :

    import 'gameTimerDelegate.dart';
    
    class GameBoard extends StatefulWidget with GameTimerDelegate {
      // ... 생략
    
      void gameOver() {
        print("game over");
      }
    }

    with 키워드를 사용하여 실제 추상 메서드가 구현되어야 할 클래스에 GameTimerDelegate 클래스를 포함하였습니다.

    그리고 콘솔에 "game over" 라는 메시지를 출력하도록 gameOver 메서드를 구현했습니다.

     

     

    다른 클래스에서 함수 호출하기

    gameTimer.dart :

    import 'gameTimerDelegate.dart';
    
    class GameTimer extends StatefulWidget {
      GameTimerDelegate delegate; // 델리게이트 선언
    
      @override
      _GameTimerState createState() => _GameTimerState();
    }
    
    class _GameTimerState extends State<GameTimer> {
      // ... 생략
    
      void startTimer() {
        // ... 타이머 로직 생략
        
        if (remainingTime < 1) {
          timer.cancel();
          widget.delegate.gameOver(); // 델리게이트를 통해 함수 호출
        } else {
          remainingTime = remainingTime - 1;
        }
      }
    }
    

    델리게이트 구현한 목적이 다른 클래스에서 상호 작용을 하기 위함이었으므로

    특정 조건에서 다른 객체 함수를 수행할 수 있어야 합니다.

    여기서는 GameTimer 클래스를 구현하고 delegate 변수를 선언하여

    타이머가 0초가 되면 gameOver 메서드를 수행하도록 작성하였습니다.

     

     

    상호작용이 필요한 객체 연결하기

    game.dart :

    import 'gameBoard.dart';
    import 'gameTimer.dart';
    
    class Game extends StatefulWidget {
      @override
      _GameState createState() => _GameState();
    }
    
    class _GameState extends State<Game> {
      @override
      Widget build(BuildContext context) {
        final gameBoard = GameBoard();
        final gameTimer = GameTimer();
        gameTimer.delegate = gameBoard; // 객체 연결하기
        return Scaffold(body: gameBoard, floatingActionButton: gameTimer);
      }
    }

    한 객체에서 다른 객체의 메서드를 수행하기 위해서는 두 객체가 서로 연결이 되어야겠죠.

    GameTimer 클래스 객체를 생성하고 delegate 변수에 GameBoard 클래스 객체를 대입하는 방식으로

    두 객체를 연결하였습니다.

    이렇게 되면 GameTimer 객체에서 타이머가 0이 되면

    GameBoard의 gameOver 메서드를 수행하게 되는 것입니다.

     

     

    실행 결과

     

     

    이러한 패턴을 모르면 막막한데 알면 간단하죠?

    여러 상황에서 유용하게 활용할 수 있어 보입니다.

     

    궁금하신 점은 댓글 남겨주세요.

    감사합니다 :)

    반응형

    '프로그래밍 & IT 정보 > Flutter|Dart' 카테고리의 다른 글

    Flutter 유용한 사이트 모음  (0) 2020.07.06

    댓글

    💲 추천 글