Androidアーキテクチャ設計---MVVMモデルについての検討
13214 ワード
###一、MVPモードのメリットとデメリット
MVVMについて話す前に、MVPの階層を簡単に振り返ってみると、MVPは全部で3つの階層に分かれています. a、View:xmlファイルとActivity/fragmentに対応するビューレイヤ; b、Presenter:論理制御層、同時にViewとModelオブジェクトを持つ; c、Model:エンティティ層で、エンティティデータの取得を担当します.
MVPモードシーケンス図
MVPモードには大きなメリットがあります 1.解結合、ビジネスロジック、ビュー分離; 2.プロジェクトコード構造(フォルダ)が明確で、見ただけで何をしているかがわかります. 3.ユニットテストを容易にする(実際には第一点である); 4.協同作業(例えば、デザイナーが図を出さない前にビジネスロジックコードを書いたり、他の人がコードを引き継いだりするのが容易です); しかし、米中が不足している部分もあり、MVPモードの欠点は以下の通りです. 1.Presente層とView層はインタフェースを介して相互作用し,インタフェースの粒度は制御しにくい.粒度が小さすぎると、大量のインタフェースが存在し、コードが砕けすぎてしまう.粒度が大きすぎて、デカップリング効果がよくありません.ビュー定義のメソッドは必ずしもすべて使用する必要はありませんので、後で先に定義する必要があるだけかもしれません(後で削除するかどうかは不明ですが)、後にいくつかのメソッドが削除される場合は、PresenterとActivityが削除され、面倒です. 2.V層とP層はまだ一定の結合度を持っている.V層のUI要素が変更されると、対応するインタフェースが変更され、データがUIにどのようにマッピングされるか、イベントリスニングインタフェースが変更され、全身を動かす必要があります.この層もデカップリングできればもっとよかったのに. 3.複雑な業務は同時にP層が大きすぎる可能性があり、コードの肥大化の問題は依然として解決できない.これはもうインタフェースの粒度制御の問題ではない.業務論理がますます多くなると、View定義の方法がますます多くなり、ActivityとFragmentの実現方法がますます多くなり、依然として肥大化する.
###二、MVVMモード
###2.1、データの双方向バインドOK、今からMVVMを紹介します.MVVMモードは4層ではなく、MVPと同じ3層ですが、MVVMがMVPのアップグレード版であることに同意しません.両者は同じところがありますが、MVPのいくつかの利点は、MVVMも取って代わることができません.MVVMの3層モデルは以下の通りです.
Model:MVPのようなデータ実装と論理処理を担当します.View:ActivityとXMLに対応し、MVPのようにViewの描画とユーザーとのインタラクションを担当します.ViewModel:関連付けを作成し、modelとviewをバインドします.その後、モデルの変更はviewmodelを介してviewにフィードバックされます.(viewのxmlレイアウトファイルは、特定の作成を経て、コンパイルツールが処理すると、生成されたコードがview modelのデータ通知メッセージを受信し、インタフェースを自動的にリフレッシュします).
MVVMモードの最大のハイライトは双方向バインドであることがわかります
一方的なバインドでは、データの流れは一方的で、コードからUIにしか流れません.双方向バインドされたデータの流れは双方向であり、ビジネスコードのデータが変更されると、UI上のデータがリフレッシュされる.ユーザがUIを介してデータをインタラクティブに編集すると、データの変化はビジネスコードのデータに自動的に更新される.双方向バインディングでは、DataBindingを使用することができます.DataBindingはデータとUIバインディングを実現するフレームワークであり、MVVMモードを構築する重要なツールです.そのためAndroidではMVVMを実現するのが便利になり、IOSではblockコールバックやreactiveCocoaライブラリも使用されます.
#####2.2、DataBinding基本用法
#####-Gradle構成
Gradleのandroidドメイン内でdataBindingを開くだけでOKです.
#####-エンティティークラスの作成
バインドを実現すると、レイアウトの作成は従来のxmlとは異なります
DataBindingを使用すると、レイアウトはすべてラベルをルートノードとして使用します.このレイアウトは最終的にBindingクラスを生成します.命名規則は、単語の頭文字が大文字で、下線を削除し、最後にBindingを追加します.ここはactivityですmain.xmlなので、Activity MainBindingが生成されます.
setContentView(R.layout.activity_main)をDataBindingUtil.setContentView(this,R.layout.activity_main)に置き換え、生成されたバインディングクラスActivity MainBindingを返し、userをバインディングします.運転効果は以下の通りです.
しかし、これはまだ双方向バインドを実現することはできません.双方向バインドを実現するには.エンティティクラスを変更する必要があります.
public ObservableField name=new ObservableField<>()という方法で属性を作成します.ObservableFieldは、エンティティークラスの値が変更されると自動的にViewリフレッシュを通知する役割を果たします.名前を使う.get()は属性値を取得し、name.set()属性値を設定します.フィールドを変更するには、そのフィールドのgetメソッドに@Bindable注記を追加し、そのフィールドのsetメソッドにnotifyPropertyChanged(mvm.wangjing.com.mvvm.BR.name)を追加する必要があります.上のコードは、Viewをクリックしたときにnameの値を変更することを示しています.dadabindingのもっと高級な使い方について:私を突き刺します.
ObservableFieldの場合、これらのフィールドは少し分類して包むことができます.たとえば、一部のフィールドはコントロールのStyleプロパティにバインドされている可能性があります.(長さ、色、サイズなど)このようなView Styleに対するフィールドに対して、View Styleクラスがラップされていることを宣言することで、コードロジック全体がより明確になり、読み取りが悪くなります.他のフィールド、例えばtitle、imageUrl、nameなどのデータソースタイプに属するフィールドについては、データフィールドとも呼ばれ、ビジネスデータとパトロールです.これらのフィールドは1つに置くことができます.
MVVMモードを実装する中でViewModelの重要な部分であるDataBindingがどのように双方向にバインドされているかを示した.
2.2、AndroidのMVVMモード
###a、View層view層はxmlとActivity
今回導入されたのは、MVVMのVMレイヤであるUserViewModelであり、Modelの業務データが変化した場合、UIの更新、UIの更新を通知した場合、Modelに変化を通知する.
我々はXML,Activity,FragmentのみでView層のコードを書き,View層は業務に関することをしない,つまりActivityでは業務ロジックや業務データに関するコードを書かず,UIを更新することはデータバインドによって実現され,できるだけView Modelで行うことが分かった.
####b、ViewModel層
ViewModelは業務の論理処理に専念し、業務論理と業務データに関することだけをし、UIに関することはここに書かないでください.ViewModel層はコントロールの参照を一切持たず、ViewModelではUIコントロールの参照を通じてUIを更新することはありません.ただし、ViewModelはデータを変更する可能性があります.データとUIがバインドされているため、対応するコントロールでUIが自動的に更新されます.
####c、Model層
Model層は職責データ取得であり、ネットワーク要求の論理はここに書かれており、MVPに似ている.そのため、ViewModelレイヤはModelの参照を持って、Modelにデータの取得を通知することができると思います.同時に、Modelはデータの取得後、コールバックしてViewModelにデータの変更を通知し、UIを更新します.
まとめてみると、ViewレイヤのActivityはDataBindingによってBindingインスタンスを生成し、このインスタンスをView Modelに渡し、View Modelレイヤは自身をBindingインスタンスにバインドすることで、ViewにおけるlayoutとView Modelの双方向バインドを実現する.ビューモデルを導入しないと、1つのxmlに複数のデータオブジェクトが含まれる可能性があるという欠点もあります.この複数のデータオブジェクトを導入するだけで、xmlレイアウトの鮮明さが低下します.この方法では、layoutファイルのdataラベルにビューモデルを導入するだけでいいのです.他のデータオブジェクトは、ViewModelで一括処理されます.3つのコラボレーションについては、次の図に示します.
from Kelin
###d、MVVMの問題第一点:データバインディングによりBugをデバッグすることが困難になる.インタフェースが異常になっているのを見て、あなたのViewのコードにBugがあるかもしれないし、Modelのコードに問題があるかもしれません.データバインディングにより、1つの位置のBugが他の位置に迅速に伝達され、元の問題の場所を特定するのは容易ではありません.2つ目:大きなプロジェクトでは、データバインドにより多くのメモリが必要です.MVVMの理解について、ネット上で、みんなの全体的な理解はあまり悪くないことを発見して、しかし細部の上でいくつかの異なる地方があって、例えばMVVMの業務の論理の分業はあまり明確ではありませんて、一部の人はView Modelで書くことができて、ある人はMoldelの中で書くことができて、甚だしきに至ってはいくつかの反対派が私を突いて、MVVMが背いていると思っているJAVAの階層設計の思想、***
Please accept mybest wishes for your happiness and success !
推荐阅读:Androidアーキテクチャー设计---MVPモード第(一)篇之基本认実Androidアーキテクチャー设计---MVPモード第(二)篇,如何减少类爆炸
参照先:
tech.meituan.com/android_mvv…
www.jianshu.com/p/2fc41a310…
zhuanlan.zhihu.com/p/23772285?…
github.com/tianzhijiex…
www.open-open.com/lib/view/op…
juejin.im/entry/57d16…
github.com/Kelin-Hong/…
MVVMについて話す前に、MVPの階層を簡単に振り返ってみると、MVPは全部で3つの階層に分かれています.
MVPモードシーケンス図
MVPモードには大きなメリットがあります
###二、MVVMモード
###2.1、データの双方向バインドOK、今からMVVMを紹介します.MVVMモードは4層ではなく、MVPと同じ3層ですが、MVVMがMVPのアップグレード版であることに同意しません.両者は同じところがありますが、MVPのいくつかの利点は、MVVMも取って代わることができません.MVVMの3層モデルは以下の通りです.
Model:MVPのようなデータ実装と論理処理を担当します.View:ActivityとXMLに対応し、MVPのようにViewの描画とユーザーとのインタラクションを担当します.ViewModel:関連付けを作成し、modelとviewをバインドします.その後、モデルの変更はviewmodelを介してviewにフィードバックされます.(viewのxmlレイアウトファイルは、特定の作成を経て、コンパイルツールが処理すると、生成されたコードがview modelのデータ通知メッセージを受信し、インタフェースを自動的にリフレッシュします).
MVVMモードの最大のハイライトは双方向バインドであることがわかります
一方的なバインドでは、データの流れは一方的で、コードからUIにしか流れません.双方向バインドされたデータの流れは双方向であり、ビジネスコードのデータが変更されると、UI上のデータがリフレッシュされる.ユーザがUIを介してデータをインタラクティブに編集すると、データの変化はビジネスコードのデータに自動的に更新される.双方向バインディングでは、DataBindingを使用することができます.DataBindingはデータとUIバインディングを実現するフレームワークであり、MVVMモードを構築する重要なツールです.そのためAndroidではMVVMを実現するのが便利になり、IOSではblockコールバックやreactiveCocoaライブラリも使用されます.
#####2.2、DataBinding基本用法
#####-Gradle構成
Gradleのandroidドメイン内でdataBindingを開くだけでOKです.
#####-エンティティークラスの作成
public class User {
private String name;
private String age;
public void onItemClick(View pView) {
Toast.makeText(pView.getContext(), getName(), Toast.LENGTH_SHORT).show();
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public User(String name, String age) {
this.name = name;
this.age = age;
}
}
バインドを実現すると、レイアウトの作成は従来のxmlとは異なります
activity_main.xml
"1.0" encoding="utf-8"?>
DataBindingを使用すると、レイアウトはすべてラベルをルートノードとして使用します.このレイアウトは最終的にBindingクラスを生成します.命名規則は、単語の頭文字が大文字で、下線を削除し、最後にBindingを追加します.ここはactivityですmain.xmlなので、Activity MainBindingが生成されます.
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.activity_main);
ActivityMainBinding viewDataBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);
User user = new User("Looperjing", "20");
viewDataBinding.setUser(user);
}
}
setContentView(R.layout.activity_main)をDataBindingUtil.setContentView(this,R.layout.activity_main)に置き換え、生成されたバインディングクラスActivity MainBindingを返し、userをバインディングします.運転効果は以下の通りです.
しかし、これはまだ双方向バインドを実現することはできません.双方向バインドを実現するには.エンティティクラスを変更する必要があります.
public class User extends BaseObservable {
public ObservableField<String> name = new ObservableField<>();
public ObservableField<String> age = new ObservableField<>();
public User(String pName, String pAge) {
name.set(pName);
age.set(pAge);
}
@Bindable
public String getName() {
return name.get();
}
public void setName(String name) {
this.name.set(name);
notifyPropertyChanged(mvvm.wangjing.com.mvvm.BR.name);
}
@Bindable
public String getAge() {
return age.get();
}
public void setAge(String age) {
this.age.set(age);
}
public void onItemClick(View pView) {
Toast.makeText(pView.getContext(), name.get(), Toast.LENGTH_SHORT).show();
setName("June");
}
}
public ObservableField name=new ObservableField<>()という方法で属性を作成します.ObservableFieldは、エンティティークラスの値が変更されると自動的にViewリフレッシュを通知する役割を果たします.名前を使う.get()は属性値を取得し、name.set()属性値を設定します.フィールドを変更するには、そのフィールドのgetメソッドに@Bindable注記を追加し、そのフィールドのsetメソッドにnotifyPropertyChanged(mvm.wangjing.com.mvvm.BR.name)を追加する必要があります.上のコードは、Viewをクリックしたときにnameの値を変更することを示しています.dadabindingのもっと高級な使い方について:私を突き刺します.
ObservableFieldの場合、これらのフィールドは少し分類して包むことができます.たとえば、一部のフィールドはコントロールのStyleプロパティにバインドされている可能性があります.(長さ、色、サイズなど)このようなView Styleに対するフィールドに対して、View Styleクラスがラップされていることを宣言することで、コードロジック全体がより明確になり、読み取りが悪くなります.他のフィールド、例えばtitle、imageUrl、nameなどのデータソースタイプに属するフィールドについては、データフィールドとも呼ばれ、ビジネスデータとパトロールです.これらのフィールドは1つに置くことができます.
MVVMモードを実装する中でViewModelの重要な部分であるDataBindingがどのように双方向にバインドされているかを示した.
2.2、AndroidのMVVMモード
###a、View層view層はxmlとActivity
"1.0" encoding="utf-8"?>
今回導入されたのは、MVVMのVMレイヤであるUserViewModelであり、Modelの業務データが変化した場合、UIの更新、UIの更新を通知した場合、Modelに変化を通知する.
<variable
name="model"
type="mvvm.wangjing.com.mvvm.User.UserViewModel" />
data>
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final ActivityMainBinding viewDataBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);
UserViewModel userViewModel=new UserViewModel(this,viewDataBinding);
}
}
我々はXML,Activity,FragmentのみでView層のコードを書き,View層は業務に関することをしない,つまりActivityでは業務ロジックや業務データに関するコードを書かず,UIを更新することはデータバインドによって実現され,できるだけView Modelで行うことが分かった.
####b、ViewModel層
public class UserViewModel {
// , public,
public User user;
public ActivityMainBinding mainBinding;
public Activity activity;
public UserViewModel(Activity pActivity, ActivityMainBinding pMainBinding) {
this.activity = pActivity;
this.mainBinding = pMainBinding;
mainBinding.setModel(this);
init();
}
private void init() {
user=new User("LooperJing","20");
}
public void onItemClick(View pView) {
Toast.makeText(pView.getContext(), " Medel , , ", Toast.LENGTH_SHORT).show();
}
}
ViewModelは業務の論理処理に専念し、業務論理と業務データに関することだけをし、UIに関することはここに書かないでください.ViewModel層はコントロールの参照を一切持たず、ViewModelではUIコントロールの参照を通じてUIを更新することはありません.ただし、ViewModelはデータを変更する可能性があります.データとUIがバインドされているため、対応するコントロールでUIが自動的に更新されます.
####c、Model層
Model層は職責データ取得であり、ネットワーク要求の論理はここに書かれており、MVPに似ている.そのため、ViewModelレイヤはModelの参照を持って、Modelにデータの取得を通知することができると思います.同時に、Modelはデータの取得後、コールバックしてViewModelにデータの変更を通知し、UIを更新します.
まとめてみると、ViewレイヤのActivityはDataBindingによってBindingインスタンスを生成し、このインスタンスをView Modelに渡し、View Modelレイヤは自身をBindingインスタンスにバインドすることで、ViewにおけるlayoutとView Modelの双方向バインドを実現する.ビューモデルを導入しないと、1つのxmlに複数のデータオブジェクトが含まれる可能性があるという欠点もあります.この複数のデータオブジェクトを導入するだけで、xmlレイアウトの鮮明さが低下します.この方法では、layoutファイルのdataラベルにビューモデルを導入するだけでいいのです.他のデータオブジェクトは、ViewModelで一括処理されます.3つのコラボレーションについては、次の図に示します.
from Kelin
###d、MVVMの問題第一点:データバインディングによりBugをデバッグすることが困難になる.インタフェースが異常になっているのを見て、あなたのViewのコードにBugがあるかもしれないし、Modelのコードに問題があるかもしれません.データバインディングにより、1つの位置のBugが他の位置に迅速に伝達され、元の問題の場所を特定するのは容易ではありません.2つ目:大きなプロジェクトでは、データバインドにより多くのメモリが必要です.MVVMの理解について、ネット上で、みんなの全体的な理解はあまり悪くないことを発見して、しかし細部の上でいくつかの異なる地方があって、例えばMVVMの業務の論理の分業はあまり明確ではありませんて、一部の人はView Modelで書くことができて、ある人はMoldelの中で書くことができて、甚だしきに至ってはいくつかの反対派が私を突いて、MVVMが背いていると思っているJAVAの階層設計の思想、***
Please accept mybest wishes for your happiness and success !
推荐阅读:Androidアーキテクチャー设计---MVPモード第(一)篇之基本认実Androidアーキテクチャー设计---MVPモード第(二)篇,如何减少类爆炸
参照先:
tech.meituan.com/android_mvv…
www.jianshu.com/p/2fc41a310…
zhuanlan.zhihu.com/p/23772285?…
github.com/tianzhijiex…
www.open-open.com/lib/view/op…
juejin.im/entry/57d16…
github.com/Kelin-Hong/…