轉(zhuǎn)載請(qǐng)標(biāo)明出處:
http://blog.csdn.net/mollyxiong/article/details/54925663;
本文出自:【MollyShong博客】
一個(gè)簡(jiǎn)單的發(fā)送內(nèi)容的demo 先上效果圖
MVP模式的結(jié)構(gòu)
一、什么是MVP模式? 分離view 與 model 層的功能,使得程序更加清晰 提高分離 解耦性,減輕activity的工作量 將業(yè)務(wù)代碼單獨(dú)抽取出來(lái),各自負(fù)責(zé)各自層應(yīng)該做的事情。簡(jiǎn)單一句話(huà)說(shuō)就是基于MVC模式演變而來(lái),提高代碼結(jié)構(gòu)清晰度,提高程序解耦性可維護(hù)性的模式。 接下來(lái)我們具體梳理下MVP究竟是什么 M 對(duì)應(yīng)的Model 數(shù)據(jù)層,負(fù)責(zé)操作、獲取數(shù)據(jù) V 對(duì)應(yīng)的是View 也就是Activity層,負(fù)責(zé)UI、與用戶(hù)進(jìn)行交互 P PResenter 就是我們要分離的業(yè)務(wù)邏輯層,連接view和model層,處理業(yè)務(wù)邏輯。二、為什么要用MVP模式? Android開(kāi)發(fā)不同于javaWeb開(kāi)發(fā)的是利用MVC模式 使得控制器和展示層完全分離,但是Android中activity有控制器也有view做的事情,如果把布局文件單獨(dú)分成view層,幾乎就沒(méi)有做什么事情,而activity還承擔(dān)了部分view層的工作,到最后需求越來(lái)越多,activity也會(huì)越來(lái)也胖。所以在A(yíng)ndroid開(kāi)發(fā)中可以使用MVP模式來(lái)清晰的分離各自層的工作。同樣也利于單元測(cè)試。三、MVP模式怎么用? view層專(zhuān)門(mén)負(fù)責(zé)UI及用戶(hù)交互 Persenter層負(fù)責(zé)所有的業(yè)務(wù)邏輯的處理 Model層負(fù)責(zé)數(shù)據(jù)的獲取、操縱 各個(gè)層單獨(dú)分離,用層與層之間用接口交互下面我們來(lái)看一個(gè)簡(jiǎn)單的Demo Acitivity 也就是view層 實(shí)現(xiàn)了ViewInterface接口,分離業(yè)務(wù)邏輯public class MainActivity extends AppCompatActivity implements ViewInterface, View.OnClickListener { private EditText content; private EditText author; private Button send; private Button clean; private ProgressBar loading; private PresenterImpl presenter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); } public void initView(){ content = (EditText) findViewById(R.id.content); author = (EditText) findViewById(R.id.author); loading = (ProgressBar) findViewById(R.id.loading); send = (Button) findViewById(R.id.send); clean = (Button) findViewById(R.id.clean); send.setOnClickListener(this); clean.setOnClickListener(this); presenter = new PresenterImpl(this); } /** * 顯示和隱藏進(jìn)度條 */ @Override public void showProgressBar() { loading.setVisibility(View.VISIBLE); } @Override public void hideProgressBar() { loading.setVisibility(View.GONE); } /** * 發(fā)送是成功還是失敗各自需要做的事情 */ @Override public void sendSuccess() { Toast.makeText(this,"發(fā)送成功!",Toast.LENGTH_SHORT).show(); } @Override public void sendFailed() { Toast.makeText(this,"發(fā)送失敗!",Toast.LENGTH_SHORT).show(); } /** * 清除發(fā)送內(nèi)容 */ @Override public void cleanContent() { content.setText(""); } @Override public void cleanAuthor() { author.setText(""); } /** * 獲取內(nèi)容和作者 */ @Override public String getContent() { return content.getText().toString().trim(); } @Override public String getAuthor() { return author.getText().toString().trim(); } /** * Called when a view has been clicked. * @param v The view that was clicked. */ @Override public void onClick(View v) { switch( v.getId()){ case R.id.send: presenter.send(); break; case R.id.clean: presenter.clean(); break; } } @Override protected void onDestroy() { presenter.destroy(); super.onDestroy(); }}ViewInterface/** * Created by Administrator on 2017/2/7. * view 層的接口,定義view 的所有動(dòng)作 view通常是指activity 讓activity去實(shí)現(xiàn)本接口 * view 和 presenter 互相持有引用 */public interface ViewInterface { /** * 顯示和隱藏進(jìn)度條 */ public void showProgressBar(); public void hideProgressBar(); /** * 發(fā)送是成功還是失敗各自需要做的事情 */ public void sendSuccess(); public void sendFailed(); /** * 清除發(fā)送內(nèi)容 */ public void cleanContent(); public void cleanAuthor(); /** * 獲取內(nèi)容和作者 */ public String getContent(); public String getAuthor();}業(yè)務(wù)邏輯層/** * Created by Administrator on 2017/2/7. * * 控制 業(yè)務(wù)層,處理所有的業(yè)務(wù)邏輯,連接view 和 model */public interface PresenterInterface { public void send(); public void destroy(); public void clean();}從view層獲取數(shù)據(jù) ,做完相應(yīng)的業(yè)務(wù)處理,把事情交給model校驗(yàn)數(shù)據(jù),返回結(jié)果,根據(jù)結(jié)果控制view做出相應(yīng)的UI處理/** * Created by Administrator on 2017/2/7. */public class PresenterImpl implements PresenterInterface { ViewInterface viewInterface; ModelImpl model; private Handler mHandler = new Handler(); public PresenterImpl() { } public PresenterImpl(ViewInterface viewInterface) { this.viewInterface = viewInterface; model = new ModelImpl(); } @Override public void send() { //顯示進(jìn)度條 viewInterface.showProgressBar(); model.send(viewInterface.getContent(), viewInterface.getAuthor(), new ModelInterface.OnSendLinterer() { @Override public void sendSuccess() { mHandler.post(new Runnable() { @Override public void run() { viewInterface.sendSuccess(); viewInterface.hideProgressBar(); } }); } @Override public void sendFailed() { mHandler.post(new Runnable() { @Override public void run() { viewInterface.sendFailed(); viewInterface.hideProgressBar(); } }); } }); } @Override public void destroy() { viewInterface = null; model.destory(); model = null; } @Override public void clean() { viewInterface.cleanAuthor(); viewInterface.cleanContent(); }}數(shù)據(jù)層/** * Created by Administrator on 2017/2/7. * * 數(shù)據(jù)層,做的事情就是為Presenter層提供數(shù)據(jù) */public interface ModelInterface { interface OnSendLinterer{ void sendSuccess(); void sendFailed(); } public void send(String content, String author, OnSendLinterer onSendLinterer);}發(fā)送數(shù)據(jù)請(qǐng)求發(fā)送內(nèi)容是否成功,這里用的是模擬/** * Created by Administrator on 2017/2/7. */public class ModelImpl implements ModelInterface { private ExecutorService executorService ; public ModelImpl(){ //獲取一個(gè)線(xiàn)程池 根據(jù) 虛擬機(jī)可用的處理器的最大數(shù)量 +1 定義線(xiàn)程池大小 executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()+1); } @Override public void send(String content, String author,final OnSendLinterer onSendLinterer) { executorService.execute(new Runnable() { /** * When an object implementing interface <code>Runnable</code> is used * to create a thread, starting the thread causes the object's * <code>run</code> method to be called in that separately executing * thread. * <p> * The general contract of the method <code>run</code> is that it may * take any action whatsoever. * * @see Thread#run() */ @Override public void run() { //模擬網(wǎng)絡(luò)請(qǐng)求的耗時(shí)操作 try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } //隨機(jī)boolean 模擬發(fā)送成功或失敗 Random random = new Random(); if( random.nextBoolean() ){ onSendLinterer.sendSuccess(); }else{ onSendLinterer.sendFailed(); } } }); //不再接受新的任務(wù)// executorService.shutdown(); /*try { future.get(); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); }*/ } public void destory(){ executorService = null; }}項(xiàng)目的結(jié)構(gòu)
四、MVP模式什么時(shí)候用? 可能有朋友會(huì)覺(jué)得MVP是為了模式而模式,開(kāi)發(fā)中類(lèi)變得多了,感覺(jué)還更加復(fù)雜了。我們知道,當(dāng)需求過(guò)多過(guò)于復(fù)雜的時(shí)候,activity的代碼量就會(huì)越來(lái)越多,可能一個(gè)activity中會(huì)有幾千行代碼,極大的影響了后期的維護(hù)和開(kāi)發(fā)的成本。如果用上MVP就能極大限度的將activity中展示 業(yè)務(wù)處理 數(shù)據(jù)存取單獨(dú)分離出來(lái),雖然類(lèi)文件增加了不少,但是整體來(lái)看程序和代碼的結(jié)構(gòu)還是很清晰的。所以,應(yīng)用層開(kāi)發(fā)的項(xiàng)目個(gè)人覺(jué)得使用MVP都是比較合適的。使用MVP模式,建議按功能分包,利于后面的維護(hù)和開(kāi)發(fā)最后附上Demo的下載鏈接: github
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注