MVC全名是Model View Controller忍捡,是模型(model)-視圖(view)-控制器(controller)的縮寫集漾,一種軟件設(shè)計(jì)典范,用一種業(yè)務(wù)邏輯砸脊、數(shù)據(jù)具篇、界面顯示分離的方法組織代碼,將業(yè)務(wù)邏輯聚集到一個(gè)部件里面凌埂,在改進(jìn)和個(gè)性化定制界面及用戶交互的同時(shí)驱显,不需要重新編寫業(yè)務(wù)邏輯。MVC被獨(dú)特的發(fā)展起來用于映射傳統(tǒng)的輸入侨舆、處理和輸出功能在一個(gè)邏輯的圖形化用戶界面的結(jié)構(gòu)中秒紧。
MVC簡介
MVC開始是存在于桌面程序中的,M是指業(yè)務(wù)模型挨下,V是指用戶界面熔恢,C則是控制器,使用MVC的目的是將M和V的實(shí)現(xiàn)代碼分離臭笆,從而使同一個(gè)程序可以使用不同的表現(xiàn)形式叙淌。比如一批統(tǒng)計(jì)數(shù)據(jù)可以分別用柱狀圖、餅圖來展示愁铺。C存在的目的則是確保M和V的同步鹰霍,一旦M改變,V應(yīng)該同步更新茵乱。
MVC編程模式
Model(模型)表示應(yīng)用程序核心(比如數(shù)據(jù)庫記錄列表)茂洒。
View(視圖)顯示數(shù)據(jù)(數(shù)據(jù)庫記錄)。
Controller(控制器)處理輸入(寫入數(shù)據(jù)庫記錄)瓶竭。
MVC 模式同時(shí)提供了對 HTML督勺、CSS 和 JavaScript 的完全控制。
Model(模型)是應(yīng)用程序中用于處理應(yīng)用程序數(shù)據(jù)邏輯的部分斤贰。
通常模型對象負(fù)責(zé)在數(shù)據(jù)庫中存取數(shù)據(jù)智哀。
View(視圖)是應(yīng)用程序中處理數(shù)據(jù)顯示的部分。
通常視圖是依據(jù)模型數(shù)據(jù)創(chuàng)建的荧恍。
Controller(控制器)是應(yīng)用程序中處理用戶交互的部分瓷叫。
通常控制器負(fù)責(zé)從視圖讀取數(shù)據(jù)送巡,控制用戶輸入摹菠,并向模型發(fā)送數(shù)據(jù)。
MVC 分層有助于管理復(fù)雜的應(yīng)用程序授艰,因?yàn)槟梢栽谝粋€(gè)時(shí)間內(nèi)專門關(guān)注一個(gè)方面辨嗽。例如,您可以在不依賴業(yè)務(wù)邏輯的情況下專注于視圖設(shè)計(jì)淮腾。同時(shí)也讓應(yīng)用程序的測試更加容易糟需。
MVC 分層同時(shí)也簡化了分組開發(fā)屉佳。不同的開發(fā)人員可同時(shí)開發(fā)視圖、控制器邏輯和業(yè)務(wù)邏輯洲押。
框架和設(shè)計(jì)模式的區(qū)別
框架武花、設(shè)計(jì)模式這兩個(gè)概念總?cè)菀妆换煜鋵?shí)它們之間還是有區(qū)別的杈帐√寤框架通常是代碼重用,而設(shè)計(jì)模式是設(shè)計(jì)重用挑童,架構(gòu)則介于兩者之間累铅,部分代碼重用,部分設(shè)計(jì)重用站叼,有時(shí)分析也可重用娃兽。在軟件生產(chǎn)中有三種級(jí)別的重用:內(nèi)部重用,即在同一應(yīng)用中能公共使用的抽象塊;代碼重用尽楔,即將通用模塊組合成庫或工具集投储,以便在多個(gè)應(yīng)用和領(lǐng)域都能使用;應(yīng)用框架的重用阔馋,即為專用領(lǐng)域提供通用的或現(xiàn)成的基礎(chǔ)結(jié)構(gòu)玛荞,以獲得最高級(jí)別的重用性。
框架與設(shè)計(jì)模式雖然相似呕寝,但卻有著根本的不同勋眯。設(shè)計(jì)模式是對在某種環(huán)境中反復(fù)出現(xiàn)的問題以及解決該問題的方案的描述,它比框架更抽象下梢;框架可以用代碼表示凡恍,也能直接執(zhí)行或復(fù)用,而對模式而言只有實(shí)例才能用代碼表示;設(shè)計(jì)模式是比框架更小的元素怔球,一個(gè)框架中往往含有一個(gè)或多個(gè)設(shè)計(jì)模式,框架總是針對某一特定應(yīng)用領(lǐng)域浮还,但同一模式卻可適用于各種應(yīng)用竟坛。可以說钧舌,框架是軟件担汤,而設(shè)計(jì)模式是軟件的知識(shí)。
優(yōu)點(diǎn)
耦合性低
耦合性(Coupling)耦合性也叫塊間聯(lián)系洼冻。指軟件系統(tǒng)結(jié)構(gòu)中各模塊間相互聯(lián)系緊密程度的一種度量崭歧。模塊之間聯(lián)系越緊密,其耦合性就越強(qiáng)撞牢,模塊之間越獨(dú)立則越差率碾,模塊間耦合的高低取決于模塊間接口的復(fù)雜性叔营,調(diào)用的方式以及傳遞的信息。
將視圖層和業(yè)務(wù)層分離所宰,這樣就允許更改視圖層代碼而不用重新編譯模型和控制器代碼绒尊,同樣,一個(gè)應(yīng)用的業(yè)務(wù)流程或者業(yè)務(wù)規(guī)則的改變只需要改動(dòng)MVC的模型層即可仔粥。因?yàn)槟P团c控制器和視圖相分離婴谱,所以很容易改變應(yīng)用程序的數(shù)據(jù)層和業(yè)務(wù)規(guī)則。
重用性高
隨著技術(shù)的不斷進(jìn)步躯泰,需要用越來越多的方式來訪問應(yīng)用程序谭羔。MVC模式允許使用各種不同樣式的視圖來訪問同一個(gè)服務(wù)器端的代碼,因?yàn)槎鄠€(gè)視圖能共享一個(gè)模型麦向,它包括任何WEB(HTTP)瀏覽器或者無線瀏覽器(wap)瘟裸,比如,用戶可以通過電腦也可通過手機(jī)來訂購某樣產(chǎn)品磕蛇,雖然訂購的方式不一樣景描,但處理訂購產(chǎn)品的方式是一樣的。由于模型返回的數(shù)據(jù)沒有進(jìn)行格式化秀撇,所以同樣的構(gòu)件能被不同的界面使用超棺。
生命周期成本低
MVC使開發(fā)和維護(hù)用戶接口的機(jī)數(shù)含量降低。
可維護(hù)性高
分離視圖層和業(yè)務(wù)邏輯層也使得WEB應(yīng)用更易于維護(hù)和修改呵燕。
1.我們說了我們要把model和view分開棠绘,但是需要聯(lián)系,model處理完成了以后需要告訴view層我做完了請你展示再扭。所以他們直接是要用聯(lián)系的那就是OnNewsListener
public interface OnNewsListener {
void onSuccess(News news);
void onError();
}
2.我們知道用戶通過Controller告訴model應(yīng)該干什么說以氧苍,他們之間的聯(lián)系就是NewsModel
public interface NewsModel {
void getWeather(String name, OnNewsListener mlistener);
}
3.就是我們的邏輯處理NewsModelImpl進(jìn)行網(wǎng)絡(luò)請求
public class NewsModelImpl implements NewsModel {
private final String baseUrl = "http://v.juhe.cn";
private final String key = "這個(gè)地方就寫你在聚合數(shù)據(jù)上面申請的今日頭條的KEY";
@Override
public void getWeather(String name, final OnNewsListener mlistener) {
OkHttpClient.Builder client = new OkHttpClient.Builder();
Retrofit retrofit = new Retrofit.Builder()
.client(client.build())
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create())
.build();
MyService service = retrofit.create(MyService.class);
service.getNews(key,name).enqueue(new Callback<News>() {
@Override
public void onResponse(Call<News> call, Response<News> response) {
News news = response.body();
if (news.getReason().equals("成功的返回")) {
Log.e("news", "成功");
mlistener.onSuccess(news);
} else {
Log.e("news", "失敗");
mlistener.onError();
}
}
@Override
public void onFailure(Call<News> call, Throwable t) {
t.getStackTrace();
mlistener.onError();
}
});
}
}
4.MainActivity.java
public class MainActivity extends AppCompatActivity implements OnNewsListener, View.OnClickListener {
private EditText editText = null;
private Button button = null;
private TextView title, date, category, author_name = null;
private NewsModelImpl weatherModel = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
weatherModel = new NewsModelImpl();
initView();
}
public void initView() {
editText = (EditText) findViewById(R.id.edit);
button = (Button) findViewById(R.id.button);
title = (TextView) findViewById(R.id.title);
date = (TextView) findViewById(R.id.date);
category = (TextView) findViewById(R.id.category);
author_name = (TextView) findViewById(R.id.author_name);
button.setOnClickListener(this);
}
//設(shè)置數(shù)據(jù)
public void setView(News news) {
title.setText(news.getResult().getData().get(1).getTitle());
date.setText(news.getResult().getData().get(1).getDate());
category.setText(news.getResult().getData().get(1).getCategory());
author_name.setText(news.getResult().getData().get(1).getAuthor_name());
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.button:
String name = editText.getText().toString();
if (!name.equals("")) {
weatherModel.getWeather(name, this);
} else {
Toast.makeText(this, "輸入的新聞標(biāo)題不能為空", Toast.LENGTH_SHORT).show();
}
break;
}
}
@Override
public void onSuccess(News news) {
setView(news);
}
@Override
public void onError() {
Toast.makeText(this, "出錯(cuò)了哦!", Toast.LENGTH_SHORT).show();
}
}