MVC的架构Model-View-Controller
是一种设计模式,通过业务逻辑,数据,以及界面显示各司其职的分离方法来呈现代码设计,通过界面与用户交互的同时,不改变业务逻辑的一种实现。我们通常是在model中实现业务逻辑和处理数据;View中则显示处理的结果,直观的呈献给用户;Controller只是起到桥梁嫁接的作用,通过控制Model和View的通信以此来达到分离视图和业务逻辑,在一些大的项目中通常是观察者模式、策略者模式、组合模式的合体,而核心在于观察者模式。
MVC的优点很多,首先耦合性低,可扩展性好,职责明确,理解起来也是很容易的,且易于维护和修改,但由此我们也知道每一个设计模式的产生都会伴生出很多的包和类,这对一些小应用来说是很“不公平”的,因为会影响开发效率。
现在我们来对上面提到的模式做一个简单实现对各设计模式有一个基础了解
首先看一下观察者模式:
观察者:
public class Student implements Observer {
private String name = "";
public Student(String name) {
this.name = name;
}
@Override
public void update(Observable observable, Object o) {
Log.d("AA","Hello,"+name+" TED Class 更新了课件。内容为:"+o);
}
}
这里student类是具体观察者的角色
实现jdk提供的Observer,重写update方法
被观察者:
public class TEDClass extends Observable {
public void setContent(String content){
// 设置改变
setChanged();
// 通知内容
notifyObservers(content);
}
}
这里TEDClass类是具体的被观察者对象
当有更新时,会遍历所有观察者(Student),然后给这些观察者发布一个更新的消息
测试代码:
TEDClass tedClass = new TEDClass();
//创建观察者
Student student1 = new Student("小红");
Student student2 = new Student("小黑");
Student student3 = new Student("小白");
//添加观察者到被观察者
tedClass.addObserver(student1);
tedClass.addObserver(student2);
tedClass.addObserver(student3);
//更新内容
tedClass.setContent("观察者模式的简单实现!");
运行效果:
05-25 16:38:42.451 13491-13491/com.example.gaonet D/AA﹕ Hello,小红 TED Class 更新了课件。内容为:观察者模式的简单实现!
05-25 16:38:42.451 13491-13491/com.example.gaonet D/AA﹕ Hello,小黑 TED Class 更新了课件。内容为:观察者模式的简单实现!
05-25 16:38:42.451 13491-13491/com.example.gaonet D/AA﹕ Hello,小白 TED Class 更新了课件。内容为:观察者模式的简单实现!
认识策略模式:
顾名思义根据不同的策略来实现功能。即通过提供一个接口,对不同的策略有不同的实现类,当用到的时候可以动态替换,这样我们就把一个个的策略方法给独立出来,不会让类变得很大。
上代码看策略接口:
public interface PriceStrategy {
//折扣
public static final float DISCOUNT_NO = 1.0f;
public static final float DISCOUNT_8 = 0.8f;
public static final float DISCOUNT_5 = 0.5f;
/**
* 需要多少钱
* @param nums 数量
* @return
*/
float needMoney(int nums);
}
策略的实现之一:
public class MathBook implements PriceStrategy {
// 单价 20元
private static final int MATH_BOOK = 20;
@Override
public float needMoney(int nums) {
if (nums < 3){
return MATH_BOOK * nums * PriceStrategy.DISCOUNT_NO;
}else if (nums >= 3 && nums < 10){
return MATH_BOOK * nums * PriceStrategy.DISCOUNT_8;
}
return MATH_BOOK * nums * PriceStrategy.DISCOUNT_5;
}
}
策略的实现之二:
public class ChineseBook implements PriceStrategy {
private static final int CHINESE_BOOK = 15;
@Override
public float needMoney(int nums) {
if (nums < 5){
return CHINESE_BOOK * nums * PriceStrategy.DISCOUNT_NO;
}else if (nums >= 5 && nums < 12){
return CHINESE_BOOK * nums * PriceStrategy.DISCOUNT_8;
}
return CHINESE_BOOK * nums * PriceStrategy.DISCOUNT_5;
}
}
价钱的计算类:
public class MoneyCal {
private PriceStrategy priceStrategy;
public float needMoney(int nums) {
return priceStrategy.needMoney(nums);
}
public void setPriceStrategy(PriceStrategy priceStrategy) {
this.priceStrategy = priceStrategy;
}
}
测试代码:
MoneyCal moneyCal = new MoneyCal();
moneyCal.setPriceStrategy(new MathBook());
Log.d("AA","买5本数学书的价钱为:"+moneyCal.needMoney(5));
moneyCal.setPriceStrategy(new ChineseBook());
Log.d("AA","买10本汉语书的价钱为:"+moneyCal.needMoney(10));
打印日志:
05-25 18:35:46.861 1009-1009/com.example.gaonet D/AA﹕ 买5本数学书的价钱为:80.0
05-25 18:35:46.861 1009-1009/com.example.gaonet D/AA﹕ 买10本汉语书的价钱为:120.0
组合模式:将一组相似的对象看做一个对象处理,并根据一个树结构来组合对象,最后由一个统一的方法去访问相应的对象
首先新建一个抽象类People:
public abstract class People {
//只有一个name字段
protected String name = "";
public People(String name) {
this.name = name;
}
/**
* 抽象方法交给子类
*/
public abstract void printName();
}
新建Father类:
public class Father extends People {
// 持有People的容器
private List<People> lists = new ArrayList<>();
public Father(String name) {
super(name);
}
@Override
public void printName() {
Log.d("AA", name);
for (People list : lists) {
list.printName();
}
}
public void addChild(People home){
lists.add(home);
}
}
新建Child类:
public class Child extends People {
public Child(String name) {
super(name);
}
@Override
public void printName() {
Log.d("AA",name);
}
}
测试代码:
Father father = new Father("Father");
Child child1 = new Child("child1");
Child child2 = new Child("child2");
father.addChild(child1);
father.addChild(child2);
father.printName();
测试结果:
05-26 14:48:17.261 27671-27671/com.example.gaonet D/AA﹕ Father
05-26 14:48:17.261 27671-27671/com.example.gaonet D/AA﹕ child1
05-26 14:48:17.261 27671-27671/com.example.gaonet D/AA﹕ child2
总结:
我们只是通过MVC模式来做个引入,在这里并没有谈MVC的总体实现,如果想了解的更深入,可以通过一些MVCDemo来细细品味。比如这个
MVP与MVC模式的比较