Android在开发过程中演变出许多的设计模式,今天我们就在讲讲MVC设计模式模式
简介
MVC设计模式,全称Model(模型)-View(视图)-Controller(控制器)设计模式,它最大的好处是将业务和逻辑分开。在MVC里,View是可以直接访问Model的。从而,View里会包含Model信息,不可避免的还要包括一些业务逻辑。 在MVC模型里,更关注的Model的不变,而同时有多个对Model的不同显示,及View。所以,在MVC模型里,Model不依赖于View,但是View是依赖于Model的。不仅如此,因为有一些业务逻辑在View里实现了,导致要更改View也是比较困难的,至少那些业务逻辑是无法重用的.
实际上,现在开发已经很少使用MVC开发模式了,因为MVC模式对 V和C分得不是很清楚。
详细介绍
大概流程
MVC的大概流程是这样的,用户看到的只有View视图,然后当用户与视图进行互动的时候,控制器会接受到来自客户的请求,并调用相应的模型来进行处理,并返回处理后得到数据,最后控制器根据数据更新相应的视图呈现给用户。
每个部分的作用
M(模型):封装了数据和对数据的操作(函数),是实际进行数据管理、处理的地方
V(视图):是用户与应用之间的接口,主要用于输出内容给用户看,并允许用户与之交互。
C(控制器):Controller是用来处理用户输入数据,已经更新业务模型的部分。控制器中接收了用户与界面交互时传递过来的数据,并根据数据业务逻辑来执行服务的调用和更新业务模型的数据和状态。
优缺点分析
优点
- 耦合性低
- 重用性高
- 生命周期成本低
- 部署快
- 可维护性高
- 有利软件工程化管理
缺点
- 没有明确的定义
- 不适合小型,中等规模的应用程序
- 增加系统结构和实现的复杂性
- 视图与控制器间的过于紧密的连接
- 视图对模型数据的低效率访问
- 一般高级的界面工具或构造器不支持模式
简单实例
view层:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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:id="@+id/linearLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/questionText"
android:layout_width="107dp"
android:layout_height="28dp"
android:layout_marginBottom="361dp"
android:layout_marginEnd="8dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="122dp"
android:text="TextView"
android:textSize="26sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/answerText"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<EditText
android:id="@+id/answerText"
android:layout_width="105dp"
android:layout_height="50dp"
android:layout_marginBottom="361dp"
android:layout_marginEnd="8dp"
android:layout_marginLeft="46dp"
android:layout_marginRight="8dp"
android:layout_marginStart="46dp"
android:layout_marginTop="122dp"
android:text="0"
android:textSize="26sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/checkButon"
app:layout_constraintStart_toEndOf="@+id/questionText"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/checkButon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="349dp"
android:layout_marginEnd="8dp"
android:layout_marginLeft="18dp"
android:layout_marginRight="8dp"
android:layout_marginStart="18dp"
android:layout_marginTop="114dp"
android:text="CHECK"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/answerText"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
model层
package com.example.a95150.myapplication;
import android.app.Activity;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import org.w3c.dom.Text;
public class MainActivity extends AppCompatActivity {
private TextView question;
private TextView answer;
private Button checkButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Cal cal = new Cal();
question = (TextView) findViewById(R.id.questionText);
answer = (TextView)findViewById(R.id.answerText);
checkButton = (Button) findViewById(R.id.checkButon);
createQuestion();
}
public void createQuestion(){
Cal cal = new Cal();
String result = cal.getQuestion();
question.setText(result);
final Cal finalCal = cal;
checkButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String answerString = answer.getText().toString();
if (finalCal.checkAnswer(answerString)){
Toast.makeText(MainActivity.this, finalCal.right,Toast.LENGTH_LONG).show();
}
else{
Toast.makeText(MainActivity.this, finalCal.wrong,Toast.LENGTH_LONG).show();
}
createQuestion();
}
});
}
}
controller层
package com.example.a95150.myapplication;
public class Cal {
private String firstNumber;
private String secondNumber;
private String opeartors[] = {"+", "-", "*"};
private int answer;
private String opeartor;
public String right = "恭喜你答对啦~";
public String wrong = "好可怜,你错啦~";
public Cal(){
int num = (int) (Math.random() * 3);
opeartor = opeartors[num];
firstNumber = String.valueOf((int) (Math.random() * 10));
secondNumber = String.valueOf((int) (Math.random() * 10));
}
public String getQuestion() {
int num = (int) (Math.random() * 3);
opeartor = opeartors[num];
firstNumber = String.valueOf((int) (Math.random() * 10));
secondNumber = String.valueOf((int) (Math.random() * 10));
return (firstNumber + opeartor + secondNumber + " = ");
}
public boolean checkAnswer(String answerString) {
answer = Integer.parseInt(answerString);
int first = Integer.parseInt(firstNumber);
int second = Integer.parseInt(secondNumber);
int trueAnswer = 0;
switch (opeartor) {
case " +":
trueAnswer = first + second;
break;
case "_":
trueAnswer = first - second;
break;
case "*":
trueAnswer = first * second;
break;
default:
break;
}
return answer == trueAnswer;
}
}