国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發(fā)設計 > 正文

開發(fā)模式——MVC框架開發(fā)

2019-11-09 18:38:41
字體:
供稿:網(wǎng)友

簡介

MVC是一種設計模式,也就是一種解決問題的方法和思路, 是上世紀80年代提出的,到現(xiàn)在已經(jīng)頗有歷史了。 MVC的意義在于指導開發(fā)者將數(shù)據(jù)與表現(xiàn)解耦,提高代碼,特別是模型部分代碼的復用性。

MVC模式的意思是,軟件可以分成三個部分。 視圖(View):用戶界面。 控制器(Controller):業(yè)務邏輯 模型(Model):數(shù)據(jù)保存

這里寫圖片描述

View 傳送指令到 Controller Controller 完成業(yè)務邏輯后,要求 Model 改變狀態(tài) Model 將新的數(shù)據(jù)發(fā)送到 View,用戶得到反饋

這里寫圖片描述

所有通信都是單向的。 最上面的一層,是直接面向最終用戶的”視圖層”(View)。它是提供給用戶的操作界面,是程序的外殼。 最底下的一層,是核心的”數(shù)據(jù)層”(Model),也就是程序需要操作的數(shù)據(jù)或信息。 中間的一層,就是”控制層”(Controller),它負責根據(jù)用戶從”視圖層”輸入的指令,選取”數(shù)據(jù)層”中的數(shù)據(jù),然后對其進行相應的操作,產(chǎn)生最終結(jié)果。

這三層是緊密聯(lián)系在一起的,但又是互相獨立的,每一層內(nèi)部的變化不影響其他層。每一層都對外提供接口(Interface),供上面一層調(diào)用。這樣一來,軟件就可以實現(xiàn)模塊化,修改外觀或者變更數(shù)據(jù)都不用修改其他層,大大方便了維護和升級。

舉例 這里寫圖片描述 用Windows的計算器小程序為例,解釋一下MVC模式,雖然它不一定使用這個模式編寫。 在這個計算器程序中,外部的那些按鈕和最上面的顯示條,就是”視圖層”,那些需要運算的數(shù)字就是”數(shù)據(jù)層”,執(zhí)行加減乘除的那些內(nèi)部運算步驟就是”控制層”。每一層執(zhí)行不同的功能,整個程序的結(jié)構(gòu)非常清楚。 如果我們擴大一點想象,就會發(fā)現(xiàn),很多程序本質(zhì)上都是這種模式:對外提供一組觸發(fā)器(本例中是按鈕),然后執(zhí)行一些內(nèi)部操作,最后返回結(jié)果。因此,MVC模式的應用是非常廣泛的。

這里寫圖片描述

以家用微波爐為例,可以將它也理解成三層結(jié)構(gòu)。最簡單的情況下,微波爐的操作用兩個轉(zhuǎn)盤實現(xiàn),一個控制溫度,另一個控制時間。這兩個轉(zhuǎn)盤就是”視圖層”(view),而其內(nèi)部的微波產(chǎn)生裝置則是”數(shù)據(jù)層”(Model),這里的”數(shù)據(jù)”需要理解成”核心功能”。至于將用戶通過轉(zhuǎn)盤輸入的信息,轉(zhuǎn)換成對微波產(chǎn)生器的操作,則用”控制層”來實現(xiàn)。 如果每一層都是獨立的,那么微波爐外部更換一個新潮的外殼,或者內(nèi)部更換更大功率的微波產(chǎn)生器,完全可以在不更改其他層的情況下實現(xiàn)。這就是MVC模式的優(yōu)勢。

View:自定義View或ViewGroup,負責將用戶的請求通知Controller,并根據(jù)model更新界面;

Controller:Activity或者Fragment,接收用戶請求并更新model;

Model:數(shù)據(jù)模型,負責數(shù)據(jù)處理相關的邏輯,封裝應用程序狀態(tài),響應狀態(tài)查詢,通知View改變,對應Android中的datebase、SharePReference等。

MVC的優(yōu)點:

(1)耦合性低。所謂耦合性就是模塊代碼之間的關聯(lián)程度。利用MVC框架使得View(視圖)層和Model(模型)層可以很好的分離,這樣就達到了解耦的目的,所以耦合性低,減少模塊代碼之間的相互影響。

(2)可擴展性好。由于耦合性低,添加需求,擴展代碼就可以減少修改之前的代碼,降低bug的出現(xiàn)率。

(3)模塊職責劃分明確。主要劃分層M,V,C三個模塊,利于代碼的維護。

代碼Demo

以登錄界面為例

這里寫圖片描述

編寫V

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main"android:layout_width="match_parent" android:layout_height="match_parent"tools:context="com.itheima.a001mvclogin.MainActivity"><LinearLayoutandroid:layout_width="match_parent"android:orientation="vertical"android:layout_centerInParent="true"android:layout_height="wrap_content"><EditTextandroid:layout_width="match_parent"android:maxLines="1"android:hint="輸入賬號"android:id="@+id/account_et"android:layout_height="wrap_content" /><EditTextandroid:layout_width="match_parent"android:maxLines="1"android:hint="輸入密碼"android:id="@+id/pwd_et"android:layout_height="wrap_content" /><Buttonandroid:layout_width="match_parent"android:onClick="login"android:text="登錄"android:layout_height="wrap_content" /><ProgressBarandroid:layout_width="wrap_content"android:id="@+id/pbar"android:visibility="invisible"android:layout_gravity="center_horizontal"android:layout_height="wrap_content" /></LinearLayout></RelativeLayout>

編寫M http或者database

public class User {public String pwd;public String account;public User(String account, String pwd) {this.account = account;this.pwd = pwd;}}

編寫C

public class MainActivity extends AppCompatActivity {private EditText accountEt;private EditText pwdEt;private ProgressBar pBar;@Overrideprotected void onCreate(Bundle savedInstanceState{ super.onCreate(savedInstanceState); setContentView(R.layout.activity_main);//編寫登錄//1.編寫V 在android中就是在layout里面布局 accountEt = (EditText) findViewById(R.id.account_et); pwdEt = (EditText) findViewById(R.id.pwd_et); pBar = (ProgressBar) findViewById(R.id.pbar);//2.編寫M 將頁面上獲取的賬號密碼提交給服務器, 返回校驗結(jié)果 //3.編寫C 事件 線程 判斷 } public void login(View view) {//3.1.獲取頁面值 String inputAccount = accountEt.getText().toString(); String inputPwd = pwdEt.getText().toString();//3.2.進行邏輯判斷 if (!TextUtils.isEmpty(inputAccount) && !TextUtils.isEmpty(inputPwd)) { //3.3.提示等待 pBar.setVisibility(View.VISIBLE);//3.4.數(shù)據(jù)提交 final User user = new User(inputAccount, inputPwd);//發(fā)送 new Handler().postDelayed(new Runnable() {@Overridepublic void run() {//3.5.獲取請求結(jié)果 int code = new Random().nextInt(2);//3.6.關閉等待 pBar.setVisibility(View.INVISIBLE);if (code == 0)//賬號密碼正確 { Toast.makeText(MainActivity.this, "登錄成功,歡迎" + user.account, Toast.LENGTH_SHORT).show(); } else {Toast.makeText(MainActivity.this, "賬號密碼錯誤", Toast.LENGTH_SHORT).show(); } } }, 3000); } else { Toast.makeText(this, "賬號密碼不能為空", Toast.LENGTH_SHORT).show(); } }}

代碼Demo2

參考別人寫的代碼 點擊查看

View實現(xiàn):

public class TrackCtrlView implements View.OnClickListener{ private ImageView btnStartTrack, btnStopTrack, btnPauseTrack; private TrackCtrlViewListener listener; private TrackRecordInfo trackRecordInfo; public TrackCtrlView(Activity activity, TrackCtrlViewListener listener){ this.listener = listener; btnStartTrack = (ImageView) activity.findViewById(R.id.btnStartTrack); btnStopTrack = (ImageView) activity.findViewById(R.id.btnStopTrack); btnPauseTrack = (ImageView) activity.findViewById(R.id.btnPauseTrack); btnStartTrack.setOnClickListener(this); btnStopTrack.setOnClickListener(this); btnPauseTrack.setOnClickListener(this); btnPauseTrack.setOnClickListener(this); } /** * 將用戶請求通知Controller */ @Override public void onClick(View v) { switch(v.getId()){ case R.id.btnStartTrack: if(listener != null){ listener.trackStatusRequest(TrackRecordStatus.Recording); } break; case R.id.btnStopTrack: if(listener != null){ listener.trackStatusRequest(TrackRecordStatus.Stoped); } break; case R.id.btnPauseTrack: if(listener != null){ if(trackRecordInfo.status == TrackRecordStatus.Paused){ listener.trackStatusRequest(TrackRecordStatus.Recording); }else{ listener.trackStatusRequest(TrackRecordStatus.Paused); } } break; default: break; } } private void refreshView(){ TrackRecordStatus trackStatus = trackRecordInfo == null ? TrackRecordStatus.Stoped : trackRecordInfo.status; if (trackStatus == TrackRecordStatus.Recording) { btnStartTrack.setVisibility(View.GONE); btnPauseTrack.setVisibility(View.VISIBLE); btnStopTrack.setVisibility(View.VISIBLE); btnPauseTrack.setImageResource(R.drawable.btn_track_ctrl_pause); } else if (trackStatus == TrackRecordStatus.Paused) { btnStartTrack.setVisibility(View.GONE); btnPauseTrack.setVisibility(View.VISIBLE); btnStopTrack.setVisibility(View.VISIBLE); btnPauseTrack.setImageResource(R.drawable.btn_track_ctrl_resume); } else { // TrackRecordStatus.Stoped btnStartTrack.setVisibility(View.VISIBLE); btnPauseTrack.setVisibility(View.GONE); btnStopTrack.setVisibility(View.GONE); } }   public void setTrackRecordInfo(@Nullable TrackRecordInfo trackRecordInfo) { this.trackRecordInfo = trackRecordInfo; refreshView(); } public interface TrackCtrlViewListener{ /** * 用戶點擊按鈕 */ public void trackStatusRequest(@Nullable TrackRecordStatus newStatus); }}

Model實現(xiàn):

public class TrackRecordInfo { private static final Gson gson = new Gson(); /** * 應該是保存軌跡數(shù)據(jù)庫id,此demo中數(shù)據(jù)庫操作不實現(xiàn),暫時trackId一直為0 */ public int trackId; public TrackRecordStatus status; public TrackRecordInfo(int trackId, TrackRecordStatus status) { this.trackId = trackId; this.status = status; } @NonNull public static TrackRecordInfo loadTrackRecordInfo(@NonNull Context context){ String pref = SpUtil.getString(context, SpUtil.KEY_TRACK_RECORD_INFO, ""); if(!TextUtils.isEmpty(pref)){ return gson.fromJson(pref, TrackRecordInfo.class); } return null; } public static void changeTrackRecordInfo(@NonNull Context context, @Nullable TrackRecordInfo info){ SpUtil.saveString(context, SpUtil.KEY_TRACK_RECORD_INFO, info == null ? "" : gson.toJson(info)); //model通過消息總線,通知View刷新 EventBus.getDefault().post(new EventTrackRecordInfoChanged(info)); }}

Controller實現(xiàn):

public class MainActivity extends ActionBarActivity implements TrackCtrlView.TrackCtrlViewListener{ private TrackCtrlView trackCtrlView; private TrackRecordInfo trackRecordInfo; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); trackCtrlView = new TrackCtrlView(this, this); EventBus.getDefault().register(this); trackRecordInfo = TrackRecordInfo.loadTrackRecordInfo(this); trackCtrlView.setTrackRecordInfo(trackRecordInfo); } @Override protected void onDestroy() { super.onDestroy(); EventBus.getDefault().unregister(this); } @Override public void trackStatusRequest(@Nullable TrackRecordStatus newStatus) { if(newStatus == TrackRecordStatus.Recording){ int trackId = 0; //在數(shù)據(jù)庫創(chuàng)建一條軌跡,并獲取到數(shù)據(jù)庫id trackRecordInfo = new TrackRecordInfo(trackId, TrackRecordStatus.Recording); }else if (newStatus == TrackRecordStatus.Paused) { if(trackRecordInfo != null){ trackRecordInfo.status = newStatus; } } else { trackRecordInfo = null; } TrackRecordInfo.changeTrackRecordInfo(this, trackRecordInfo); } public void onEventMainThread(EventTrackRecordInfoChanged event){ trackRecordInfo = event.info; trackCtrlView.setTrackRecordInfo(trackRecordInfo); }}

這里寫圖片描述

參考博客John-Chen


發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 海晏县| 咸宁市| 仪征市| 耒阳市| 汉沽区| 昌图县| 永顺县| 绥中县| 丹阳市| 华坪县| 塔河县| 从化市| 中方县| 容城县| 巩留县| 昆明市| 九江县| 留坝县| 昌乐县| 曲麻莱县| 从江县| 天镇县| 石狮市| 麻城市| 浦县| 德格县| 循化| 嵊泗县| 栖霞市| 洛宁县| 灯塔市| 屯门区| 达州市| 锦屏县| 阜平县| 新郑市| 英山县| 高邮市| 科技| 本溪| 本溪|