Android Mvc 模式
1.Mvc 介紹
?? Model-View-Controller(模型-視圖-控制器) 模式,這種模式用于應(yīng)用程序的分層開(kāi)發(fā)。
?? model:模型層主要是處理數(shù)據(jù)的,主要進(jìn)行網(wǎng)絡(luò)請(qǐng)求,復(fù)雜的數(shù)據(jù)操作
?? view:視圖層xml 負(fù)責(zé)數(shù)據(jù)的顯示,主要是xml,View負(fù)責(zé)
?? controller:控制層處理用戶交互的部分,負(fù)責(zé)從視圖層獲取數(shù)據(jù)傳遞給模型層進(jìn)行處理activity,Fragment和Adapter充當(dāng)這個(gè)角色
如圖:
2.Android中demo
(1).代碼的目錄結(jié)構(gòu):
(2).model層:
public interface GetDataModelImpl {public void getData(String url, GetDataListener listener); } public class GetDataModel implements GetDataModelImpl {@Overridepublic void getData(String url, final GetDataListener listener){OkHttpClient client = new OkHttpClient(final Request request = new Request.Builder().url(url).addHeader("Content-Type","application/json").build();client.newCall(request).enqueue(new Callback() {@Overridepublic void onFailure(Call call, IOException e) {listener.onFail();} ?@Overridepublic void onResponse(Call call, final Response response) throws IOException {final String resultStr = response.body().string();Handler mainHandler = new Handler(Looper.getMainLooper());mainHandler.post(new Runnable() {@Overridepublic void run() {//已在主線程中,更新UIif(response.isSuccessful()){//回調(diào)的方法執(zhí)行在子線程。listener.onSuccess(resultStr);}else{listener.onFail();}}}); ? ?} ? ? ?});} }(3).view層
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"> ?<Buttonandroid:id="@+id/bt0"android:layout_width="fill_parent"android:layout_height="wrap_content"android:text="mvc1獲取數(shù)據(jù)"></Button><Buttonandroid:id="@+id/bt1"android:layout_width="fill_parent"android:layout_height="wrap_content"android:text="mvc2獲取數(shù)據(jù)(變相的)"></Button><Buttonandroid:id="@+id/bt2"android:layout_width="fill_parent"android:layout_height="wrap_content"android:text="沒(méi)有用mvc模式的"></Button><TextViewandroid:id="@+id/tv"android:layout_width="fill_parent"android:layout_height="fill_parent"android:text="返回的結(jié)果"></TextView> ? </LinearLayout>(4).controller層
public class MainActivity extends FragmentActivity implements GetDataListener {private GetDataModelImpl getDataModel;private Button bt0;private Button bt1;private Button bt2;private TextView tv;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);bt0 = (Button)findViewById(R.id.bt0);bt1 = (Button)findViewById(R.id.bt1);bt2 = (Button)findViewById(R.id.bt2);tv = (TextView)findViewById(R.id.tv); ?bt0.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {String url = "https://www.baidu.com/";getDataModel.getData(url,MainActivity.this); ?}});bt1.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {//換一種形態(tài)的mvc模式這個(gè)時(shí)候只不過(guò)是沒(méi)有回調(diào)lister,但是方法返回值里面有也屬于mvc模式int number = UtilTools.parseInt("2");Toast.makeText(getApplicationContext(),"獲取的數(shù)據(jù)"+ number,Toast.LENGTH_LONG).show();}});bt2.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {//沒(méi)有mvc模式 數(shù)據(jù)處理的能力都在activity層也就是Controller層//這樣造成activity 有控制層的能力也有model層的數(shù)據(jù)處理的能力,導(dǎo)致activity代碼量很大String url = "https://www.baidu.com/";getData(url,MainActivity.this);}});if(getDataModel == null){getDataModel = new GetDataModel();}} ?@Overridepublic void onSuccess(String data) {if(!TextUtils.isEmpty(data)){tv.setText(data);}else{tv.setText("請(qǐng)求的結(jié)果為空");} ?} ?@Overridepublic void onFail() {tv.setText("---請(qǐng)求的結(jié)果失敗--");}public void getData(String url, final GetDataListener listener){OkHttpClient client = new OkHttpClient();final Request request = new Request.Builder().url(url).addHeader("Content-Type","application/json").build();client.newCall(request).enqueue(new Callback() {@Overridepublic void onFailure(Call call, IOException e) {listener.onFail();} ?@Overridepublic void onResponse(Call call, final Response response) throws IOException {final String resultStr = response.body().string();Handler mainHandler = new Handler(Looper.getMainLooper());mainHandler.post(new Runnable() {@Overridepublic void run() {//已在主線程中,更新UIif(response.isSuccessful()){//回調(diào)的方法執(zhí)行在子線程。listener.onSuccess(resultStr);}else{listener.onFail();}}}); ? ?} ? ? ?});} }(5).git 下載地址GitHub - wyc1411162011/MvcDemo: mvc模式的實(shí)例
3.優(yōu)缺點(diǎn)總結(jié):
優(yōu)點(diǎn):mvc采取分層結(jié)構(gòu)結(jié)構(gòu)清晰明了,各個(gè)層級(jí)分工明確耦合性低
缺點(diǎn):(1).mvc模式activity充當(dāng)view和controller這兩種角色,隨著項(xiàng)目擴(kuò)大activity里面代碼會(huì)很多,不適用 復(fù)雜的頁(yè)面
?????????? (2).view層和model層有交互,有代碼的耦合。
?????????? (3).model層數(shù)據(jù)操作沒(méi)有和activity生命周期綁定,activity結(jié)束model數(shù)據(jù)處理還會(huì)有回調(diào),容易引起context的內(nèi)存溢出
4.問(wèn)題及解答:
?????????? (1).model層封裝了一層接口為什么要用接口直接的類不是更簡(jiǎn)單嗎?
?????????? 答案:個(gè)人理解這就是面向接口編程,為了以后好擴(kuò)展,比如獲取數(shù)據(jù)的方法變了,直接新加一個(gè)實(shí)現(xiàn)接口的類,在activity里面換點(diǎn)指向的新對(duì)象就行了,符合設(shè)計(jì)模式里面的開(kāi)關(guān)原則,對(duì)內(nèi)修改關(guān)閉,對(duì)外擴(kuò)展開(kāi)放的原則,鬼知道這個(gè)玩意以后會(huì)不會(huì),為以后擴(kuò)展留好后路。
?????????? (2).如果請(qǐng)求方式從okhttp換成retifit怎么辦?
??????????? 答案:網(wǎng)絡(luò)請(qǐng)求,最好封裝一層,在model層請(qǐng)求數(shù)據(jù),不要用具體的okhttp或者retifit 用自己封裝統(tǒng)一的請(qǐng)求處理,方便以后的全局替換,比如以后又有嶄新的框架了。
?????????? (3).如果有多個(gè)model怎么辦 會(huì)有多個(gè)listener 邏輯處理很混亂?
?????????? 答案:這就要求listener 封裝的足夠通用,這個(gè)model能用,其他model也能用,項(xiàng)目封裝幾個(gè)通用的listener,讓足夠多的model 層使用。
總結(jié)
以上是生活随笔為你收集整理的Android Mvc 模式的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: php捉迷藏,查看“蘑菇捉迷藏!”的源代
- 下一篇: 名帖236 俞和 行书《次韵韩伯清见寄之