(Translated by https://www.hiragana.jp/)
Flutter はプロダクション開発に耐えうるのか / Flutter ready for production? - Speaker Deck
Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Flutter はプロダクション開発かいはつえうるのか / Flutter ready for...

Flutter はプロダクション開発かいはつえうるのか / Flutter ready for production?

Avatar for Daichi Furiya (Wasabeef)

Daichi Furiya (Wasabeef)

October 17, 2020
Tweet

More Decks by Daichi Furiya (Wasabeef)

Other Decks in Programming

Transcript

  1. 現在げんざい 〜 Android アプリ開発かいはつ成熟せいじゅく Activity/Fragment Repository ViewModel LiveData Local Source

    Room/DataStore Remote Data Source Retrofit/okHttp Jetpack Jetpack Jetpack Dagger Hilt Android Studio ここでいう成熟せいじゅくのイメージは アーキテクチャ論争ろんそう、パフォー マンス改善かいぜん手法しゅほう確立かくりつがひと段落だんらく し、それらの知見ちけん一般いっぱんした 状態じょうたいであり、アプリ開発かいはつ(コー ド)の簡略かんりゃく・テンプレートかっていることとする。
  2. Jetpack Compose などの宣言せんげんてきな UI の手法しゅほう ようしたことによるパラダイムシフトと、それによる 今後こんご影響えいきょうは…? MVVM から Flux/Redux/MVU

    のような状態じょうたい管理かんり への移行いこうもあるかもしれない。 宣言せんげんてき UI による VIEW のパラダイムシフト
  3. • アプリ動作どうさ安定あんていせい (クロスプラットフォーム <<= ネイティブ) • 将来しょうらいせい先行さきゆ不安ふあん • iOS/Android で共通きょうつう

    UI(わるくも) • iOS/Android のしん機能きのうへの追従ついしょうおくれ? • Flutter と Kotlin MPP のどちらを採用さいようするか? 課題かだい
  4. 世界せかいてきに200まんにん以上いじょうのエンジニアが Flutter を使つかって いて毎月まいつき10%増加ぞうかしている • 利用りようすう上位じょうい5地域ちいきは インド、中国ちゅうごく米国べいこく、EU、ブラジル • Google

    Play にすでに100,000毎月まいつき10,000以上いじょうの Flutter アプリがアップされている 事例じれい https://medium.com/flutter/flutter-spring-2020-update-f723d898d7af
  5. • 2018 ねん 6 がつサービス開始かいし (Flutter stable 1.0 のリリースは2018ねん 12

    つき) • 担当たんとうアプリエンジニア 2 にん REQU
  6. iOS/Android のしん機能きのうへの追従ついしょうおくれ? たとえば最近さいきんの iOS 14、Android 11 への対応たいおうは Flutter 1.22.0 でも改善かいぜんされ

    ていますし、致命ちめいてきには対応たいおうおくれてないという個人こじんてき感覚かんかくはあるが、かく OS のしん API のインターフェース公開こうかい後追あとおいでるのは事実じじつです。
  7. エンジニアのリソース節約せつやく サーバエンジニア iOS エンジニア Web エンジニア Android エンジニア 一般いっぱんてきな Swift/Kotlin

    アプリのアサインスタイル それぞれいちにん場合ばあい、 コードレビューされない ケースも...
  8. エンジニアのリソース節約せつやく Flutter ͷΞαΠϯελΠϧ サーバエンジニア アプリエンジニア Web エンジニア とりあえず1人ひとり以上いじょういれば iOS/ Android

    アプリ両方りょうほう開発かいはつ可能かのう コードレビューできて結果けっかとして 品質ひんしつ向上こうじょうも。
  9. • Google によって開発かいはつ • 2018 ねん 12 がつリリース (BREAKING CHANGES

    はありえる) • Dart • ステートフルホットリロード (高速こうそく開発かいはつ) • UI ツールキット(豊富ほうふなウィジェット) Flutter
  10. • グラフィックライブラリ • Android, Chrome, Firefox, Blink, Flutter で採用さいようされている •

    Skia は Vulkan をバックエンドエンジンとして変更へんこう可能かのう • Android 9 以降いこう、デフォルトのレンダラーは Skia になってい る(8 と 9 でUIがわったのはそのため)。Flutter にする とレイヤーがえるもののレンダラーはおなじ Skia
  11. 対応たいおうプラットフォーム • Windows 7, 8, 8.1, 10 • macOS 10.10.5

    or later • iOS 8 or later • Android 4.1 (JellyBean) or later • Ubuntu 14.04+, Debian 8+, openSUSE 13.3+, or Fedora Linux 24+ もちろん iOS でも Windows でも動作どうさする Skia
  12. • Swift/Kotlin で体験たいけんをしてしまったエンジ ニアには Dart の言語げんご実装じっそうりない。 (Data class, Nested Class,

    Enum Custom Value, Switch expression, protected, alias..) • アーキテクチャの議論ぎろん活発かっぱつくもわるくも) • かく SaaS の SDK が場合ばあいがある Flutter の難点なんてん
  13. Flutter だけだと解決かいけつできないれいかく SaaS や広告こうこく計測けいそくけいなどの Flutter SDK 対応たいおうってない 場合ばあい自分じぶんでラッパー相当そうとう実装じっそうする必要ひつようがあり、そのとき

    Kotlin/Swift の知識ちしき必要ひつようになる。 • どうしても Flutter からだとコールできない OS がわ機能きのう使つかい たいときには PlatformView を使つかい Flutter アプリないのウィジェッ トの一部いちぶだけをネイティブにすることは出来できるが、DRM などの 一部いちぶ制限せいげんがあるようなものではそれも出来できない。 れい
  14. Flutter だけだと解決かいけつできないれい たとえばこのアプリが Flutter でつくら れてるとして、動画どうが部分ぶぶんに DRM で HW Secure

    Decoder を使つかっている ような場合ばあいには PlatformViewを 使つかったとしても Flutter からだし すのは出来できない。
  15. Flutter <-->- iOS/Android Flutter から MethodChannel API 経由けいゆで iOS/Android がわ

    実装じっそうされた画面がめんをまるごと表示ひょうじ することが出来できるデザインだと 解決かいけつ可能かのうになる
  16. Flutter <-->- iOS/Android ウィジェットの一部分いちぶぶんだけを かく OS がわのものを使つかうのは出来でき ないがかく OS の

    API をだし したり、画面がめんまるごと起動きどうした りは出来できる。
  17. Flutter <-->- iOS/Android Flutter (Dart code) Android (Kotlin code) iOS

    (Swift code) Activity を起動きどう ViewController を起動きどう
  18. iOS (arm32, arm64, simulator x86_64) macOS (x86_64) Android (arm32, arm64)

    Windows (mingw x86_64, x86) Kotlin/Native - Target Platforms Linux (x86_64, arm32, MIPS, MIPS LE, Raspberry Pi) WebAssembly (x86_64)
  19. Flutter か? Kotlin MPP か? • ゼロからつく新規しんきプロジェクト? • 既存きそんプロジェクトのリアーキテクチャ?リプレイス? •

    アプリ開発かいはつてれるエンジニアの人数にんずうは? • エンジニアの技術ぎじゅつレベルかんは?
  20. Flutter か? Kotlin MPP か? • ゼロからつく新規しんきプロジェクト? • 既存きそんプロジェクトのリアーキテクチャ?リプレイス? •

    アプリ開発かいはつてれるエンジニアの人数にんずうは? • エンジニアの技術ぎじゅつレベルかんは? • 安定あんていてき技術ぎじゅつ志向しこうか?リスクをとった挑戦ちょうせん志向しこうか?
  21. Flutter か? Kotlin MPP か? • ゼロからつく新規しんきプロジェクト? • 既存きそんプロジェクトのリアーキテクチャ?リプレイス? •

    アプリ開発かいはつてれるエンジニアの人数にんずうは? • エンジニアの技術ぎじゅつレベルかんは? • 安定あんていてき技術ぎじゅつ志向しこうか?リスクをとった挑戦ちょうせん志向しこうか? • プロジェクト・プロダクトのスケールをつよ意識いしきするか?
  22. Flutter か? Kotlin MPP か? • ゼロからつく新規しんきプロジェクト? • 既存きそんプロジェクトのリアーキテクチャ?リプレイス? •

    アプリ開発かいはつてれるエンジニアの人数にんずうは? • エンジニアの技術ぎじゅつレベルかんは? • 安定あんていてき技術ぎじゅつ志向しこうか?リスクをとった挑戦ちょうせん志向しこうか? • プロジェクト・プロダクトのスケールをつよ意識いしきするか? • とにかくはやくリリースしたい?
  23. Flutter か? Kotlin MPP か? • ゼロからつく新規しんきプロジェクト? • 既存きそんプロジェクトのリアーキテクチャ?リプレイス? •

    アプリ開発かいはつてれるエンジニアの人数にんずうは? • エンジニアの技術ぎじゅつレベルかんは? • 安定あんていてき技術ぎじゅつ志向しこうか?リスクをとった挑戦ちょうせん志向しこうか? • プロジェクト・プロダクトのスケールをつよ意識いしきするか? • とにかくはやくリリースしたい?
  24. Flutter か? Kotlin MPP か?  Flutter   Kotlin MPP  • 新規しんきプロジェクト

    しょう人数にんずう(1〜4にん) • しょう人数にんずうでもりょうプラットフォーム でブランディングの一貫いっかんせいを維 もたしたい • とにかくはやくリリースしたい • よりチャレンジしたい • 新規しんき/既存きそんプロジェクト • 大人おとなすう(10にん〜) • iOS/Androidアプリ開発かいはつせい とおしている • リスクをおさえたい • かくプラットフォームでけて デザインをかかわりたい れい れい
  25. MVVM + Repository View Repository ViewModel Local Source Remote Data

    Source このスライドでは Android エンジニアの馴 みが一番いちばんあるであろう MVVM + Repository を れいとしてげていこ うとおもいます。 MVVM Repository
  26. MVVM UI の実装じっそうにおいて、たとえばテキストを入力にゅうりょくし、バリーデーション、データを保持ほじし、ボタン をタップして、サーバに送信そうしんするようなコードを View にすべ追加ついかしていくと UI が複雑ふくざつに なっていったときにはさらにコードが肥大ひだいしてしまい、それは UI

    とプレゼンテーションロジッ クとビジネスロジックのみつ結合けつごうになっているのでメンテナンスが大変たいへんですし、テストをく が困難こんなんおもえます。 そこで必要ひつようになってくる概念がいねん関心かんしん分離ぶんり (SoC) です。 簡単かんたん説明せつめいす るとすべてのアーキテクチャ共通きょうつうしてえることですが、なにをさせたいのか?その役割やくわりによっ て分離ぶんりした構成こうせい要素ようそとすることです。
  27. MVVM MVVM は Model–View–ViewModel のことをし、その構成こうせい要素ようそ基本形きほんけい以下いかとなっています。 • View は UI (Widget)

    描画びょうが出力しゅつりょく)し、ユーザからの入力にゅうりょくデータをります。 • ViewModel は View から入力にゅうりょくされた状態じょうたい(データ)を適切てきせつ変換へんかんして Model としてちます。 また、Model の状態じょうたい(データ)を View わたして画面がめん更新こうしんうながします。 • Model は状態じょうたい(データ)を保持ほじし、それがどう変換へんかんされて画面がめん描画びょうがされるかはりません。
  28. Repository Repository Local Source Remote Data Source Repository pattern はデータソース

    へのアクセスを抽象ちゅうしょうするためのデ ザインパターンです。ViewModel が つことになりますが、ViewModel がわからすると Repository とデータ の形式けいしきだけをめるだけで、にゅう 手先てさきがサーバからなのか、ローカル の DB なのか、オンメモリなのかな どはりません。
  29. MVVM + Repository View Repository ViewModel Local Source Remote Data

    Source Android で現在げんざい一般いっぱんてきな アーキテクチャは MVVM に Repository Pattern をわせた設計せっけい となっています。 MVVM Repository 
  30. DI/Service Locator View Repository ViewModel Local Source Remote Data Source

    DI/SL クラスあいだみつ結合けつごうらして、 さい利用りようせいたかめるための手法しゅほう。 すごくポピュラーなれいをいうと テストきたいので、テスト ぎょうはサーバ API をたたくので はなくて、モックデータをむような処理しょりえたいがた めに使つかいます。 (テスタビリティの向上こうじょう
  31. おもな DI/Service Locator のパッケージ  InheritedWidget   Riverpod package  • Flutter SDK

    内包ないほう • BuildContext が必要ひつようウィジェットからでも O(1) でオブジェクトが取得しゅとくできる • すこしローレベルなクラス • 有名ゆうめいほう個人こじん開発かいはつあたらしい Provider でシンプル • まだ安定あんていばんではない • いまや Dagger みたいな位置いちづけ • コンパイルセーフ • Flutter に依存いぞんせずにも使つかえる https://github.com/rrousselGit/river_pod https://api.flutter.dev/flutter/widgets/InheritedWidget-class.html
  32. Riverpod https://github.com/rrousselGit/river_pod final myNotifierProvider = ChangeNotifierProvider((_) { return MyNotifier(); });

    class MyNotifier extends ChangeNotifier { int count; /// TODO: typical ChangeNotifier logic } このれいでは ChangeNotifier を継承けいしょうした MyNotifier を Riverpod に管理かんりしても らいます。Riverpod には ChangerNotifierProvider というものが用意よういされてい るので、そこで MyNotifier のインスタンスを返却へんきゃくします。
  33. Riverpod https://github.com/rrousselGit/river_pod class MainPage extends ConsumerWidget { @override Widget build(BuildContext

    context, ScopedReader watch) { final count = watch(myNotifierProvider); return Text(count.toString()); } } Riverpod の ConsumerWidget を継承けいしょうしたウィジェットないであれば、シンプル に監視かんしをすることができます。MyNotifier のわっていれば、この build がさい実行じっこうされます。
  34. State management View Repository ViewModel Local Source Remote Data Source

    DI ぬしに View とViewModel あいだ状態じょうたい共有きょうゆうおこなうことが 目的もくてきとなっています。View がわ状態じょうたいわったことを りたいので ViewModel から通知つうちをもらうようなイ メージになります。
  35. State management そのウィジェットツリーを表現ひょうげんするとこ のようになっており、それぞれクラスが かれていたとします。 [ADD] ボタン自体じたいは MyListItem クラス が制御せいぎょ管理かんりしているので、どうやって

    MyCart クラスに通知つうちするかをかんがえないと いけません。 Observable に該当がいとうする仕組しくみが必要ひつようで す。 https://flutter.dev/docs/development/data-and-backend/state-mgmt/simple
  36. State management https://flutter.dev/docs/development/data-and-backend/state-mgmt/simple そのウィジェットツリーを表現ひょうげんするとこ のようになっており、それぞれクラスが かれていたとします。 [ADD] ボタン自体じたいは MyListItem クラス

    制御せいぎょ管理かんりしているので、どうやって MyCart クラスに通知つうちするかをかんがえないと いけません。 Observable に該当がいとうする仕組しくみが必要ひつようで す。
  37. State management  ChangeNotifier   StateNotifier package  • Flutter SDK に内包ないほう

    状態じょうたい複数ふくすう管理かんりできる • わり自由じゆうにできる • その状態じょうたいは Mutable • 状態じょうたい変更へんこう通知つうちできる • Riverpod にわせて使つかえる • 有名ゆうめいほう個人こじん開発かいはつ • ValueNotifier の進化しんかばん状態じょうたい(state)をひとつだけ管理かんり • その状態じょうたいは Immutable • 状態じょうたい変更へんこう通知つうちできる • Freezed で copyWith を自動じどう 生成せいせいしてもらうとい • Riverpod にわせて使つかえる Android の LiveData のような役割やくわり
  38. ChangeNotifier を継承けいしょうした ViewModel final homeViewModelNotifierProvider = ChangeNotifierProvider( (ref) =>= HomeViewModel(repository:

    ref.read(newsRepositoryProvider))); class HomeViewModel extends ChangeNotifier { HomeViewModel({@required NewsRepository repository}) : _repository = repository; final NewsRepository _repository; News _news; News get news =>= _news; Future<void> fetchNews() async { _news = _repository.getNews(); notifyListeners() } } 全体ぜんたいてきすこしシンプルにしてありますが、HomeViewModel は ChangeNotifier を継承けいしょうします。
  39. ChangeNotifier を継承けいしょうした ViewModel final homeViewModelNotifierProvider = ChangeNotifierProvider( (ref) =>= HomeViewModel(repository:

    ref.read(newsRepositoryProvider))); class HomeViewModel extends ChangeNotifier { HomeViewModel({@required NewsRepository repository}) : _repository = repository; final NewsRepository _repository; News _news; News get news =>= _news; Future<void> fetchNews() async { _news = _repository.getNews(); notifyListeners() } } StateNotifier の場合ばあい管理かんり対象たいしょう状態じょうたいは state を実装じっそう必要ひつようになりますが、ChangeNotifier はとくなにも。
  40. ChangeNotifier を継承けいしょうした ViewModel final homeViewModelNotifierProvider = ChangeNotifierProvider( (ref) =>= HomeViewModel(repository:

    ref.read(newsRepositoryProvider))); class HomeViewModel extends ChangeNotifier { HomeViewModel({@required NewsRepository repository}) : _repository = repository; final NewsRepository _repository; News _news; News get news =>= _news; Future<void> fetchNews() async { _news = _repository.getNews(); notifyListeners() } } Repository で取得しゅとくしたデータを格納かくのうしただけでは、リスナーに通知つうちはされません。
  41. ChangeNotifier を継承けいしょうした ViewModel final homeViewModelNotifierProvider = ChangeNotifierProvider( (ref) =>= HomeViewModel(repository:

    ref.read(newsRepositoryProvider))); class HomeViewModel extends ChangeNotifier { HomeViewModel({@required NewsRepository repository}) : _repository = repository; final NewsRepository _repository; News _news; News get news =>= _news; Future<void> fetchNews() async { _news = _repository.getNews(); notifyListeners() } } notifyListeners() をコールすることで、通知つうちがいきます。
  42. ChangeNotifier を継承けいしょうした ViewModel class MainPage extends ConsumerWidget { @override Widget

    build(BuildContext context, ScopedReader watch) { final news = watch(homeViewModelNotifierProvider); return Text(news.title); } } さきほどの Riverpod の説明せつめいのところで紹介しょうかいしたものとおなじです。
  43. Networking View Repository ViewModel Local Source Remote Data Source DI

    おもに Remote Data Source でサーバの API  をたたくために Endpoint, Header, Token, Body のせい おこないます。
  44. おもな Http client のパッケージ  http package   dio package  • 公式こうしき

    Google が開発かいはつ • メンテは活発かっぱつ • シンプルな Http client で単純たんじゅん なことをやるならこれでも十分じゅうぶん • Flutter China コミュニティ が開発かいはつおも一人ひとり) • メンテが若干じゃっかん不安ふあん機能きのう豊富ほうふで Cancel, Cache や Cookie の制御せいぎょや retrofit like なジェネレータもある • で人気にんきがある https://github.com/flutterchina/dio https://github.com/dart-lang/http
  45. dio + Cache https://github.com/flutterchina/dio # data_source.dart import 'package:dio/dio.dart'; @override Future<News>

    getNews() async { return _dio.get<Map<String, dynamic>>>( '/v1/wasabeef', queryParameters: <String, String>{ 'apiKey': 'VEhJUyBJUyBBUElLRVk', }, options: buildCacheOptions(const Duration(hours: 1)), ) .then((response) =>= News.fromJson(response.data)); } # pubspec.yaml dependencies: dio: ^3.x.x dio_http_cache: ^0.2.x なにかしら分野ぶんやでも Http client を使つかったこと あるひとであれば理解りかいむずかし くないとおもいます。
  46. Serializable/Deserialize View Repository ViewModel Local Source Remote Data Source DI

    とくにサーバ API 通信つうしん使つかい われる送受信そうじゅしんしたデータを シリアライズとデシリアラ イズ。
  47. おもな Serializable/Deserialize のパッケージ  json_serializable package   Freezed package  • 公式こうしきに Google

    開発かいはつ • アノテーションをもと自動じどう生成せいせい • to/from JSON • 有名ゆうめいほう個人こじん開発かいはつ • json_serializable のサポートし ている • アノテーションをもと自動じどう生成せいせい • toString, hashCode.. • copyWith • Immutable https://github.com/rrousselGit/freezed https://github.com/google/json_serializable.dart
  48. Freezed part 'article.freezed.dart'; part 'article.g.dart'; @freezed abstract class Article with

    _$Article { factory Article({ @required Source source, String author, @required String title, @required String description, @required String url, String urlToImage, @required DateTime publishedAt, String content, }) = _Article; factory Article.fromJson(Map<String, dynamic> json) =>= _$ArticleFromJson(json); } このれいでは、@freezed アノ テーションをつけて、 _$Article (自動じどう生成せいせいされるク ラス)の mixin を適用てきようしていま す。 Freezed は json_serializable にも対応たいおうしているので、 _$ArticleFromJson のイン ターフェースも生成せいせいされていま す。 https://github.com/rrousselGit/freezed
  49. Assets/Fonts View Repository ViewModel Local Source Remote Data Source DI

    アプリない画像がぞうやフォ ントなどのファイルを 使つかいたい場合ばあい設定せってい説明せつめいしていきます。
  50. Assets - ローカル画像がぞうファイルへのアクセス # pubspec.yaml flutter: assets: - assets/images/ -

    assets/images/icons/ pubspec.yaml に画像がぞうファイルをいたところのパスを assets: に指定していします。 ディレクトリを指定していした場合ばあいは、そのディレクトリないすべ精査せいさされますが、サ ブディレクトリないまでを再帰さいきてきには精査せいさしません。
  51. Assets - ローカル画像がぞうファイルへのアクセス /// main.dart Widget build(BuildContext context) { return

    Image.asset(‘assets/images/icons/profile.jpg'); } たとえば、Image class にローカルの画像がぞう指定していしたい場合ばあいには以下いかのようにパス を指定していします。
  52. Assets - ローカル画像がぞうファイルへのアクセス /// main.dart Widget build(BuildContext context) { return

    Image.asset(‘assets/images/icons/profile.jpg'); } ただ、文字もじれつ指定していするのはとてもタイプセーフだとえず R.java ってくで きた仕組しくみだなぁってかんじることとなります。。
  53. Fonts - ローカルフォントへのアクセス # pubspec.yaml flutter: fonts: - family: RobotoMono

    fonts: - asset: assets/fonts/RobotoMono-Regular.ttf - asset: assets/fonts/RobotoMono-Bold.ttf weight: 700 きな Fonts を使つかいたい場合ばあいにも pubspec.yaml に指定してい必要ひつようとなります
  54. Fonts - ローカルフォントへのアクセス /// main.dart Widget build(BuildContext context) { return

    Text( 'Hi there', style: TextStyle( fontFamily: 'RobotoMono', ), } フォントもファミリーめい文字もじれつ指定していします。
  55. もしタイポしていた場合ばあい 拡張子かくちょうし間違まちがっていたなどのタイポ(❌ jpeg、⭕ jpg)でも ランタイムエラーになるので、をつけないといけません。 The following assertion was thrown

    resolving an image codec: Unable to load asset: assets/images/profile.jpeg /// main.dart Widget build(BuildContext context) { return Image.asset(‘assets/images/icons/profile.jpeg'); }
  56. FlutterGen /// main.dart Widget build(BuildContext context) { return Image.asset(‘assets/images/icons/profile.jpg'); }

    FlutterGen を使つかえば、コマンドひとつでタイプセーフにクラスを自動じどう生成せいせいします プロモーションをふくみます /// main.dart Widget build(BuildContext context) { return Assets.images.profile.image(); }
  57. Mockito /// Real class class Dog { String sound() =>=

    "Woof"; } /// Mock class class MockCat extends Mock implements Cat {} test('Dog Sound Test', () async { var dog = MockDog(); dog.sound(); verify(dog.sound()); when(dog.sound()).thenReturn("Grrrr"); expect(dog.sound(), "Grrrr"); }); https://github.com/dart-lang/mockito Android アプリ開発かいはつ でもよく使つかわれるモッ クライブラリの Mockito の Dart ばん が Google 公式こうしきとし て公開こうかいされているの で、最初さいしょはこのパッ ケージを導入どうにゅうしてみる ことをおすすめします。
  58. Effective Dart style # main.dart library peg_parser.source_scanner; import 'file_system.dart'; import

    'slider_menu.dart'; # main.dart library pegparser.SourceScanner; import 'file-system.dart'; import 'SliderMenu.dart'; れい:Lower snake case でディレクトリやファイルめいをつけること。
  59.  effective_dart style  Effective Dart に準拠じゅんきょ した Lint ルール Linter, Analyzer

    設定せってい  pedantic style  Google 内部ないぶ採用さいようされ ている Lint ルール  flutter style  Flutter analyze コマン ドで適用てきようされている Lint ルール https://dart-lang.github.io/linter/lints/index.html