次のMVCフラッタープロジェクトICHI.PRO次のMVCフラッタープロジェクトこのMVCプロジェクトテンプレートを使用して、次のFlutterアプリをすばやく構築しますこのzipファイルをダウンロードすると、既製のFlutterプロジェクトが作成されますが、ひねりが加えられています。これは、プロジェクトの起動時に実行されるサンプルアプリと連動しています。ここでの目的は、基盤となるフレームワークがどのように機能するかをよりよく理解できるようにすることです。これは、MVCデザインパターンを利用するフレームワークです。実際、このFlutterプロジェクトテンプレートには2つのサンプルアプリがあります。どちらも、mvc_applicationと呼ばれるMVCフレームワークであるまったく同じライブラリパッケージを使用します。次に、フレームワークは、FlutterのMVCアーキテクチャ実装のコアであるライブラリパッケージmvc_patternを使用します。この他のzipファイルをダウンロードして、サンプルアプリなしでプロジェクトテンプレートのみを取得し、そのプロジェクトを何度も使用して、次のFlutterアプリを作成します。Flutterで動作するように特別に設計されたこのMVCアーキテクチャを最大限に活用するために必要なすべてのファイルとディレクトリを提供します。提供されている他のアーキテクチャとは異なり、Flutterの「上に座る」だけでなく、Flutterで動作します。ある程度Flutterに組み込まれています。このアーキテクチャは、実際にはFlutterフレームワーク自体が提供する多くのクラスと高レベルの関数を使用しています。独自のAPIを課そうとはしませんが、代わりに、基盤となるFlutterフレームワークにある多くのパラメーターと関数の名前を共有します。すべてのFlutterアプリに一般的に必要な機能と機能を提供する、人気のあるライブラリパッケージの多くをインストールして操作します。共有設定機能はすぐに使用できます。最後に、広範なエラー処理機能が最初から開発者に提供されます。確かに、プロバイダーフレームワークはGoogleによって公式にサポートされていますが、他のフレームワークと同様に、プロバイダーは既存のFlutterフレームワークの上に、独自のAPIを備えた非常に独立したレイヤーを配置しています。したがって、それを操作するには、まったく新しいクラスのリスト(「Providerthis」および「Providerthat」)を学習する必要があります。それらすべてのFlutterプロバイダーを理解するそして、私はReduxを使い始めません。皮肉なことに、Flutterに切り替えたときに最初に使用したアーキテクチャでした。Flexに基づいており、もともとJavaScriptで考案された、Reduxは、大規模なWebサイトだけでなく、facebook.comという巨大なWebサイトでも機能するように開発されました。これは、数千とは言わないまでも数百の開発者が長期にわたって簡単に保守できるように設計されています。したがって、本質的に精巧なメッセージングシステムであるものを構成する多くの「アクション」および「リデューサー」の使用。これをFlutterに課すと、ボイラープレートの「重量」によって作業が滞ります。Reduxはモバイル開発用に設計されていません。このMVCフレームワークを使用するには、3つのことを行います。StatefulWidgetでは、従来のStateクラスの代わりにStateMVCクラスを使用します。ご存知かもしれませんが、MVCデザインパターンの「ビュー」部分(インターフェイス)として機能します。次に、クラスControllerMVCを拡張して、すべてのビジネスロジックを含めます。デザインパターンの「コントローラー」部分です。最後に、そのControllerオブジェクトをStateMVCオブジェクトに渡して、ControllerがStateオブジェクトのすべての機能やプロパティなどにアクセスできるようにし、アプリのライフサイクルにフックします。Android開発者はそれが何を意味するのかを理解します。MVCを選んだのですか?この記事の終わりまでに、特にMVCがなぜであるかがわかることを願っています。その理由はたくさんあります。何よりもまず、あらゆるデザインパターンに従うことには利点があります。それは実際には、Flutterフレームワークが独自の「状態管理」の舞台裏で使用するメカニズムそのものに帰着しました。することで、Flutterは携帯電話だけでなく、デスクトップコンピューターやWebでもすぐに機能するようになります。間違いなく、あなたが最初にFlutterをいじり始めたとき、あなたはうっかりしてその迷惑な「不変の」メッセージを出させました。特定のStatefulWidgetの以下の2つのスクリーンショットを見ると、私が何を意味するかがわかります。インスタンス変数titleをfinalとして宣言する必要があることを警告しています。今、そのようなメッセージを無視することはノーノーです。あなたは、Flutterが独自の状態管理の取り組みで使用する手段そのものを妨げています。コードは確かに機能しますが、そうすることでFlutterアプリの全体的なパフォーマンスが実際に低下します。典型的なFlutterアプリのライフサイクルで、StatefulWidgetとStatelessWidgetが何度も作成される頻度に気づいていません。これらはFlutterアプリの「構成要素」であり、常に使用されるため、このようなオブジェクト内のすべてを静的、不変、不変に保つことが最適です。説明するこの「ペイウォール」の記事があります:FlutterのStatefulWidgetとそのライフサイクルの詳細。最初は、それはすべての可変のもの、すべての「根性」、特定のアプリのすべてのロジックをアプリのStateオブジェクトに格納する必要があることを意味します。Stateオブジェクトのコードで呼び出されるDartファイルに保存する必要があります。これは、Stateオブジェクトにあるbuild()関数内のコードによって呼び出されるDartファイルに保存する必要があります。その結果、かなり「忙しそうな」状態オブジェクトが生成されます。繰り返しになりますが、コードの多くを別のDartファイルに配置することは、Javaとは異なり、Dartを使用するときに特定の能力を持っているためです。図書館です!「Javaなどの一部の言語は、ファイルの編成をクラスの編成に結び付けます。各ファイルは、単一の最上位クラスのみを定義できます。Dartにはその制限はありません。」—効果的なダーツ:デザインDartファイルはライブラリファイルと呼ばれます。同じファイルでいくつでもクラスを宣言できるからだと思います。それは巨大です!1つのDartファイルには、任意の数のクラス、任意の数の最上位変数、および任意の数の最上位関数を含めることができます。それが一番大きいです!(言葉?)それは強力です!これは、ソフトウェアの側面をより管理しやすい部分に分割するなど、産業用の強力なアプリを作成するのに非常に役立ちます。MVCの場合と同様に、「データ」を「インターフェース」および「ロジック」から分離します。これは基本的にすべてのアプリを構成します。これらのプロジェクトテンプレートを使用して作業するときに得られるものを紹介することで、さらに説明するために「長い道のり」を取ります。以下は、インストールされたプロジェクトテンプレートの一連のスクリーンショットです。このアーキテクチャでは、アプリのデータ、アプリのインターフェース、アプリのロジックを区別するために、ファイルやフォルダーの「model-view-controller」ラベルが一貫して表示されます。これがMVCアーキテクチャの特徴です。次に、コードを入力して次のFlutterアプリを作成します。フレームワークは基盤ですフレームワークはあなたに仕えることです。アプリの作成をはるかに簡単にすることです。フレームワークは構造を提供することです。これは、迅速な開発を可能にする一貫したアプローチを伝えることでありながら、個々のアプリの固有の要件に適応することです。このようなフレームワークを使用すると、効率的なコードの再利用が促進され、並列開発が可能になります。それはあなたのコードを整理する方法を提供し、それはいくつかの適合性といくつかの一貫性を提供します。開発者がそのようなアーキテクチャに精通していると、進行中のプロジェクトに立ち入り、すべてのコードがどこにあり、どのコードが何を実行するかを正確に知ることができます。新しい開発者は、「着実に実行する」ことができます。読者がMVCデザインパターンとそれがFlutterでどのように使用されているかをすぐに理解していない場合。FlutterのMVCと呼ばれる補足記事があり、このテーマに関して現在利用可能なすべての記事がリストされています。これは、現在Flutterコミュニティに提供されているMVC解釈について読者を「スピードアップ」させるのに役立ちます。スクリーンショットのみ。要旨をクリックします。いつものように、私は記事にコードを表示するだけでなく、要点よりもスクリーンショットを使用して概念を表示することを好みます。私はそれらが扱いやすく、読みやすいと感じています。それらをクリック/タップすると、要点またはGithubでコードを表示できます。皮肉なことに、携帯電話よりもコンピューターでのモバイル開発に関するこの記事を読む方が良いでしょう。その上、私たちは主にコンピューターでプログラムします。私たちの電話ではありません。動画もソーシャルメディアもありませんこの記事には、目前のトピックの側面を示す多数のgifファイルがあります。InstagramやFacebookなどのプラットフォームでこの記事を読む場合、このようなgifファイルを表示することはできないと言われています。これに注意し、medium.comでこの記事を読んでください。グレッグペリーによる他の物語メイン()関数は、フラッタアプリの出発点です。プロジェクトテンプレートはそれを提供し、ほとんどの場合、それを訪問する本当の理由はありません。それはすべて行く準備ができています。プロジェクトテンプレートのmain.dartファイルのスクリーンショットを以下に示します。runApp()関数と、すべてのクラス参照が1つのインポートステートメントからのものであることがわかります。フレームワークがMVCデザインパターンを最初から実装していることがわかります。これは、実際にコードの記述を開始してアプリの構築を開始するクラスMyViewであるためです。main.dart注、runApp()関数は、直接あなたのアプリとなります「表示」(インタフェース)を呼び出す代わりに、ここであるクラス、MyAppを、取り込んでいない「アプリレベル」。これはフレームワーク自体のビューであり、必ずしも特定のアプリである必要はありません。ご覧のとおり、Flutterアプリをセットアップするには、常に多くの準備が必要です。すべてが行われるのはこのレベルです。テンプレート全体で、nullを渡すだけで、使用可能なすべてのパラメーターが強調表示されることに注意してください。無視したり、必要に応じて削除したりすることもできますが、これも行われるため、そこにあるものや利用可能なものを簡単に確認できます。この時点では、アプリは起動時に表示されるロード画面のみに関係します。エラー処理が最初から最も重要であり、最後の3つのパラメーターは、エラーが発生した場合の応答方法と表示内容を扱います。他の優れたフレームワークと同様に、そのようなパラメーターが明示的に値を受け取らない(またはnullが渡される)場合、ロード画面は表示されず、デフォルトのエラールーチンが使用されます。繰り返しになりますが、代わりにMyViewクラスに注意が向けられる可能性があります。MVCのVCMここmain.dartファイルにとどまり、フレームワーク全体で見られる一般的なパターンを紹介します。これは、コミュニケーションのラインと、その結果として、このMVCデザインパターンを使用してアプリを構成する3つの側面間のワークフローに関するものです。多くの場合、モデル(データ)コンポーネントはパラメーターとしてコントローラー(イベントロジック)コンポーネントに渡され、コントローラー(イベントロジック)コンポーネントはパラメーターとしてビュー(インターフェイス)コンポーネントに渡されます。ビューはコントローラーと「通信」できます。コントローラはモデルと「通信」できます。ここでもmain.dartファイルから始まります。クラスMyAppがクラスAppを拡張していることがわかります。これも、「アプリレベル」のViewコンポーネントです。main.dartファイルでは一般的ではありませんが、このViewオブジェクトでさえ、コントローラーをパラメーターとして取り込むために、conという名前のパラメーターがあります。右下のスクリーンショットでは、main.dartのバリエーションを使用してこれを示しています。nullを渡す代わりに、パラメーターconは、フレームワークControllerクラスAppConMVCを拡張するAppConというクラスのインスタンスを受け取ります。最後に、MVCデザインパターンのこの解釈はStatefulWidgetをビューの一部として指定するため、パラメーターkeyは、そのようなオブジェクトのパラメーターのリストで常に使用可能になります。繰り返しますが、エラー処理はMVCフレームワークの最も重要な責任です。率直に言って、どのフレームワークにも当てはまるはずです。このため、独自のrunApp()関数もあります。runAppあなたはmain.dartファイルで参照()関数は、上記であなたがしているお馴染みのものではない-それは、フレームワークのバージョンです。元のrunApp()関数を呼び出しますが、エラー処理ルーチンでそれとアプリ自体をラップする前ではありません。以下の右側のスクリーンショットは、フレームワークのrunApp()バージョンです。他の優れたフレームワークと同様に、その事実はすぐには宣伝されず、代わりに開発者はアプリの構築に取り掛かることになります。人気のあるライブラリパッケージであるCatcherと同じアプローチであるため、多くの人が実装を認識しているかもしれません。main.dartおよびapp.dartビューをインポートするmain.dartファイル内のその唯一のインポートステートメントをもう一度見てみましょう。そのパスを調べると、このDartファイルがsrcフォルダーの下にあることがわかります。ご存知かもしれませんが、Dartでは、srcフォルダー内のそのようなファイルはlibフォルダー内のファイルのように公開されていません。このMVCアーキテクチャでは、ファイルview.dartは、アプリのビューまたはインターフェースに関係しています。そのファイルの内部を簡単に確認します。上記のスクリーンショットの最初のエクスポートステートメントは、MVCフレームワーク自体に直接ある「ビューファイル」を参照していることに注意してください。main.dartファイルでrunApp()関数とクラスAppを提供したのはそのファイルであることに注意してください。上記の残りのエクスポートステートメントは、このプロジェクトに固有のものです。この記事では、それぞれを順番に訪問します。アプリのビューmain.dartファイルに戻って、クラスMyAppを調べました。クラスMyViewを見てみましょう。Flutter自身の関数createState()に敬意を表して。MyViewクラスを使用すると、アプリのインターフェースを広範囲に設定できます。以下のスクリーンショットでは、このクラスが含まれているファイルと、srcファイルview.dartのどこで参照されているかを確認できます。これはアプリ全体に関係しているため、appフォルダーの下にあります。そのファイル名もview.dartです。これらの「インポートファイル」を多くのエクスポートステートメントとともに使用することは、Google自体が推奨するアプローチであることに注意してください。ここで車輪の再発明はありません。アーキテクチャは常にFlutter独自のアプローチに沿ったものにしようとします。エクスポートステートメントの詳細については、ライブラリパッケージを整理するドキュメントを参照してください。main.dartとview.dart以下は、クラスMyViewのスクリーンショットです。繰り返しになりますが、多くの名前付きパラメーターは、単にあなたの利益のために、冗長なnull値とともにリストされています。このフレームワークをFlutterとスムーズに統合するための努力に合わせて、MaterialAppウィジェットまたはCupertinoAppウィジェットに渡すパラメーターとして認識されるパラメーターの多くがあります。view.dart以下のスクリーンショットでわかるように、MyViewクラスはクラスAppViewを拡張します。繰り返しますが、これはMVCのViewコンポーネントです。したがって、名前付きパラメーターconを使用してControllerオブジェクトも取り込みます。これは、特定のアプリのコントローラーです。この「アプリコントローラー」をざっと見てみましょう。view.dartおよびapp.dart上の右側のスクリーンショットでは、フレームワークのAppViewクラスが表示されています。Controller'がない場合、フレームワークは代わりにAppControllerと呼ばれるものを取り込みます。そのコントローラーは何をしますか?その目的は、Flutterアプリで一般的に必要とされる関数と機能を初期化することです。以下のスクリーンショットでは、デフォルトのAppControllerがアプリの保存された設定機能を提供していることがわかります。あなたはそれがその中で物事を設定します見ることができますinitAsyncその中まで()関数とクリーンなものにdisposeアプリをシャットダウンして()関数。initAsync()関数をオーバーライドして、アプリを起動する前に実行する必要のあるすべての「非同期」操作を実行する必要があります。initApp()と呼ばれる別の関数を使用して、アプリの起動前に実行する必要のあるすべての「同期」操作をオーバーライドして実行できます。最後に、これらの関数を呼び出すAppクラス(main.dartで導入)のスクリーンショットを右側に示します。main.dartファイルで最初に紹介されたcreateView()関数も確認できます。これがどのようにまとめられているかわかりますか?繰り返しになりますが、これはフレームワークであるため、ここで内部の動作を知る必要はありません。すべてのFlutterアプリに必要な多くの「重労働」を行っていることを知っておいてください。app.dartおよびapp.dart他の優れたフレームワークと同様に、アプリのニーズに固有の「機能と機能」を指定する独自の「アプリコントローラー」を自由に作成できます。これまでにない機能をアプリに提供するでしょう。あなたのアプリは大成功を収め、名声と幸運へと駆り立てます!ただし、気にしない場合は、フレームワークが代わりに、一般的なアプリに必要な基本的な機能の一部を提供します。以下の残りのスクリーンショットは、「MyView」クラスを操作するときに使用できる多くの関数です。これは、クラスAppViewを拡張し、アプリの「ルックアンドフィール」の設定に関して非常に特別なことを可能にします。以下にリストされている多くは、クラスAppViewに渡すことができる多くのパラメーターの「機能的同等物」であることがわかります。これは、他の優れたフレームワークと同様に、特定の値をそれらの多くのパラメーターに渡すために使用するロジックを予測できないため、それを可能にする同等の関数を提供するためです。以下は、名前付きパラメーターtitleを含む簡単な例です。これは、このMyViewクラスにある数少ないパラメーターの1つであり、正当な値が渡されます。以下に、それがかなり単純な値であることがわかります。タイトルをパラメーターとしてAppViewクラスに明示的に渡す代わりに、関数onTitle()をオーバーライドして、その方法でタイトルを作成することもできます。右側のスクリーンショットは、MVCフレームワークの奥深くにあるコードです。パラメータとしてタイトルに渡された値がないか、タイトルを生成するために記述された関数がないかどうかを確認できます。代わりに空の文字列が提供されます。この配置は、他のほとんどのパラメーターでも使用できます。view.dartおよびapp.dartしたがって、このプロジェクトテンプレートを使用するときに使用できるすべての関数はオーバーライドされ、単にnullを返します。このテンプレートを使用して独自のアプリを実装する場合は、使用しない関数のすべてではないにしてもほとんどを削除することをお勧めします。不要な雑然としたものをクリーンアップします。フレームワークに慣れてきたら、MVCプロジェクトテンプレートを提供する代わりの方法があると期待されていることに注意してください。IDE自体に統合されており、マウスをクリックするだけで新しい「MVCFlutterプロジェクト」を作成できます。私がそうしなければ、他の誰かがそうすることを望んでいます。これについては後で詳しく説明します。繰り返しになりますが、以下のスクリーンショットは、MyViewクラスを操作するときに使用できる関数を示しています。いつものように、スクリーンショットをタップまたはクリックして、その要点またはGithubの同等物を調べることができます。このフレームワークは本当に多くの「パラメータテスト」と「潜在的な機能」であることに気付くでしょう。それがフレームワークのすべてです。内側が醜く、外側がなめらかで、開発者の生活が楽になります。view.dart繰り返しになりますが、Flutter自体、MaterialAppウィジェットおよびCupertinoAppウィジェットにますます慣れてくると、ここにリストされているすべての関数で何ができるかがすぐにわかります。すれば、必要が生じたときにそれらをうまく利用できます。view.dartview.dartview.dartはい、たくさんあります。これは優れたフレームワークのもう1つの属性であり、開発者には多くのオプションがあります。view.dart家に帰る独自のFlutterアプリでは、MaterialAppウィジェットまたはCupertinoAppウィジェットのホームパラメーターでウィジェットを指定したことは間違いありません。これはクラスMyViewにあり、ここでも名前付きパラメーターhomeにウィジェットを提供します。ここで、アプリの「最初の画面」がインスタンス化され、最終的に表示されます。ご覧のとおり、ホーム画面が最初に表示される前に、多くのことが舞台裏で行われます。MaterialAppウィジェットまたはCupterinoAppウィジェットの操作に精通している場合、このフレームワークは、まったく同じ名前のパラメーターを提供する基盤となるFlutterフレームワークと「連動する」ため、このクラスをうまく操作できます。このテンプレートで使用されている「ホーム」ウィジェットに関しては、空のコンテナウィジェットを表示するシェルにすぎません。それほど多くはありません。テンプレートは、実際には単なるプレースホルダーとして提供します。MyHomeクラスを見ると、AndroidプラットフォームとiPhoneプラットフォームの両方のインターフェイスを分離するアプローチが提供されていることがわかります。プラットフォームごとに2つの別々のStateオブジェクトを作成する必要があります。これは単に提案されたアプローチであることに注意してください。このテンプレートを自分で使用する場合は、アプリのメイン画面を作成する過程で、このStatefulWidgetとそれに付随するStateオブジェクトをすべてのコードで完全に上書きするという考え方です。MVCに沿って、コードはその時点でのアプリのインターフェースのみに関係する必要がありますよね?view.dartとview.dartたとえば、上のスクリーンショットに表示されているStateオブジェクトの1つを見てみましょう。MyAndroidと呼ばれるものを見ていきます。以下のスクリーンショットでは、クラスStateMVCを拡張していることがわかります。この名前は、MVCアーキテクチャの一部であることを示しています。それはStateオブジェクトのようなものですが、それ以上のものです。ご存知かもしれませんが、MVCデザインパターンのこの解釈では、Stateオブジェクト内のbuild()関数は、MVCデザインパターンで「ビュー」と見なされるものを返します。したがって、すべての意図と目的のために、このフレームワークのすべてのStateオブジェクトは「View」オブジェクトです。クラスStateMVCを拡張すると、従来のStateオブジェクトなどを構成するすべての関数と機能が保持されます。以下のスクリーンショットを確認してください—対応する要点またはGithubコピーのスクリーンショットをタップまたはクリックしてください。親クラスStateMVCのdispose()関数をざっと見ると、「ビュー」であるStateオブジェクトとそのすべてのコントローラーの間の「依存関係」がわかります。この特定のStateオブジェクトのdispose()関数を呼び出すときに事実を強調するために、ほとんどのコードをコメントアウトしました。関連付けられているすべてのコントローラーのすべてのdispose()関数を呼び出しています(存在する場合)。終了時のStateオブジェクトも、アプリの元のエラールーチンに戻ることに注意してください。必要に応じて、各Stateオブジェクトに専用のエラー処理を含めることができます。あなたは私がエラー処理に長けていると言うことができます。mvc_pattern.dartしたがって、MVCアーキテクチャを構成する3つのコンポーネントに関するプロトコルに沿って、すべてのビューがコントローラーを取り込むことができます。MyAndroidクラスでは、例外はありません。以下に、想像を絶するコントローラーと呼ばれるコントローラーがインスタンス化され、ViewオブジェクトMyAndroidに渡されることがわかります。android.dartViewオブジェクトMyAndroidにあるすべての関数は、再び...Controllerと呼ばれるControllerにあります。このControllerクラスを見てみましょう。以下のスクリーンショットは、MVCクラスControllerMVCを拡張していることを示しています。これはオプションですが、ファクトリーコンストラクターがそこで使用されていることに気付くでしょう。私自身の経験では、コントローラーのインスタンスを複数持つ理由はなかったので、コントローラーは常にファクトリーコンストラクターを使用していました。ここにあるすべての関数は、MyAndroidクラスにもあります。この場合も、StateMVCオブジェクトは、独自の関数の1つが呼び出されると、すべてのControllerオブジェクトを順番に呼び出します。このような配置により、コントローラーは従来のStateオブジェクトのすべての機能(setState()やBuildContextなど)を使用できます。各コントローラーは、その状態オブジェクト自体のライフサイクルとエラーハンドラーも利用します。各コントローラーは、渡された「最後の」ビューオブジェクトへのアクセス、プロパティ、および機能を備えています。1つのビューに一度に必要な数のコントローラーを含めることができます。コードを個別のコントローラーに分割すると、MVCに対する一般的な批判である「コントローラーの肥大化」が軽減されます。1対多および後入れ先出しcontroller.dart例によってフレームワークを学ぶプロジェクトテンプレートの2番目のzipファイルをダウンロードすると、MVCフレームワークの多くの機能を活用する方法を示す2つの実用的な例が得られます。違いのあるメインこのサンプルテンプレートを開くと、main.dartファイルにももう少しコードがあります。これは、ここのmain()関数で「アプリコントローラー」が必要になる可能性がある数回のうちの1つを示すためのものです。この場合、「ホットリロード」を使用してAndroidインターフェイス(マテリアル)とiOSインターフェイス(クパチーノ)を切り替えます。ここで示すもう1つの要件は、「ホットリロード」を使用してまったく新しいアプリに切り替えることです。この場合、それはGoogleがFlutterGalleryパッケージで提供しているShrineサンプルアプリです。私は知っています、素晴らしい例ではありません。本番環境ではホットリロードが利用できないのに、なぜこのような機能が必要になるのでしょうか。私はこの記事を書いているときにこれを考えました。私を放っておいて...続けます。右側の2番目のスクリーンショットでは、コメントを削除しただけで、パラメーターにnullが渡されています。このテンプレートを使い始めたときにコードが乱雑になることはないので、削除しました。main.dartでは、これはどのように機能しますか?以下の右下に表示されているgifで、サンプルアプリの動作を確認できます。表示される「インターフェースの切り替え」は、適切な切り替えが切り替えられた後のこのプロジェクトサンプルの「ホットリロード」の結果であることに注意してください。createView()関数でインスタンス化されたAppConオブジェクトは、これをすべて可能にする基本的な要素です。これは、上のスクリーンショットでわかるように、多くのAppConのプロパティがcreateView()関数で参照されているためです。推測していない場合は、「ホットリロード」によってそのcreateView()関数が再度呼び出されます。これらのプロパティは、どこかで切り替えられたスイッチによって設定され、出来上がりです。—インターフェイスはそれに応じて変更されます。createView()関数には、次のステートメントがあります。{controller.dartホットリロード時ホットリロードでは、MyViewクラス(AppViewを拡張する)はStateオブジェクトであり、その結果、そのreassemble()関数が呼び出されます。以下のその関数のスクリーンショットは、Appクラスのブールプロパティがtrueに設定されていることを示しています。Stateオブジェクト)が再構築されることです—そのbuild()関数を再度呼び出します。そのクラスのスクリーンショットを以下に示します。ビルド()関数は、その呼び出しますinitAsync再び()関数を。アプリのプロパティ_hotReloadをtrueに設定した関数では、関数createView()が再度呼び出されていることがわかります。その機能を覚えていますか?はい、main.dartファイルでその関数を最初に見ました。これがどのように機能するかを見てみましょう。AppConコントローラオブジェクトがへの追加の呼び出しにもかかわらず、工場出荷時のコンストラクタでインスタンス化されているので注意がCREATEVIEW)(、コントローラは、コントローラのプロパティ値は、その新しい設定で保存されていることをすべてやり直すので、インスタンス化されていません。app.dart別の見方サンプルテンプレートのコピーは、最初に起動したときに「連絡先」サンプルアプリを実行します。これは、元のMyAndroidクラス(以下を参照)をコメントアウトし、連絡先アプリで実際に見つかったStateオブジェクトを返す関数に置き換えるだけで実行できます。確かに、これは私が探していた効果を達成するための迅速で汚い方法です。それは確かに推奨されるアプローチではありません。これは、MVCフレームワークをさらに実証するのに役立つだけです。android.dartMyHomeクラスでは、MyAndroid()関数がStatefulWidgetで参照されます。繰り返しになりますが、理想的ではありませんが、これにより「連絡先」インターフェースが得られ、「サードパーティ」がこのプロジェクトに統合されます。android.dartコントローラを作成するわかりました、それは私が物事の「ビュー」側で物事を仮帆装する方法です。コントローラー側でも同じ効果が得られたと思いますが、よりエレガントなアプローチでした。オブジェクト指向プログラミング言語での作業に関しては、コンポジションは認識されており、実際、継承の代替として推奨されています。皮肉なことに、ここでの使用は実際には少しやり過ぎです。このプロジェクトテンプレートを使用するときの本来の目的は、独自のアプリに関連するすべてのコードでこのクラスを「上書き」することです。Compositionは、デモンストレーションの目的でサードパーティを統合するためにここで使用されます。そのため、以下のコントローラーは、コンストラクターでContactsという別のコントローラーをインスタンス化し、対応するすべての関数とプロパティでそのコントローラーを使用します。下のスクリーンショットをタップまたはクリックして、自分の目で確かめてください。controller.dart繰り返しになりますが、Contactサンプルアプリ(以下を参照)を構成するディレクトリとファイルを見るだけで、それ自体が自己完結型のアプリであることがわかります。MVCデザインパターンを使用しています。一見すると、独自のmain.dartファイル、独自の画面、独自の「ビジネスロジック」、および独自のデータがあることがわかります。あなたはあれが見えますか?連絡先アプリモデル構成サンプルアプリのContactsにはデータベースがあります。処理するデータがあります。MVCデザインパターンを使用しているため、モデルコンポーネントが関係しています。コントローラと同様に、下のスクリーンショットで、Compositionを使用してContactアプリの独自のモデルをこのテンプレートの対応するモデルに導入したことがわかります。このモデルのすべての関数は、Contactアプリ自体のModelクラスにある関数をミラーリングして、同じ機能を実現します。model.dart1つのインポートで多くのインポート上のスクリーンショットの1つのインポートステートメントに注意してください。理にかなっています—データを含むすべての「インポートファイル」です。したがって、model.dartという名前になります。andShrineサンプルアプリにあるすべての「dataelement」を取り込むための追加のエントリがあると推測できます。ここでの考え方は、その1つのインポートステートメントをそのままにしておくことです。新しい機能はすべて、Dartのimportステートメントを使用してプロジェクトに導入され続けますが、それはすべて、その1つの「インポートファイル」model.dartで行われます。上記のクラスのコード(および時にはそのコードに取り組んでいる開発者)は賢明ではありません。これにより、コードの開発と保守に対するモジュラーアプローチが促進されます。以下は、空のFlutterプロジェクトテンプレートと2つのサンプルアプリを含むこのテンプレートの両方のモデル「インポートファイル」の内容です。一目で、何が何であるかを見ることができます。2番目のプロジェクトには追加の「データ関数と機能」があるため、2番目のファイルには追加の行があります。model.dartおよびmodel.dartマシンのモデルこのようなファイルでは、最初の2行がよく見られることに注意してください。最初の行は、MVCフレームワーク自体からすべての「モデルのもの」をインポートします。これは、開発者が独自のFlutterアプリでデータベースやファイルなどを操作するときに、一般的に役立つ機能です。そのファイルのスクリーンショットを以下に示します—あなたが知っているすべてのグッズを見てください。次のインポートステートメントは、このプロジェクト自体のモデルファイルです。このようなモデルの「インポートファイル」を作成する場合、独自のモデルファイルで定義した関数や機能が必要な場合は、インポートコマンドを使用してそのファイルをアプリの任意の部分に含めることができます。'package:your_project/src/model.dart';model.dartiOS側ちなみに、これのiOS側では、連絡先アプリのiOSインターフェイスをこのテンプレートに統合する際にさらに別のアプローチが取られていることに気付くでしょう。このアプリのビューでは、Contactsiosフォルダー内の要素がちらほらと表示されていることがわかります。ios.dart上のスクリーンショットをタップまたはクリックしてクラス全体を表示すると、強調表示された要素が実際に連絡先アプリに表示されていることがわかります。scaffoldKeyは、連絡先アプリ自体のコントローラーのプロパティです。この記事のフォローアップは、FlutterのMVCという記事で、レビュー用のサンプルアプリContactsの内部動作についてさらに詳しく説明しています。フラッターへのMVCアプローチpubspec.yaml以下は、2つのプロジェクトテンプレートのpubspec.yamlファイルのスクリーンショットです。最初のものは「空の」プロジェクトテンプレートに属しています—その唯一の一意のエントリはMVCフレームワークライブラリパッケージです。2つのサンプルアプリを含む2番目のファイルには、ライブラリパッケージのエントリがさらに5つあります。そのうちの2つも書いています—もし私がそんなに大胆になれたら。pubspec.yamlとpubspec.yaml[新しいMVCフラッタープロジェクト]をクリックしますあなたが知っている、私はもっとうまくいくことができます。昨年、AndroidStudioで「NewMVCFlutterProject」というファイルオプションを作成する方法について、うさぎの穴を掘り下げて1か月を過ごしました。...」テンプレート/ウィザードを担当していたPhilQuitslundに連絡を取りました。同様のオプションを提供するために必要な多大な努力にすぐに感謝するようになったので、別のアプローチに目を向けました。私は今、今井知明の「Androidベストプラクティステンプレート」アプローチのようなものを見ています。彼は、特定のフレームワーク構造に準拠したAndroidStudioの「NewProject...」オプションの下に新しいAndroidプロジェクトを含めています。それは私自身の追求に馴染みがあるように見えます。Androidのベストプラクティステンプレートこれにより、提供する次のAndroidプロジェクトの効果的なボイラープレートに必要なすべてのファイルとディレクトリ、および必要なすべての「プラットフォーム固有の」ファイル(AutoMandfest.xmlファイルなど)が作成されます。Androidのベストプラクティスのレイアウトいくつかのmedium.comの記事は、出発点として適しているようです。AndroidStudioテンプレートの作成をマスターする方法とAndroidStudio用のMVPテンプレートを使用して開発をスピードアップする方法。私は現在圧倒されているので、これを別のものに「委任」したいと思います。興味があれば—私に知らせてください。このすべての終わりに、私は何もしていません。MVCフレームワークのリリース以降に寄せられた多くの肯定的なフィードバックに永遠に感謝しています。MVCデザインパターンであるコンセプトとFlutterのアプローチを組み合わせただけです。当初からの意図は、低い学習曲線を確保することでした。実際、これをすべて可能にしたのは、Flutterを考案したGoogleチームでした。MVCが約40年前に行われることを思いついたTrygveReenskaug。そのため、最初にFlutterに目を向けたとき、現在提供されているアーキテクチャソリューションを確認するときに一歩下がらなければなりませんでした。ご覧のとおり、彼らが「状態管理」という用語を使い始めたのは約18年前のことです。インターネット上で実行できる「Webアプリ」の登場とともに登場しました。これは、当時のより困難なタスクの1つが、そのようなアプリのライフサイクル中の「状態の永続化」であったためです。「状態管理は、ラウンドトリップ間でWebページの状態を維持するプロセスです。HTTPプロトコルの切断された性質のため、状態管理はWebアプリケーションにとって大きな問題です。MCSDトレーニングガイド(70–305):VisualBasic.NETおよびVisualStudio.NETを使用したWebアプリケーションの開発と実装2002年12月31日公開このようなアプリが登場する前は、状態管理は、すべてのデスクトップアプリケーションとスタンドアロンの実行可能ファイルに固有の機能でした。「状態の維持」は、開発者が心配しなければならないことではありませんでした。「状態管理」の概念は、現在その世界から戻ってきた開発者の利益のために、率直に言ってFlutterに引き継がれました。Flutterは「状態を保持します」。これで、ある種のスタンドアロン実行可能ファイルが再び作成されました。今回は、手のひらに収まります。嬉しいことに、これは、この試行錯誤された真のデザインパターンが私にとって非常にうまく機能したことを意味します。私はそれがあなたのために働くことができると感じます。誰も見たことのないものを作ることができます—名声と幸運へと駆り立てます。ほっといて...乾杯。DRあなたはクラスを手に入れました!この記事をさらに補足するために、MVCフレームワークで使用できるすべてのパブリッククラスをリストアップしましょう。最初の2つだけを使用する可能性が高いことに注意してください。—ビューのStateオブジェクト。—システムイベントとユーザーイベントの両方に応答するコントローラー。アプリ全体の「ルックアンドフィール」を設定します。—Stateオブジェクトのライフサイクルへのリスナーを提供するMixin。—Stateオブジェクトなしでアプリの自発的な「再構築」を可能にします。—アプリ全体のMVCStateオブジェクト。—アプリ全体のコントローラーオブジェクト。runApp()関数に渡されます。—一意のIDを生成するのに役立つUUIDジェネレーター。状態状態Flutterで実行しています。それを使うのもいいかもしれません。このフレームワークのControllerクラスとViewクラス(StateMVC)は、Flutterが提供する必要のあるすべての関数とプロパティを使用します。ライフサイクルに関しては、このフレームワークはFlutter独自のWidgetsBindingObserverクラスを利用して、アプリのライフサイクルに応答します。経験豊富なFlutter開発者なら誰でも、StateMVCオブジェクトによって提供されるほとんどの機能を認識できます。build()関数で渡されるBuildContext。搭載-ステートオブジェクトが終端されているかどうかを示すブール値。ウィジェット—関連付けられた「StatefulWidget」オブジェクト。Stateオブジェクトが最初に作成されたときに1回だけ呼び出されます。Stateオブジェクトが二度とビルドされないときに呼び出されます。deactivate()—状態オブジェクトがウィジェットツリーから削除されたときに呼び出されます。setState()—フレームワークにStateオブジェクトのbuild()関数を呼び出すように通知します。didChangeAccessibilityFeatures()—システムがアクティブなアクセシビリティ機能のセットを変更したときに呼び出されます。didChangeAppLifecycleState(AppLifecycleState状態)—システムがアプリをバックグラウンドに置くか、アプリをフォアグラウンドに戻すときに呼び出されます。didChangeDependencies()—このStateオブジェクトの依存関係が変更されたときに呼び出されます。didChangeLocale(ロケールロケール)—システムがユーザーのロケールが変更されたことをアプリに通知したときに呼び出されます。didChangeMetrics()—アプリケーションのディメンションが変更されたときに呼び出されます。didChangeTextScaleFactor()—プラットフォームのテキストスケール係数が変更されたときに呼び出されます。didHaveMemoryPressure()—システムのメモリが不足しているときに呼び出されます。oldWidget)—ウィジェットが変更されたときに応答するように(たとえば、暗黙のアニメーションを開始するために)、このメソッドをオーバーライドします。details)—独自のエラーハンドラーを定義できます。デフォルトのルーチンは、エラーをコンソールにダンプすることです。reassemble()—ホットリロード中など、デバッグ中にアプリケーションが再アセンブルされるたびに呼び出されます。addBeforeListener(StateListenerリスナー)—メインコントローラーが実行される前に「起動される」リスナーを追加します。addAfterListener(StateListenerリスナー)—メインコントローラーの実行後に起動されるリスナーを追加します。beforeListener(文字列キー)—一意のIDでリスナーを返します。リスナーは、コントローラーが実行される前に起動します。afterListener(文字列キー)—一意のIDでリスナーを返します。リスナーは、コントローラーの実行後に「起動」します。'after'listernerが含まれている場合はtrueを返しますControllerMVCクラスStateオブジェクトが実行できることはすべて、コントローラーが実行できます。Stateオブジェクトにもアクセスできます。—関連付けられたMVCStateオブジェクトからのBuildContext。—関連付けられたMVCStateオブジェクトへの参照。StateオブジェクトからsetState()を呼び出します。再構築()—関連付けられたMVC状態オブジェクトからsetState()を呼び出します。StateオブジェクトからsetState()を呼び出します。StateオブジェクトからsetState()を呼び出します。—コントローラーが現在関連付けられているStateオブジェクトのセットを返します。Stateオブジェクトが最初に作成されたときに1回だけ呼び出されます。Stateオブジェクトが二度とビルドされないときに呼び出されます。initAsync()—非同期操作を初期化します。deactivate()—状態オブジェクトがウィジェットツリーから削除されたときに呼び出されます。didChangeAccessibilityFeatures()—システムがアクティブなアクセシビリティ機能のセットを変更したときに呼び出されます。didChangeAppLifecycleState(AppLifecycleState状態)—システムがアプリをバックグラウンドに置くか、アプリをフォアグラウンドに戻すときに呼び出されます。didChangeDependencies()—このStateオブジェクトの依存関係が変更されたときに呼び出されます。didChangeLocale(ロケールロケール)—システムがユーザーのロケールが変更されたことをアプリに通知したときに呼び出されます。didChangeTextScaleFactor()—電話のテキストスケール係数が変更されたとき。didHaveMemoryPressure()—システムのメモリが不足している場合。oldWidget)—ウィジェットが変更されたときに応答するように(たとえば、暗黙のアニメーションを開始するために)、このメソッドをオーバーライドします。reassemble()—ホットリロード中など、デバッグ中にアプリケーションが再アセンブルされるたびに呼び出されます。didPopRoute()—システムが現在のルートをポップしたときに呼び出されます。didPushRoute(文字列ルート)—システムが新しいルートをプッシュしたときに呼び出されます。didChangeMetrics()—電話が回転したときに呼び出されます。didChangePlatformBrightness()—電話はその明るさを変更します。details)—独自のエラーハンドラーを定義できます。デフォルトのルーチンは、エラーをコンソールにダンプすることです。—このコントローラーを一意に識別するStingオブジェクトを返します。beforeListener(文字列キー)—一意のIDでリスナーを返します。afterListener(文字列キー)—一意のIDでリスナーを返します。あなたのアプリはすべてを知っています他の優れたフレームワークと同様に、アプリ全体に関連する多くの情報を簡単に取得できます。探している情報の前に「アプリ」を付けるのと同じくらい簡単です。アプリのどこにいてもその情報があります。—アプリのビューへのアクセスを許可します。最初に使用する「MyView」。スナップショット—アプリのビューで使用されるスナップショット。—アプリがエラーなしで正常に初期化されたかどうかを確認します。—アプリがマテリアルインターフェイステーマを実行しているかどうかを示します。—アプリがCupertinoインターフェーステーマを実行しているかどうかを示します。—アプリのビューで使用されるナビゲーターキーを返します。ルート—アプリのビューで使用されるルートを返します。—アプリのビューで使用される最初のルートに戻ります。—アプリが名前付きルートに移動するときに使用されるルートジェネレーター。[initialRoute]を除いて[onGenerateRoute]が失敗したときに呼び出されます。—このアプリの[ナビゲーター]のオブザーバーのリスト。[home]、[routes]、または[onGenerateRoute]のいずれも渡されなかった場合。—アプリのビューのタイトルを返します。—アプリのタイトルを生成するために使用されるルーチン。テーマ—アプリの現在のテーマ。—アプリのビューに渡された色を返します。—アプリの現在のロケールを返します。ローカリゼーションデリゲート—アプリの現在のローカリゼーションデリゲートを返します。—アプリのロケールを解決します。—アプリのロケールの反復を返します。—マテリアルアプリにグリッドオーバーレイをペイントします。—パフォーマンスオーバーレイをオンにします。—全体的なレンダリングを高速化するためのチェッカーボードラスターキャッシュ。checkerboardOffscreenLayers:オフスクリーンビットマップでレンダリングされたチェッカーボードレイヤー。showSemanticsDebugger:アクセシビリティ情報のオーバーレイを表示します。—チェックモードで小さな「DEBUG」バナーを表示します。—境界の周りにボックスをペイントする各RenderBox。—RenderBoxはベースラインに線を描画します。—オブジェクトがタップされている間フラッシュします。—レイヤーはその境界の周りにボックスをペイントします。—チェックモードでレイヤーを再描画するときに、回転する色のセットをオーバーレイします。—アプリのビューのBuildContext。—アプリの「パッケージ名」。—アプリの現在のバージョン。—アプリのビルド番号。—チェックモードまたはデバッグモードの場合はTrue。足場—このアプリのビューの足場オブジェクト。—このアプリのメニューのColorSwatch。—このアプリのローカルディレクトリ。接続性—デバイスの接続ステータスを返します。—アプリがインターネットにアクセスできるかどうかを示します。—このアプリの特定のインストールのID。addConnectivityListener()—接続リスナーを追加します。removeConnectivityListener()—接続リスナーを削除します。clearConnectivityListener()—接続リスナーをクリアします。アドレスに変換し、コンピュータが接続できるようにします。技術的な背景がなくてもサイバーセキュリティに移行するためのヒント。年に、私は非技術職からサイバーセキュリティの職に転職しました。あなたがショックを受け、私がどのようにしてドイツ語への移行に成功したかに興味を持っているのはわかりますが、それはたまたまです。関連記事JARMとPythonを使用したSSLサーバーのフィンガープリントPythonでJARMを使用する簡単な方法であるpyJARMの紹介2020年11月初旬、SalesForceは、説明のつかないJARMという名前の新しいアクティブなTLSフィンガープリントツールを発表しました。JARMの前提は、ターゲットサーバーがさまざまなカスタムクラフトのTCP「Clienthello」パケットを使用してスキャンされた場合、結果の応答を組み合わせてハッシュし、共有または類似のアプリケーションまたはサーバーを示すフィンガープリントを提供できることです。優れた開発者を作る非技術的なこと私はこの記事を書くのをしばらく延期してきました—私はそれを書く資格があるとはまったく感じませんでした。今日はそれを書く時だと思いました。技術面接の社会的要素に取り組むコーディングの課題はストレスがたまりますが、ストレスに対するあなたの反応は、これまでの技術スキルよりも雄弁です。テクノロジー業界でのポジションについて面接する場合、通常、オファーが検討される前に、少なくとも3回の面接を行います。ラウンドは通常次のようになります:あなたがそれを考えるなら、あなたは間違っています。Programmerは1999年に最初に出版されて以来、史上最高のプログラミング本に選ばれています。Manifestoの最初の著者の一人であり、いくつかの真剣な資格を持っています。