플러터에서 위젯 간에 데이터 전달이나 상호 통신 또는 이벤트 리스너와 같은 역할을 어떻게 할 수 있을까
고민을 하다가 가장 효과적으로 구현할 수 있는 방법을 찾았습니다.
바로 Dart 언어에서 제공하는 mixin을 활용하여
델리게이트 디자인 패턴을 구현하면 시원하게 해결이 가능합니다.
objective-c나 swift의 delegate와도 거의 동일한 패턴입니다.
다음은 실제 활용한 예제이므로 참고 바랄게요.
목차
mixin 클래스 생성
gameTimerDelegate.dart :
mixin GameTimerDelegate {
void gameOver();
}
mixin 키워드로 GameTimerDelegate 클래스를 생성하고 내부에 gameOver 메서드를 선언해 보겠습니다.
믹스인은 인터페이스 또는 추상클래스와 비슷하게 사용이 가능합니다.
내부에는 추상 메서드를 포함할 수 있습니다.
여기서는 이 정도로만 이해해도 무리가 없습니다.
믹스인을 좀 더 깊이 이해하고 싶은 분은 참고 바랄게요.
여러 클래스 공유 및 재사용 특성을 활용하여 이와 같은 계층 구조를 가질 수 있습니다.
아래 링크에서 좀 더 상세한 설명을 볼 수 있습니다.
medium.com/flutter-community/dart-what-are-mixins-3a72344011f3
+내용 추가
다음과 같이 추상 클래스로 선언해도 가능합니다.
abstract class GameTimerDelegate {
void gameOver();
}
상속을 위한 키워드는 with, implements 둘 다 가능합니다.
둘의 차이가 궁금하신 분은 아래 링크 참고 바랍니다.
snowdeer.github.io/flutter/2020/06/13/flutter-extends-and-with/
추상 메서드 구현
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 |
---|
댓글