序号 | 设计模式名称 | 简单思路 | Android中的源码实现 |
01 | 单例模式 |
Context |
|
02 | 工厂方法 | Activity onCreate() | |
03 | 抽象工厂 | MediaPlayerFactory | |
04 | 模板方法 | AsyncTask | |
05 | 建造者 | AlertDialog.Builder | |
06 | 代理 | ||
07 | 原型 |
ArrayList clone() |
|
08 | 中介者 | ||
09 | 命令 | ||
10 | 责任链 | ViewGroup 的 dispatchTouchEvent | |
11 | 装饰 | ContextWrapper | |
12 | 策略 |
Interpolator 策略抽象 |
|
13 | 适配器 | Adapter | |
14 | 迭代器 | Cursor | |
15 | 组合 | View ViewGroup | |
16 | 观察者 | BaseAdapter notifyDataSetChanged | |
17 | 门面 | ContextImpl | |
18 | 备忘录 | Activity onSaveInstanceState onRestoreInstanceState | |
19 | 访问者 | ||
20 | 状态 | ||
21 | 解释器 | PackageParser | |
22 | 享元 | Handler Looper | |
23 | 桥梁 | Window WindowManager |
//01 单例模式 public class Singleton { private static final Singleton singleton = new Singleton(); //限制产生多个对象 private Singleton(){ } //通过该方法获得实例对象 public static Singleton getSingleton(){ return singleton; } //类中其他方法,尽量是static public static void doSomething(){ } }
//02 工厂方法 public class Client { public static void main(String[] args) { Creator creator = new ConcreteCreator(); Product product = creator.createProduct(ConcreteProduct1.class); /* * 继续业务处理 */ } } public abstract class Creator { /* * 创建一个产品对象,其输入参数类型可以自行设置 * 通常为String、Enum、Class等,当然也可以为空 */ public abstract <T extends Product> T createProduct(Class<T> c); } public class ConcreteCreator extends Creator { public <T extends Product> T createProduct(Class<T> c){ Product product=null; try { product = (Product)Class.forName(c.getName()).newInstance(); } catch (Exception e) { //异常处理 } return (T)product; } } public abstract class Product { //产品类的公共方法 public void method1(){ //业务逻辑处理 } //抽象方法1 public abstract void method2(); } public class ConcreteProduct1 extends Product { public void method2() { //业务逻辑处理 } } public class ConcreteProduct2 extends Product { public void method2() { //业务逻辑处理 } }
//03 抽象工厂 public class Client { public static void main(String[] args) { //定义出两个工厂 AbstractCreator creator1 = new Creator1(); AbstractCreator creator2 = new Creator2(); //产生A1对象 AbstractProductA a1 = creator1.createProductA(); //产生A2对象 AbstractProductA a2 = creator2.createProductA(); //产生B1对象 AbstractProductB b1 = creator1.createProductB(); //产生B2对象 AbstractProductB b2 = creator2.createProductB(); /* * 然后在这里就可以为所欲为了... */ } } public abstract class AbstractCreator { //创建A产品家族 public abstract AbstractProductA createProductA(); //创建B产品家族 public abstract AbstractProductB createProductB(); } public class Creator1 extends AbstractCreator { //只生产产品等级为1的A产品 public AbstractProductA createProductA() { return new ProductA1(); } //只生产产品等级为1的B产品 public AbstractProductB createProductB() { return new ProductB1(); } } public class Creator2 extends AbstractCreator { //只生产产品等级为2的A产品 public AbstractProductA createProductA() { return new ProductA2(); } //只生产产品等级为2的B产品 public AbstractProductB createProductB() { return new ProductB2(); } } public abstract class AbstractProductA { //每个产品共有的方法 public void shareMethod(){ } //每个产品相同方法,不同实现 public abstract void doSomething(); } public abstract class AbstractProductB { //每个产品共有的方法 public void shareMethod(){ } //每个产品相同方法,不同实现 public abstract void doSomething(); } public class ProductA1 extends AbstractProductA { @Override public void doSomething() { System.out.println("产品A1的实现方法"); } } public class ProductA2 extends AbstractProductA { @Override public void doSomething() { System.out.println("产品A2的实现方法"); } } public class ProductB1 extends AbstractProductB { @Override public void doSomething() { System.out.println("产品B1的实现方法"); } } public class ProductB2 extends AbstractProductB { @Override public void doSomething() { System.out.println("产品B2的实现方法"); } }
//04 模板方法 public class Client { public static void main(String[] args) { AbstractClass class1 = new ConcreteClass1(); AbstractClass class2 = new ConcreteClass2(); //调用模版方法 class1.templateMethod(); class2.templateMethod(); } } public abstract class AbstractClass { //基本方法 protected abstract void doSomething(); //基本方法 protected abstract void doAnything(); //模版方法 public void templateMethod(){ /* * 调用基本方法,完成相关的逻辑 */ this.doAnything(); this.doSomething(); } } public class ConcreteClass1 extends AbstractClass { //实现基本方法 protected void doAnything() { //业务逻辑处理 } protected void doSomething() { //业务逻辑处理 } } public class ConcreteClass2 extends AbstractClass { //实现基本方法 protected void doAnything() { //业务逻辑处理 } protected void doSomething() { //业务逻辑处理 } }
//05 建造者 public class Director { private Builder builder = new ConcreteProduct(); //构建不同的产品 public Product getAProduct(){ builder.setPart(); /* * 设置不同的零件,产生不同的产品 */ return builder.buildProduct(); } } public abstract class Builder { //设置产品的不同部分,以获得不同的产品 public abstract void setPart(); //建造产品 public abstract Product buildProduct(); } public class ConcreteProduct extends Builder { private Product product = new Product(); //设置产品零件 public void setPart(){ /* * 产品类内的逻辑处理 */ } //组建一个产品 public Product buildProduct() { return product; } } public class Product { public void doSomething(){ //独立业务处理 } }
//06 代理 public class Client { public static void main(String[] args) { Subject proxy = new RealSubject(); proxy.request(); } } public interface Subject { //定义一个方法 public void request(); } public class RealSubject implements Subject { //实现方法 public void request() { //业务逻辑处理 } } public class Proxy implements Subject { //要代理哪个实现类 private Subject subject = null; //默认被代理者 public Proxy(){ this.subject = new Proxy(); } public Proxy(Subject _subject){ this.subject = _subject; } //通过构造函数传递代理者 public Proxy(Object...objects ){ } //实现接口中定义的方法 public void request() { this.before(); this.subject.request(); this.after(); } //预处理 private void before(){ //do something } //善后处理 private void after(){ //do something } }
//07 原型 public class PrototypeClass implements Cloneable{ //覆写父类Object方法 @Override public PrototypeClass clone(){ PrototypeClass prototypeClass = null; try { prototypeClass = (PrototypeClass)super.clone(); } catch (CloneNotSupportedException e) { //异常处理 } return prototypeClass; } }
//08 中介者 public abstract class Mediator { //定义同事类 protected ConcreteColleague1 c1; protected ConcreteColleague2 c2; //通过getter/setter方法吧同事类注入进来 public ConcreteColleague1 getC1() { return c1; } public void setC1(ConcreteColleague1 c1) { this.c1 = c1; } public ConcreteColleague2 getC2() { return c2; } public void setC2(ConcreteColleague2 c2) { this.c2 = c2; } //中介者模式的业务逻辑 public abstract void doSomething1(); public abstract void doSomething2(); } public abstract class Colleague { protected Mediator mediator; public Colleague(Mediator _mediator){ this.mediator = _mediator; } } public class ConcreteColleague1 extends Colleague { //通过构造函数传递中介者 public ConcreteColleague1(Mediator _mediator){ super(_mediator); } //自有方法 self-method public void selfMethod1(){ //处理自己的业务逻辑 } //依赖方法 dep-method public void depMethod1(){ //处理自己的业务逻辑 //自己不能处理的业务逻辑,委托给中介者处理 super.mediator.doSomething1(); } } public class ConcreteColleague2 extends Colleague { //通过构造函数传递中介者 public ConcreteColleague2(Mediator _mediator){ super(_mediator); } //自有方法 self-method public void selfMethod2(){ //处理自己的业务逻辑 } //依赖方法 dep-method public void depMethod2(){ //处理自己的业务逻辑 //自己不能处理的业务逻辑,委托给中介者处理 super.mediator.doSomething2(); } } public class ConcreteMediator extends Mediator { @Override public void doSomething1() { //调用同事类的方法,只要是public方法都可以调用 super.c1.selfMethod1(); super.c2.selfMethod2(); } public void doSomething2() { super.c1.selfMethod1(); super.c2.selfMethod2(); } }
//09 命令 public class Client { public static void main(String[] args) { //首先声明出调用者Invoker Invoker invoker = new Invoker(); //定义接收者 Receiver receiver = new ConcreteReciver1(); //定义一个发送给接收者的命令 Command command = new ConcreteCommand1(receiver); //把命令交给调用者去执行 invoker.setCommand(command); invoker.action(); } } public class Invoker { private Command command; //受气包,接受命令 public void setCommand(Command _command){ this.command = _command; } //执行命令 public void action(){ this.command.execute(); } } public abstract class Receiver { //抽象接收者,定义每个接收者都必须完成的业务 public abstract void doSomething(); } public abstract class Command { //每个命令类都必须有一个执行命令的方法 public abstract void execute(); } public class ConcreteReciver1 extends Receiver{ //每个接受者都必须处理一定的业务逻辑 public void doSomething(){ } } public class ConcreteReciver2 extends Receiver{ //每个接受者都必须处理一定的业务逻辑 public void doSomething(){ } } public class ConcreteCommand1 extends Command { //也对那个Receiver类进行命令处理 private Receiver receiver; //构造函数传递接收者 public ConcreteCommand1(Receiver _receiver){ this.receiver = _receiver; } //每个具体的命令都必须实现一个命令 public void execute() { //业务处理 this.receiver.doSomething(); } } public class ConcreteCommand2 extends Command { //也对那个Receiver类进行命令处理 private Receiver receiver; //构造函数传递接收者 public ConcreteCommand2(Receiver _receiver){ this.receiver = _receiver; } //每个具体的命令都必须实现一个命令 public void execute() { //业务处理 this.receiver.doSomething(); } }
//10 责任链 public class Client { public static void main(String[] args) { //声明出所有的处理节点 Handler handler1 = new ConcreteHandler1(); Handler handler2 = new ConcreteHandler2(); Handler handler3 = new ConcreteHandler3(); //设置链中的阶段顺序,1-->2-->3 handler1.setNext(handler2); handler2.setNext(handler3); //提交请求,返回结果 Response response = handler1.handlerMessage(new Request()); } } public abstract class Handler { private Handler nextHandler; //每个处理者都必须对请求做出处理 public final Response handlerMessage(Request request){ Response response = null; //判断是否是自己的处理级别 if(this.getHandlerLevel().equals(request.getRequestLevel())){ response = this.echo(request); }else{ //不属于自己的处理级别 //判断是否有下一个处理者 if(this.nextHandler != null){ response = this.nextHandler.handlerMessage(request); }else{ //没有适当的处理者,业务自行处理 } } return response; } //设置下一个处理者是谁 public void setNext(Handler _handler){ this.nextHandler = _handler; } //每个处理者都有一个处理级别 protected abstract Level getHandlerLevel(); //每个处理者都必须实现处理任务 protected abstract Response echo(Request request); } public class ConcreteHandler1 extends Handler { //定义自己的处理逻辑 protected Response echo(Request request) { //完成处理逻辑 return null; } //设置自己的处理级别 protected Level getHandlerLevel() { //设置自己的处理级别 return null; } } public class ConcreteHandler2 extends Handler { //定义自己的处理逻辑 protected Response echo(Request request) { //完成处理逻辑 return null; } //设置自己的处理级别 protected Level getHandlerLevel() { //设置自己的处理级别 return null; } } public class ConcreteHandler3 extends Handler { //定义自己的处理逻辑 protected Response echo(Request request) { //完成处理逻辑 return null; } //设置自己的处理级别 protected Level getHandlerLevel() { //设置自己的处理级别 return null; } } public class Response { //处理者返回的数据 } public class Level { //定义一个请求和处理等级 } public class Request { //请求的等级 public Level getRequestLevel(){ return null; } }
//11 装饰 public class Client { public static void main(String[] args) { Component component = new ConcreteComponent(); //第一次修饰 component = new ConcreteDecorator1(component); //第二次修饰 component = new ConcreteDecorator2(component); //修饰后运行 component.operate(); } } public abstract class Component { //抽象的方法 public abstract void operate(); } public class ConcreteComponent extends Component { //具体实现 @Override public void operate() { System.out.println("do Something"); } } public class ConcreteDecorator1 extends Decorator { //定义被修饰者 public ConcreteDecorator1(Component _component){ super(_component); } //定义自己的修饰方法 private void method1(){ System.out.println("method1 修饰"); } //重写父类的Operation方法 public void operate(){ this.method1(); super.operate(); } } public class ConcreteDecorator2 extends Decorator { //定义被修饰者 public ConcreteDecorator2(Component _component){ super(_component); } //定义自己的修饰方法 private void method2(){ System.out.println("method2修饰"); } //重写父类的Operation方法 public void operate(){ super.operate(); this.method2(); } } public abstract class Decorator extends Component { private Component component = null; //通过构造函数传递被修饰者 public Decorator(Component _component){ this.component = _component; } //委托给被修饰者执行 @Override public void operate() { this.component.operate(); } }
//12 策略 public class Client { public static void main(String[] args) { //声明出一个具体的策略 Strategy strategy = new ConcreteStrategy1(); //声明出上下文对象 Context context = new Context(strategy); //执行封装后的方法 context.doAnythinig(); } } public interface Strategy { //策略模式的运算法则 public void doSomething(); } public class ConcreteStrategy1 implements Strategy { public void doSomething() { System.out.println("具体策略1的运算法则"); } } public class ConcreteStrategy2 implements Strategy { public void doSomething() { System.out.println("具体策略2的运算法则"); } } public class Context { //抽象策略 private Strategy strategy = null; //构造函数设置具体策略 public Context(Strategy _strategy){ this.strategy = _strategy; } //封装后的策略方法 public void doAnythinig(){ this.strategy.doSomething(); } }
//13 适配器 public class Client { public static void main(String[] args) { //原有的业务逻辑 Target target = new ConcreteTarget(); target.request(); //现在增加了适配器角色后的业务逻辑 Target target2 = new Adapter(); target2.request(); } } public interface Target { //目标角色有自己的方法 public void request(); } public class ConcreteTarget implements Target { public void request() { System.out.println("I have nothing to do. if you need any help,pls call me!"); } } public class Adapter extends Adaptee implements Target { public void request() { super.doSomething(); } } public class Adaptee { //原有的业务逻辑 public void doSomething(){ System.out.println("I'm kind of busy,leave me alone,pls!"); } }
//14 迭代器 public class Client { public static void main(String[] args) { //声明出容器 Aggregate agg = new ConcreteAggregate(); //产生对象数据放进去 agg.add("abc"); agg.add("aaa"); agg.add("1234"); //遍历一下 Iterator iterator = agg.iterator(); while(iterator.hasNext()){ System.out.println(iterator.next()); } } } public interface Aggregate { //是容器必然有元素的增加 public void add(Object object); //减少元素 public void remove(Object object); //由迭代器来遍历所有的元素 public Iterator iterator(); } public class ConcreteAggregate implements Aggregate { //容纳对象的容器 private Vector vector = new Vector(); //增加一个元素 public void add(Object object) { this.vector.add(object); } //返回迭代器对象 public Iterator iterator() { return new ConcreteIterator(this.vector); } //删除一个元素 public void remove(Object object) { this.remove(object); } } public interface Iterator { //遍历到下一个元素 public Object next(); //是否已经遍历到尾部 public boolean hasNext(); //删除当前指向的元素 public boolean remove(); } public class ConcreteIterator implements Iterator { private Vector vector = new Vector(); //定义当前游标 public int cursor = 0; @SuppressWarnings("unchecked") public ConcreteIterator(Vector _vector){ this.vector = _vector; } //判断是否到达尾部 public boolean hasNext() { if(this.cursor == this.vector.size()){ return false; }else{ return true; } } //返回下一个元素 public Object next() { Object result = null; if(this.hasNext()){ result = this.vector.get(this.cursor++); }else{ result = null; } return result; } //删除当前元素 public boolean remove() { this.vector.remove(this.cursor); return true; } }
//15 组合 public class Client { public static void main(String[] args) { //创建一个根节点 Composite root = new Composite(); root.doSomething(); //创建一个树枝构件 Composite branch = new Composite(); //创建一个叶子节点 Leaf leaf = new Leaf(); //建立整体 root.add(branch); branch.add(leaf); } //通过递归遍历树 public static void display(Composite root){ for(Component c:root.getChildren()){ if(c instanceof Leaf){ //叶子节点 c.doSomething(); }else{ //树枝节点 display((Composite)c); } } } } public class Composite extends Component { //构件容器 private ArrayList<Component> componentArrayList = new ArrayList<Component>(); //增加一个叶子构件或树枝构件 public void add(Component component){ this.componentArrayList.add(component); } //删除一个叶子构件或树枝构件 public void remove(Component component){ this.componentArrayList.remove(component); } //获得分支下的所有叶子构件和树枝构件 public ArrayList<Component> getChildren(){ return this.componentArrayList; } } public abstract class Component { //个体和整体都具有的共享 public void doSomething(){ //编写业务逻辑 } } public class Leaf extends Component { /* * 可以覆写父类方法 * public void doSomething(){ * * } */ }
//16 观察者 public class Client { public static void main(String[] args) { //创建一个被观察者 ConcreteSubject subject = new ConcreteSubject(); //定义一个观察则 Observer obs= new ConcreteObserver(); //观察者观察被被观察则 subject.addObserver(obs); //观察者开始活动了 subject.doSomething(); } } public abstract class Subject { //定一个一个观察者数组 private Vector<Observer> obsVector = new Vector<Observer>(); //增加一个观察者 public void addObserver(Observer o){ this.obsVector.add(o); } //删除一个观察者 public void delObserver(Observer o){ this.obsVector.remove(o); } //通知所有观察者 public void notifyObserver(){ for(Observer o:this.obsVector){ o.update(); } } } public class ConcreteSubject extends Subject { //具体的业务 public void doSomething(){ /* * do something */ super.notifyObserver(); } } public interface Observer { //更新方法 public void update(); } public class ConcreteObserver implements Observer { //实现更新方法 public void update() { System.out.println("接收到信息,并进行处理!"); } }
//17 门面 public class ClassA { public void doSomethingA(){ //业务逻辑 } } public class ClassB { public void doSomethingB(){ //业务逻辑 } } public class ClassC { public void doSomethingC(){ //业务逻辑 } } public class Facade { //被委托的对象 private ClassA a = new ClassA(); private ClassB b = new ClassB(); private ClassC c = new ClassC(); //提供给外部访问的方法 public void methodA(){ this.a.doSomethingA(); } public void methodB(){ this.b.doSomethingB(); } public void methodC(){ this.c.doSomethingC(); } }
//18 备忘录 public class Client { public static void main(String[] args) { //定义出发起人 Originator originator = new Originator(); //定义出备忘录管理员 Caretaker caretaker = new Caretaker(); //创建一个备忘录 caretaker.setMemento(originator.createMemento()); //恢复一个备忘录 originator.restoreMemento(caretaker.getMemento()); } } public class Originator { //内部状态 private String state = ""; public String getState() { return state; } public void setState(String state) { this.state = state; } //创建一个备忘录 public Memento createMemento(){ return new Memento(this.state); } //恢复一个备忘录 public void restoreMemento(Memento _memento){ this.setState(_memento.getState()); } } public class Caretaker { //备忘录对象 private Memento memento; public Memento getMemento() { return memento; } public void setMemento(Memento memento) { this.memento = memento; } } public class Memento { //发起人的内部状态 private String state = ""; //构造函数传递参数 public Memento(String _state){ this.state = _state; } public String getState() { return state; } public void setState(String state) { this.state = state; } }
//19 访问者 public class Client { public static void main(String[] args) { for(int i=0;i<10;i++){ //获得元素对象 Element el = ObjectStruture.createElement(); //接受访问者访问 el.accept(new Visitor()); } } } public abstract class Element { //定义业务逻辑 public abstract void doSomething(); //允许谁来访问 public abstract void accept(IVisitor visitor); } public class ObjectStruture { //对象生成器,这里通过一个工厂方法模式模拟 public static Element createElement(){ Random rand = new Random(); if(rand.nextInt(100) > 50){ return new ConcreteElement1(); }else{ return new ConcreteElement2(); } } } public class ConcreteElement1 extends Element{ //完善业务逻辑 public void doSomething(){ //业务处理 } //允许那个访问者访问 public void accept(IVisitor visitor){ visitor.visit(this); } } public class ConcreteElement2 extends Element{ //完善业务逻辑 public void doSomething(){ //业务处理 } //允许那个访问者访问 public void accept(IVisitor visitor){ visitor.visit(this); } } public interface IVisitor { //可以访问哪些对象 public void visit(ConcreteElement1 el1); public void visit(ConcreteElement2 el2); } public class Visitor implements IVisitor { //访问el1元素 public void visit(ConcreteElement1 el1) { el1.doSomething(); } //访问el2元素 public void visit(ConcreteElement2 el2) { el2.doSomething(); } }
//20 状态 public class Client { public static void main(String[] args) { //定义环境角色 Context context = new Context(); //初始化状态 context.setCurrentState(new ConcreteState1()); //行为执行 context.handle1(); context.handle2(); } } public class Context { //定义状态 public final static State STATE1 = new ConcreteState1(); public final static State STATE2 = new ConcreteState2(); //当前状态 private State CurrentState; //获得当前状态 public State getCurrentState() { return CurrentState; } //设置当前状态 public void setCurrentState(State currentState) { this.CurrentState = currentState; //切换状态 this.CurrentState.setContext(this); } //行为委托 public void handle1(){ this.CurrentState.handle1(); } public void handle2(){ this.CurrentState.handle2(); } } public abstract class State { //定义一个环境角色,提供子类访问 protected Context context; //设置环境角色 public void setContext(Context _context){ this.context = _context; } //行为1 public abstract void handle1(); //行为2 public abstract void handle2(); } public class ConcreteState1 extends State { @Override public void handle1() { //本状态下必须处理的逻辑 } @Override public void handle2() { //设置当前状态为stat2 super.context.setCurrentState(Context.STATE2); //过渡到state2状态,由Context实现 super.context.handle2(); } } public class ConcreteState2 extends State { @Override public void handle1() { //设置当前状态为stat1 super.context.setCurrentState(Context.STATE1); //过渡到state1状态,由Context实现 super.context.handle1(); } @Override public void handle2() { //本状态下必须处理的逻辑 } }
//21 解释器 @SuppressWarnings("all") public class Client { public static void main(String[] args) { Context ctx = new Context(); //通常定一个语法容器,容纳一个具体的表达式,通常为ListArray,LinkedList,Stack等类型 Stack<Expression> stack = null; /* for(;;){ //进行语法判断,并产生递归调用 } */ //产生一个完整的语法树,由各各个具体的语法分析进行解析 Expression exp = stack.pop(); //具体元素进入场景 exp.interpreter(ctx); } } public class Context { } public abstract class Expression { //每个表达式必须有一个解析任务 public abstract Object interpreter(Context ctx); } public class NonterminalExpression extends Expression { //每个非终结符表达式都会对其他表达式产生依赖 public NonterminalExpression(Expression... expression){ } public Object interpreter(Context ctx) { //进行文法处理 return null; } } public class TerminalExpression extends Expression { //通常终结符表达式只有一个,但是有多个对象 public Object interpreter(Context ctx) { return null; } }
// public abstract class Flyweight { //内部状态 private String intrinsic; //外部状态 protected final String Extrinsic; //要求享元角色必须接受外部状态 public Flyweight(String _Extrinsic){ this.Extrinsic = _Extrinsic; } //定义业务操作 public abstract void operate(); //内部状态的getter/setter public String getIntrinsic() { return intrinsic; } public void setIntrinsic(String intrinsic) { this.intrinsic = intrinsic; } } public class ConcreteFlyweight1 extends Flyweight{ //接受外部状态 public ConcreteFlyweight1(String _Extrinsic){ super(_Extrinsic); } //根据外部状态进行逻辑处理 public void operate(){ //业务逻辑 } } public class ConcreteFlyweight2 extends Flyweight{ //接受外部状态 public ConcreteFlyweight2(String _Extrinsic){ super(_Extrinsic); } //根据外部状态进行逻辑处理 public void operate(){ //业务逻辑 } } public class FlyweightFactory { //定义一个池容器 private static HashMap<String,Flyweight> pool= new HashMap<String,Flyweight>(); //享元工厂 public static Flyweight getFlyweight(String Extrinsic){ //需要返回的对象 Flyweight flyweight = null; //在池中没有改对象 if(pool.containsKey(Extrinsic)){ flyweight = pool.get(Extrinsic); }else{ //根据外部状态创建享元对象 flyweight = new ConcreteFlyweight1(Extrinsic); //放置到池中 pool.put(Extrinsic, flyweight); } return flyweight; } }
//23 桥梁 public class Client { public static void main(String[] args) { //定义一个实现化角色 Implementor imp = new ConcreteImplementor1(); //定义一个抽象化角色 Abstraction abs = new RefinedAbstraction(imp); //执行行文 abs.request(); } } public interface Implementor { //基本方法 public void doSomething(); public void doAnything(); } public class ConcreteImplementor1 implements Implementor{ public void doSomething(){ //业务逻辑处理 } public void doAnything(){ //业务逻辑处理 } } public class ConcreteImplementor2 implements Implementor{ public void doSomething(){ //业务逻辑处理 } public void doAnything(){ //业务逻辑处理 } } public abstract class Abstraction { //定义对实现化角色的引用 private Implementor imp; //约束子类必须实现该构造函数 public Abstraction(Implementor _imp){ this.imp = _imp; } //自身的行为和属性 public void request(){ this.imp.doSomething(); } //获得实现化角色 public Implementor getImp(){ return imp; } } public class RefinedAbstraction extends Abstraction { //覆写构造函数 public RefinedAbstraction(Implementor _imp){ super(_imp); } //修正父类的行文 @Override public void request(){ /* * 业务处理.... */ super.request(); super.getImp().doAnything(); } }
从Android代码中来记忆23种设计模式
相信大家都曾经下定决心把23种设计模式牢记于心,每次看完之后过一段时间又忘记了~,又得回去看,脑子里唯一依稀记得的是少数设计模式的大致的定义。其实,网上很多文章讲得都非常好,我也曾经去看过各种文章。也曾一直苦恼这些难以永久记下的设计模式,直到我接触到了《Android源码设计模式解析与实战》——何红辉与关爱明著,发现原来其实我们在Android中都接触过这些设计模式,只是我们不知道而已。既然我们都接触过,我们只需一一对号入座,对设计模式的记忆就不用死记硬背了!这里自愿无偿做个广告,《Android源码设计模式解析与实战》这本书真心不错,每个Android程序员最好都去翻翻...正如你所想的那样,本文是从这本书中的总结,相信你也会跟我一样,从中获益。
面向对象的六大原则
首先,我们为什么要学习设计模式。主要是这些模式是前人总结的经验,使用这些模式能让我们的程序更健壮、更稳定、容易扩展等等优点。在编写面向对象程序时,我们需要遵循以下6个原则,能让我们的程序维护起来更轻松~(当然还有其它好处)。
1 单一职责原则
单一原则很简单,就是将一组相关性很高的函数、数据封装到一个类中。换句话说,一个类应该有职责单一。
2 开闭原则
开闭原则理解起来也不复杂,就是一个类应该对于扩展是开放的,但是对于修改是封闭的。我们知道,在开放的app或者是系统中,经常需要升级、维护等,这就要对原来的代码进行修改,可是修改时容易破坏原有的系统,甚至带来一些新的难以发现的BUG。因此,我们在一开始编写代码时,就应该注意尽量通过扩展的方式实现新的功能,而不是通过修改已有的代码实现。
3 里氏替换原则
里氏替换原则的定义为:所有引用基类的地方必须能透明地使用其子类对象。定义看起来很抽象,其实,很容易理解,本质上就是说,要好好利用继承和多态。简单地说,就是以父类的形式声明的变量(或形参),赋值为任何继承于这个父类的子类后不影响程序的执行。看一组代码你就明白这个原则了:
//窗口类
public class Window(){
public void show(View child){
child.draw();
}
}
public abstract class View(){
public abstract void draw();
public void measure(int widht,int height){
//测量视图大小
}
}
public class Button extends View{
public void draw(){
//绘制按钮
}
}
public class TextView extends View{
public void draw(){
//绘制文本
}
}
Window 类中show函数需要传入View,并且调用View对象的draw函数。而每个继承于View的子对象都有draw的实现,不存在继承于View但是却没实现draw函数的子类(abstract方法必须实现)。我们在抽象类设计之时就运用到了里氏替换原则。
4 依赖倒置原则
依赖倒置主要是实现解耦,使得高层次的模块不依赖于低层次模块的具体实现细节。怎么去理解它呢,我们需要知道几个关键点:
(1)高层模块不应该依赖底层模块(具体实现),二者都应该依赖其抽象(抽象类或接口)
(2)抽象不应该依赖细节(废话,抽象类跟接口肯定不依赖具体的实现了)
(3)细节应该依赖于抽象(同样废话,具体实现类肯定要依赖其继承的抽象类或接口)
其实,在我们用的Java语言中,抽象就是指接口或者抽象类,二者都是不能直接被实例化;细节就是实现类,实现接口或者继承抽象类而产生的类,就是细节。使用Java语言描述就简单了:就是各个模块之间相互传递的参数声明为抽象类型,而不是声明为具体的实现类;
5 接口隔离原则
接口隔离原则定义:类之间的依赖关系应该建立在最小的接口上。其原则是将非常庞大的、臃肿的接口拆分成更小的更具体的接口。
6 迪米特原则
描述的原则:一个对象应该对其他的对象有最少的了解。什么意思呢?就是说一个类应该对自己调用的类知道的最少。还是不懂?其实简单来说:假设类A实现了某个功能,类B需要调用类A的去执行这个功能,那么类A应该只暴露一个函数给类B,这个函数表示是实现这个功能的函数,而不是让类A把实现这个功能的所有细分的函数暴露给B。
开始学设计模式
学习了上面的六大原则之后,提前做了预热。现在开始,一起学习设计模式吧~
1 单例模式
单例模式可以说是最容易理解的模式了,也是应用最广的模式之一,先看看定义吧。
定义:确保单例类只有一个实例,并且这个单例类提供一个函数接口让其他类获取到这个唯一的实例。
什么时候需要使用单例模式呢:如果某个类,创建时需要消耗很多资源,即new出这个类的代价很大;或者是这个类占用很多内存,如果创建太多这个类实例会导致内存占用太多。
关于单例模式,虽然很简单,无需过多的解释,但是这里还要提个醒,其实单例模式里面有很多坑。我们去会会单例模式。最简单的单例模式如下:
public class Singleton{
private static Singleton instance;
//将默认的构造函数私有化,防止其他类手动new
private Singleton(){};
public static Singleton getInstance(){
if(instance==null)
instance=new Singleton();
return instatnce;
}
}
如果是单线程下的系统,这么写肯定没问题。可是如果是多线程环境呢?这代码明显不是线程安全的,存在隐患:某个线程拿到的instance可能是null,可能你会想,这有什么难得,直接在getInstance()函数上加sychronized关键字不就好了。可是你想过没有,每次调用getInstance()时都要执行同步,这带来没必要的性能上的消耗。注意,在方法上加sychronized关键字时,一个线程访问这个方法时,其他线程无法同时访问这个类其他sychronized方法。的我们看看另外一种实现:
public class Singleton{
private static Singleton instance;
//将默认的构造函数私有化,防止其他类手动new
private Singleton(){};
public static Singleton getInstance(){
if(instance==null){
sychronized(Singleton.class){
if(instance==null)
instance=new Singleton();
}
}
return instatnce;
}
}
为什么需要2次判断是否为空呢?第一次判断是为了避免不必要的同步,第二次判断是确保在此之前没有其他线程进入到sychronized块创建了新实例。这段代码看上去非常完美,但是,,,却有隐患!问题出现在哪呢?主要是在instance=new Singleton();这段代码上。这段代码会编译成多条指令,大致上做了3件事:
(1)给Singleton实例分配内存
(2)调用Singleton()构造函数,初始化成员字段
(3)将instance对象指向分配的内存(此时instance就不是null啦~)
上面的(2)和(3)的顺序无法得到保证的,也就是说,JVM可能先初始化实例字段再把instance指向具体的内存实例,也可能先把instance指向内存实例再对实例进行初始化成员字段。考虑这种情况:一开始,第一个线程执行instance=new Singleton();这句时,JVM先指向一个堆地址,而此时,又来了一个线程2,它发现instance不是null,就直接拿去用了,但是堆里面对单例对象的初始化并没有完成,最终出现错误~ 。
看看另外一种方式:
public class Singleton{
private volatile static Singleton instance;
//将默认的构造函数私有化,防止其他类手动new
private Singleton(){};
public static Singleton getInstance(){
if(instance==null){
sychronized(Singleton.class){
if(instance==null)
instance=new Singleton();
}
}
return instatnce;
}
}
相比前面的代码,这里只是对instance变量加了一个volatile关键字volatile关键字的作用是:线程每次使用到被volatile关键字修饰的变量时,都会去堆里拿最新的数据。换句话说,就是每次使用instance时,保证了instance是最新的。注意:volatile关键字并不能解决并发的问题,关于volatile请查看其它相关文章。但是volatile能解决我们这里的问题。
那么在安卓中哪些地方用到了单例模式呢?其实,我们在调用系统服务时拿到的Binder对象就是个单例。比如:
//获取WindowManager服务引用
WindowManager wm = (WindowManager)getSystemService(getApplication().WINDOW_SERVICE);
其内部是通过单例的方式返回的,由于单例模式较简单,这里不去深究。
2 Builder模式
Builder模式是什么情况呢?我不想去提它的定义,因为他的定义:将一个复杂对象的构造与它的表示分离,使得同样的构造过程可以创建不同的表示。好吧,我还是提了。但是看了这个定义并没有什么luan用。我们看看具体在什么情况下用到Builder模式:主要是在创建某个对象时,需要设定很多的参数(通过setter方法),但是这些参数必须按照某个顺序设定,或者是设置步骤不同会得到不同结果。举个非常简单的例子:
public class MyData{
private int id;
private String num;
public void Test(){
}
public void setId(int id){
this.id=id;
}
public void setNum(String num){
this.num=num+"id";
}
}
当然了,没有人会这么去写代码。这里只是举例子,或者是有时候很多参数有这种类似的依赖关系时,通过构造函数未免太多参数了。回到主题,就是如果是上面的代码,该怎么办呢?你可能会说,那还不简单,先调用setId函数,再调用setNum函数。是的,没错。可是,万一你一不小心先调用了setNum呢?这是比较简单的示例,如果是比较复杂的,有很多变量之间依赖的关系,那你每次都得小心翼翼的把各个函数的执行步骤写正确。
我们看看Builder模式是怎么去做的:
public class MyBuilder{
private int id;
private String num;
public MyData build(){
MyData d=new MyData();
d.setId(id);
d.setNum(num);
return t;
}
public MyBuilder setId(int id){
this.id=id;
return this;
}
public MyBuilder setNum(String num){
this.num=num;
return this;
}
}
public class Test{
public static void main(String[] args){
MyData d=new MyBuilder().setId(10).setNum("hc").build();
}
}
注意到,Builer类的setter函数都会返回自身的引用this,这主要是用于链式调用,这也是Builder设计模式中的一个很明显的特征。
Android中用过的代码来记忆
记忆我这个例子没啥意义,我们前面说过,要通过Android中用过的代码来记忆,这样才可以不用死记硬背。那么在Android中哪里用到了Builder设计模式呢?哈哈~在创建对话框时,是不是跟上面有点类似呢?
AlertDialog.Builer builder=new AlertDialog.Builder(context);
builder.setIcon(R.drawable.icon)
.setTitle("title")
.setMessage("message")
.setPositiveButton("Button1",
new DialogInterface.OnclickListener(){
public void onClick(DialogInterface dialog,int whichButton){
setTitle("click");
}
})
.create()
.show();
这里的create()函数就想到上面代码中的build函数。看到这里是不是在内心中默默的把Builder设计模式拿下了?你并不用死记硬背~
3 原型模式
原型设计模式非常简单,就是将一个对象进行拷贝。对于类A实例a,要对a进行拷贝,就是创建一个跟a一样的类型A的实例b,然后将a的属性全部复制到b。
什么时候会用到原型模式呢?我个人认为,可以在类的属性特别多,但是又要经常对类进行拷贝的时候可以用原型模式,这样代码比较简洁,而且比较方便。
另外要注意的是,还有深拷贝和浅拷贝。深拷贝就是把对象里面的引用的对象也要拷贝一份新的对象,并将这个新的引用对象作为拷贝的对象引用。说的比较绕哈~,举个例子,假设A类中有B类的引用b,现在需要对A类实例进行拷贝,那么深拷贝就是,先对b进行一次拷贝得到nb,然后把nb作为A类拷贝的对象的引用,如此一层一层迭代拷贝,把所有的引用都拷贝结束。浅拷贝则不是。
原型模式比较简单,看看Android怎么运用原型模式:
Uri uri=Uri.parse("smsto:10086");
Intent shareIntent=new Intent(Intent.ACTION_SENDTO,uri);
//克隆副本
Intent intent=(Intetn)shareIntent.clone();
startActivity(intent);
或许我们平时不会这么去写,但是Intent对象确实提供了原型模式的函数clone()
4 工厂方法模式
定义:定义一个创建对象的接口,让子类决定实例化哪个类
先看一个例子:
public abstract class Product{
public abstract void method();
}
public class ConcreteProductA extends Prodect{
public void method(){
System.out.println("我是产品A!");
}
}
public class ConcreteProductB extends Prodect{
public void method(){
System.out.println("我是产品B!");
}
}
public abstract class Factory{
public abstract Product createProduct();
}
public class MyFactory extends Factory{
public Product createProduct(){
return new ConcreteProductA();
}
}
看到上面的代码,是不是觉得工厂模式很简单呢?还可以通过传参的方式,让MyFactory的createProduct方法根据传入的参数决定是创建ConcreteProductA还是ConcreteProductB。
同样的,我们不希望记住这个例子,而是通过Android中的代码来记忆:
其实,在getSystemService方法中就是用到了工厂模式,他就是根据传入的参数决定创建哪个对象,当然了,由于返回的都是以单例模式存在的对象,因此不用new了,直接把单例返回就好。
public Object getSystemService(String name) {
if (getBaseContext() == null) {
throw new IllegalStateException("System services not available to Activities before onCreate()");
}
//........
if (WINDOW_SERVICE.equals(name)) {
return mWindowManager;
} else if (SEARCH_SERVICE.equals(name)) {
ensureSearchManager();
return mSearchManager;
}
//.......
return super.getSystemService(name);
}
5 抽象工厂模式
抽象工厂模式:为创建一组相关或者是相互依赖的对象提供一个接口,而不需要制定他们的具体类
看个例子吧,将它跟工厂方法模式做个对比:
public abstract class AbstractProductA{
public abstract void method();
}
public abstract class AbstractProdectB{
public abstract void method();
}
public class ConcreteProductA1 extends AbstractProductA{
public void method(){
System.out.println("具体产品A1的方法!");
}
}
public class ConcreteProductA2 extends AbstractProductA{
public void method(){
System.out.println("具体产品A2的方法!");
}
}
public class ConcreteProductB1 extends AbstractProductB{
public void method(){
System.out.println("具体产品B1的方法!");
}
}
public class ConcreteProductB2 extends AbstractProductB{
public void method(){
System.out.println("具体产品B2的方法!");
}
}
public abstract class AbstractFactory{
public abstract AbstractProductA createProductA();
public abstract AbstractProductB createProductB();
}
public class ConcreteFactory1 extends AbstractFactory{
public AbstractProductA createProductA(){
return new ConcreteProductA1();
}
public AbstractProductB createProductB(){
return new ConcreteProductB1();
}
}
public class ConcreteFactory2 extends AbstractFactory{
public AbstractProductA createProductA(){
return new ConcreteProductA2();
}
public AbstractProductB createProductB(){
return new ConcreteProductB2();
}
}
其实Android源码中对抽象工厂出现的比较少,好在抽象工厂方法并不复杂,很容易记住,我们可以从Service中去理解,Service的onBind方法可以看成是一个工厂方法,从framework角度来看Service,可以看成是一个具体的工厂,这相当于一个抽象工厂方法模式的雏形。
public class BaseService extends Service{
@Nullable
@Override
public IBinder onBind(Intent intent){
return new Binder();
}
}
6 策略模式
定义:有一系列的算法,将每个算法封装起来(每个算法可以封装到不同的类中),各个算法之间可以替换,策略模式让算法独立于使用它的客户而独立变化。
举个例子来理解吧,比如,你现在又很多排序算法:冒泡、希尔、归并、选择等等。我们要根据实际情况来选择使用哪种算法,有一种常见的方法是,通过if...else或者case...等条件判断语句来选择。但是这个类的维护成本会变高,维护时也容易发生错误。
如何使用策略模式呢,我不打算写示例代码了,简单描述一下,就将前面说的算法选择进行描述。我们可以定义一个算法抽象类AbstractAlgorithm,这个类定义一个抽象方法sort()。每个具体的排序算法去继承AbstractAlgorithm类并重写sort()实现排序。在需要使用排序的类Client类中,添加一个setAlgorithm(AbstractAlgorithm al);方法将算法设置进去,每次Client需要排序而是就调用al.sort()。
不知道简单描述能不能让你理解~
看看Android中哪里出现了策略模式,其中在属性动画中使用时间插值器的时候就用到了。在使用动画时,你可以选择线性插值器LinearInterpolator、加速减速插值器AccelerateDecelerateInterpolator、减速插值器DecelerateInterpolator以及自定义的插值器。这些插值器都是实现根据时间流逝的百分比来计算出当前属性值改变的百分比。通过根据需要选择不同的插值器,实现不同的动画效果。这些比较好理解,就不去粘贴Android源码了。
7 状态模式
状态模式中,行为是由状态来决定的,不同状态下有不同行为。状态模式和策略模式的结构几乎是一模一样的,主要是他们表达的目的和本质是不同。状态模式的行为是平行的、不可替换的,策略模式的行为是彼此独立可相互替换的。
举个例子把,比如电视,电视有2个状态,一个是开机,一个是关机,开机时可以切换频道,关机时切换频道不做任何响应。
public interface TvState{
public void nextChannerl();
public void prevChannerl();
public void turnUp();
public void turnDown();
}
public class PowerOffState implements TvState{
public void nextChannel(){}
public void prevChannel(){}
public void turnUp(){}
public void turnDown(){}
}
public class PowerOnState implements TvState{
public void nextChannel(){
System.out.println("下一频道");
}
public void prevChannel(){
System.out.println("上一频道");
}
public void turnUp(){
System.out.println("调高音量");
}
public void turnDown(){
System.out.println("调低音量");
}
}
public interface PowerController{
public void powerOn();
public void powerOff();
}
public class TvController implements PowerController{
TvState mTvState;
public void setTvState(TvStete tvState){
mTvState=tvState;
}
public void powerOn(){
setTvState(new PowerOnState());
System.out.println("开机啦");
}
public void powerOff(){
setTvState(new PowerOffState());
System.out.println("关机啦");
}
public void nextChannel(){
mTvState.nextChannel();
}
public void prevChannel(){
mTvState.prevChannel();
}
public void turnUp(){
mTvState.turnUp();
}
public void turnDown(){
mTvState.turnDown();
}
}
public class Client{
public static void main(String[] args){
TvController tvController=new TvController();
tvController.powerOn();
tvController.nextChannel();
tvController.turnUp();
tvController.powerOff();
//调高音量,此时不会生效
tvController.turnUp();
}
}
在Android源码中,哪里有用到状态模式呢?其实很多地方用到了,举一个地方例子,就是WIFI管理模块。当WIFI开启时,自动扫描周围的接入点,然后以列表的形式展示;当wifi关闭时则清空。这里wifi管理模块就是根据不同的状态执行不同的行为。由于代码太多,我就不手打敲入了~我们只要知道大致Android里面在哪里用到了以及大概是怎么用的就好。
8 责任链模式
定义:使多个对象都有机会处理请求,从而避免请求的发送者和接受者直接的耦合关系,将这些对象连成一条链,并沿这条链传递该请求,直到有对象处理它为止。
相信聪明的你很容易理解吧,基本不需要例子来解释了,直接进如到Android源码中哪里用到了责任链:在Android处理点击事件时,父View先接收到点击事件,如果父View不处理则交给子View,依次往下传递~
9 解释器模式
定义:给定一个语言,定义它的语法,并定义一个解释器,这个解释器用于解析语言。
从定义中看起来比较抽象,其实,很简单,很容易理解!就是相当于自定义一个格式的文件,然后去解析它。不用理解的那么复杂!
我们看看Android中哪里用到了,从我们第一次学Android时就知道,四大组件需要在AndroidManifest.xml中定义,其实AndroidManifest.xml就定义了<Activity>,<Service>等标签(语句)的属性以及其子标签,规定了具体的使用(语法),通过PackageManagerService(解释器)进行解析。
10 命令模式
定义:命令模式将每个请求封装成一个对象,从而让用户使用不同的请求把客户端参数化;将请求进行排队或者记录请求日志,以及支持可撤销操作。
举个例子来理解:当我们点击“关机”命令,系统会执行一系列操作,比如暂停事件处理、保存系统配置、结束程序进程、调用内核命令关闭计算机等等,这些命令封装从不同的对象,然后放入到队列中一个个去执行,还可以提供撤销操作。
那么Android中哪里用到了命令模式呢?在framework层还真不多。但是在底层却用到了,一个比较典型的例子就是在Android事件机制中,底层逻辑对事件的转发处理。每次的按键事件会被封装成NotifyKeyArgs对象。通过InputDispatcher封装具体的事件操作。
11 观察者模式
定义:定义了对象之间的一对多的关系,其实就是1对n,当“1”发生变化时,“n”全部得到通知,并更新。
观察者模式一个比较经典的应用就是:订阅——发布系统。很容易理解,发布消息时,将消息发送给每个订阅者。我们常用的微信公众号就是典型,当我们关注某个公众号时,每当公众号推送消息时,我们就会去接收到消息,当然了,每个订阅(关注)公众号的的人都能接收到公众号推送的消息。
那么Android哪里用到了观察者模式呢?我们看看ListView的适配器,有个函数notifyDataSetChanged()函数,这个函数其实就是通知ListView的每个Item,数据源发生了变化,请各位Item重新刷新一下。
12 备忘录模式
备忘录模式定义:在不破坏封闭的前提下,捕获一个对象的内部状态,并在对象之外保存这个状态,这样,以后就可将对象恢复到原先保存的状态中。
其实就是相当于一个提前备份,一旦出现啥意外,能够恢复。像我们平时用的word软件,意外关闭了,它能帮我们恢复。其实就是它自动帮我们备份过。
那么Android哪里用到了备忘录模式呢?Activity的onSaveInstanceState和onRestoreInstanceState就是用到了备忘录模式,分别用于保存和恢复。
13 迭代器模式
迭代器模式定义:提供一种方法顺序访问一个容器对象中的各个元素,而不需要暴露该对象的内部表示。
相信熟悉Java的你肯定知道,Java中就有迭代器Iterator类,本质上说,它就是用迭代器模式。
按照惯例,看看Android中哪里用到了迭代器模式,Android源码中,最典型的就是Cursor用到了迭代器模式,当我们使用SQLiteDatabase的query方法时,返回的就是Cursor对象,通过如下方式去遍历:
cursor.moveToFirst();
do{
//cursor.getXXX(int);
}while(cursor.moveToNext);
14 模板方法模式
定义:定义一个操作中的算法框架,而将一些步骤延迟到子类中,使得子类可以不改变一个算法的结构即可重定义该算法的某些特定的步骤。
不用解释太多,感觉越解释越糊涂,直接拿Android中的源码来说事!
我们知道,启动一个Activity过程非常复杂,如果让开发者每次自己去调用启动Activity过程无疑是一场噩梦。好在启动Activity大部分代码时不同的,但是有很多地方需要开发者定制。也就是说,整体算法框架是相同的,但是将一些步骤延迟到子类中,比如Activity的onCreate、onStart等等。这样子类不用改变整体启动Activity过程即可重定义某些具体的操作了~。
15 访问者模式
定义:封装一些作用于某种数据结构中各元素的操作,它可以在不改变这个数据结构的前提下定义作用于这些元素的新的操作。
访问者模式是23种设计模式中最复杂的一个,但他的使用率并不高,大部分情况下,我们不需要使用访问者模式,少数特定的场景才需要。
Android中运用访问者模式,其实主要是在编译期注解中,编译期注解核心原理依赖APT(Annotation Processing Tools),著名的开源库比如ButterKnife、Dagger、Retrofit都是基于APT。APT的详细使用这里不提,后面我会写关于APT相关的文章,敬请期待~
16 中介者模式
定义:中介者模式包装了一系列对象相互作用的方式,使得这些对象不必相互明显调用,从而使他们可以轻松耦合。当某些对象之间的作用发生改变时,不会立即影响其他的一些对象之间的作用保证这些作用可以彼此独立的变化,中介者模式将多对多的相互作用转为一对多的相互作用。
什么时候用中介者模式呢?其实,中介者对象是将系统从网状结构转为以调停者为中心的星型结构。
举个简单的例子,一台电脑包括:CPU、内存、显卡、IO设备。其实,要启动一台计算机,有了CPU和内存就够了。当然,如果你需要连接显示器显示画面,那就得加显卡,如果你需要存储数据,那就要IO设备,但是这并不是最重要的,它们只是分割开来的普通零件而已,我们需要一样东西把这些零件整合起来,变成一个完整体,这个东西就是主板。主板就是起到中介者的作用,任何两个模块之间的通信都会经过主板协调。
那么Android中那些地方用到了中介者模式呢?在Binder机制中,就用到了中介者模式,对Binder不是很熟悉的童鞋请参考我的《 简单明了,彻底地理解Binder》。我们知道系统启动时,各种系统服务会向ServiceManager提交注册,即ServiceManager持有各种系统服务的引用 ,当我们需要获取系统的Service时,比如ActivityManager、WindowManager等(它们都是Binder),首先是向ServiceManager查询指定标示符对应的Binder,再由ServiceManager返回Binder的引用。并且客户端和服务端之间的通信是通过Binder驱动来实现,这里的ServiceManager和Binder驱动就是中介者。
17 代理模式
定义:为其他类提供一种代理以控制这个对象的访问。
其实代理模式我们平时用的也比较多,其实比较好理解,就是当我们需要对一个对象进行访问时,我们不直接对这个对象进行访问,而是访问这个类的代理类,代理类能帮我们执行我们想要的操作。代理模式比较容易理解,既然你来看这篇文章相信你对代理模式不陌生。
我们直接看看代理模式在Android中的应用,如果你查看AIDL生成的代码就知道,它会根据当前的线程判断是否要跨进程访问,如果不需要跨进程就直接返回实例,如果需要跨进程则返回一个代理,这个代理干什么事情呢?我们在《 简单明了,彻底地理解Binder》提到,在跨进程通信时,需要把参数写入到Parcelable对象,然后再执行transact函数,我们要写的代码挺多的。AIDL通过生成一个代理类,代理类中自动帮我们写好这些操作。
18 组合模式
定义:将对象组成成树形结构,以表示“部分-整体”的层次结构,使得用户对单个对象和组合对象的使用具有一致性。
上面的定义不太好理解,我们直接从Android中用到的组合模式说起。我们知道,Android中View的结构是树形结构,每个ViewGroup包含一系列的View,而ViewGroup本身又是View。这是Android中非常典型的组合模式。
19 适配器模式
定义:把一个类的接口变换成客户端所期待的另一个接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作。
其实适配器模式很容易理解,我们在Android开发时也经常用到。比较典型的有ListView和RecyclerView。为什么ListView需要使用适配器呢?主要是,ListView只关心它的每个ItemView,而不关心这个ItemView具体显示的是什么。而我们的数据源存放的是要显示的内容,它保存了每一个ItemView要显示的内容。ListView和数据源之间没有任何关系,这时候,需要通过适配器,适配器提供getView方法给ListView使用,每次ListView只需提供位置信息给getView函数,然后getView函数根据位置信息向数据源获取对应的数据,根据数据返回不同的View。
20 装饰模式
定义:动态的给一个对象添加额外的智者,就增加功能来说,装饰模式比子类继承的方式更灵活。
通过简单代码来理解装饰模式:
public abstract class Component{
public abstract void operate();
}
public class ConcreteComponent extends Component{
public void operate(){
//具体的实现
}
}
public class Decorator{
private Component component;
public Decorator(Component component){
this.component=component;
}
public void operate(){
operateA();
component.operate();
operateB();
}
public void operateA(){
//具体操作
}
public void operateB(){
//具体操作
}
}
那么在Android哪里出现了装饰模式呢?我们平时经常用到Context类,但是其实Context类只是个抽象类,具体实现是ContextImpl,那么谁是ContextImpl的装饰类呢?我们知道Activity是个Context,但是Activity 并不是继承于Context,而是继承于ContextThremeWrapper.而ContextThremeWrapper继承于ContextWrapper,ContextWrapper继承Context.说了这么多,跟装饰模式有啥关系?主要是引入ContextWrapper这个类。ContextWrapper内部有个Context引用mContext,并且ContextWrapper中对Context的每个方法都有实现,在实现中调用的就是mContext相同的方法。
21 享元模式
定义:使用享元对象有效地支持大量的细粒度对象。
享元模式我们平时接触真的很多,比如Java中的常量池,线程池等。主要是为了重用对象。
在Android哪里用到了享元模式呢?线程通信中的Message,每次我们获取Message时调用Message.obtain()其实就是从消息池中取出可重复使用的消息,避免产生大量的Message对象。
22 外观模式
定义:要求一个子系统的外部与其内部的通信必须通过一个统一的对象进行。
怎么理解呢,举个例子,我们在启动计算机时,只需按一下开关键,无需关系里面的磁盘、内存、cpu、电源等等这些如何工作,我们只关心他们帮我启动好了就行。实际上,由于里面的线路太复杂,我们也没办法去具体了解内部电路如何工作。主机提供唯一一个接口“开关键”给用户就好。
那么Android哪里使用到了外观模式呢?依然回到Context,Android内部有很多复杂的功能比如startActivty、sendBroadcast、bindService等等,这些功能内部的实现非常复杂,如果你看了源码你就能感受得到,但是我们无需关心它内部实现了什么,我们只关心它帮我们启动Activity,帮我们发送了一条广播,绑定了Activity等等就够了。
23 桥接模式
定义:将抽象部分与实现部分分离,使他们独立地进行变化。
其实就是,一个类存在两个维度的变化,且这两个维度都需要进行扩展。
在Android中桥接模式用的很多,举个例子,对于一个View来说,它有两个维度的变化,一个是它的描述比如Button、TextView等等他们是View的描述维度上的变化,另一个维度就是将View真正绘制到屏幕上,这跟Display、HardwareLayer和Canvas有关。这两个维度可以看成是桥接模式的应用。
24 MVC、MVP、MVVP模式
MVC
全称为Model-View-Controller,也就是模型-视图-控制器。MVC结构如下图所示:
MVC
在Android中对MVC的应用很经典,我们的布局文件如main.xml就是对应View层,本地的数据库数据或者是网络下载的数据就是对应Model层,而Activity对应Controller层。
MVP
MVP全称为Model View Presenter,目前MVP在Android应用开发中越来越重要了,它的结构图如下:
MVP
它降低了View与Model之间的耦合。彻底将View与Model分离。MVP不是一种标准化的模式,它由很多种实现。
MVVM
全称是Mode View ViewModel,它的结构如下所示:
MVVM
我们在使用ListView时,会自定义一个ViewHolder,在RecyclerView中是必须使用ViewHolder,这主要是提高性能,因为不需要每次去调用findViewById来获取View。其实ViewHolder就是个ViewModel。