android常用设计模式

一、设计模式

  1、单例模式

    一般单例模式的意思是全局中只用一个实例。下面示范使用单例的两个比较好的案例。

  ⑴ 懒汉模式

 

/** 懒汉模式,双重校验锁
 * Created by chenjk on 2018/8/6.
 */

public class Single {
    //单例
    private static voletite Single _instant;
    //注意设置为private,私有模式,只有通过内部生成实例,保证内部构造函数不被访问,保持单例
    private Single(Context context ){

    }

    /**  懒汉模式
     * @param context
     * @return
     */
    public static Single getInstance(Context context){
         if (_instant==null){
              //这里注意要加锁,保证线性安全
             synchronized (Single.class){
                 if(_instant==null){
                   _instant = new Single(context);
                 
                 }
                 return _instant;
             }
         }
         return _instant;
    }
}

 

⑵ 饿汉模式

   

/** 饿汉模式
 * Created by chenjk on 2018/8/6.
 */

public class HungrySingle {
    private static HungrySingle _intant; //单例
    //同时构造函数需要私有化
    private HungrySingle(){

    }
    public static HungrySingle getInstance(Context context){
        return  Holer.hungrySingle;
    }

 
    static class Holer{
        static  HungrySingle hungrySingle = new  HungrySingle(); 
    }
}

 

     说明:饿汉模式与懒汉模式的区别在于, * 懒汉模式在需要的时候才初始化出来,饿汉模式在进程启动的时候就创建了实例了。饿汉模式使用了内部类的形式,比在外部类去实例化更合理一些,因为你无法确定外部类是否被被动的加载出来,这个时候初始化实例对象就有点浪费内存了,具有那么一点优势所在,所以更推荐。单例应该被慎用,尽量减少内存的使用。分情况使用懒汉单例和饿汉单例。

           

  2、构建者模式

      构建者模式在android开发中尤为常见,也是我比较常用和比较喜欢的设计模式之一。比较在我们的AlerDialog当中,如下:

     

AlertDialog.Builder builder = new AlertDialog.Builder(MainApplication.getApplication());
AlertDialog alertDialog = builder.setMessage("测试")
        .setCancelable(false)
        .create();

 构造者模式,可以根据你的需求构造你需要的一些信息出来,其他的为默认。我在设计mvp框架中model实现层的时候经常会用到构造者模式去设计,以满足一些类似接口的需求。还有我应用在构建生成普遍的dialog当中去快捷的生成dialog,不用每次都去创建一个dialog类。

   

class Model {
    protected  boolean isFromCache;
    protected int cacheTime;
    protected boolean isLoading;

    private Model(boolean isFromCache, int cacheTime, boolean isLoading) {
        this.isFromCache = isFromCache;
        this.cacheTime = cacheTime;
        this.isLoading = isLoading;
    }
    static class Buidler{
        protected  boolean isFromCache;
        protected int cacheTime;
        protected boolean isLoading;

        public Buidler setCacheTime(int cacheTime) {
            this.cacheTime = cacheTime;
            return this;
        }

        public Buidler setLoading(boolean loading) {
            isLoading = loading;
            return this;
        }

        public Buidler setFromCache(boolean fromCache) {
            isFromCache = fromCache;
            return this;
        }
        public Model create(){
            return new Model(isFromCache,cacheTime,isLoading);
        }
    }
}

使用方法:

  

public class TestModel {
    public Model getModelInstance(){
        Model model = new Model.Buidler()
                .setCacheTime(10*1000)
                .setFromCache(true)
                .setLoading(true)
                .create();
        return model;

    }
}

     

  3、策略者模式

           也许你见过很多代码,伴随着很多的if else,或者switch case,有些分得清的还好,有些阅读性很差,这时候策略者模式发挥作用了。策略者模式表现为做的同一件事,而用不同的方法去实现。现实中的使用场景也很多,比如你是个管理者,你下面有多个手下,上级把任务分配了给你。这时候你要做的是,指示你的下级去做什么事,然而这件事是抽象的,比较开发安卓,开发ios,这个工作由你指派,具体实现是在下级那里去实现。

    首先,你是管理者,你要先明确你的职责,你想让他们干什么,这个是抽象的,所以定义一个接口,这里就让他们开发出一个产品。

public interface IDev {
    Product develop();
}

定义产品

public class Product {
    /**
     *  产品
     */
    private String product;

    public Product(String product) {
        this.product = product;
    }
}

这里时候你就需要指派他们工作去做了。

public class Factory {

    private IDev iDev;
//    private String type;

    public  Factory(IDev iDev){
        this.iDev = iDev;
    }
//    public void Factory(String type){
//        this.type = type;
//    }
    public Product doWork(){
          Product product = null;
//          if ("ios".equals(type)){
//              product = new Product("this is ios product");
//          }else if ("android".equals(type)){
//              product = new Product("this is android product");
//          }else if ("web".equals(type)){
//              product = new Product("this is web product");
//          }else if ("pc".equals(type)){
//              product = new Product("this is pc product");
//          }
          //假如这里有一千种方式,那么这里将很长,业务拓展修改也很麻烦,下面是策略者模式实现方式,具体实现由IDev实例去实现
          product =  iDev.develop();
          return product;
    }
}

 

大概的策略者模式的工作就做完成了,下面看看我们怎么去使用他。

public class TestDevProduct {
    public List getMutilProduct(){
        List productList = new ArrayList<>();
        productList.add(new Factory(new AndroidDev()).doWork());
        productList.add(new Factory(new IOSDev()).doWork());
        productList.add(new Factory(new WebDev()).doWork());
        return productList;
    }
}

 总结:如Factory的dowork方法所示,拓展性提高了很多,阅读性也很高。所以建议大家赶快学起来吧。

 

 

  4、代理模式

       代理模式在android也比较常见,比如okhttp中插入拦截器就是用的代理模式。举个工作的例子,比如你个android开发者,到了中午了,你需要出去打饭和取钱,又想留在公司解决点没解决的bug。而你的ios开发者同事,到了中午了,他也需要打饭,取钱,这时候就可以让你ios同事代理你去打饭取钱,你是代理者,你的ios同事是被代理者。 你的ios同事接受了你的代理,但是他不甘愿把时间花在打饭取钱时间上,想留点时间去打游戏啊,就委托web同事去打饭取钱。android开发委托ios去做,ios是被代理者,ios又委托web同事去做,ios也是代理者。

  第一步。

抽象个主题出来: 打饭、取钱

public interface ISubject {

    /** 买饭
     * @return 饭
     */
    String buyFood();

    /** 取钱
     *
     */
    void drawMoney();
}

第二步,以架构的角度,抽取一个的代理类基类(注意java单继承)

** 代理类抽象出来的基类
 * Created by chenjk on 2018/8/7.
 */

public abstract class BaseSubject implements ISubject {
    //被代理的类
    public ISubject proxySubject;
    protected BaseSubject(ISubject proxySubject){
        this.proxySubject = proxySubject;
    }
    @Override
    public String buyFood() {
        if (proxySubject!=null){
            return proxySubject.buyFood();
        }
        return null;
    }

    @Override
    public void drawMoney() {
        if (proxySubject!=null){
            proxySubject.drawMoney();
        }
    }
}

定义android开发者。继承代理成为代理类

public class AndroidDeveloper extends BaseSubject {

    protected AndroidDeveloper(ISubject proxySubject) {
        super(proxySubject);
    }
    /**
     *  除了让别人去买饭,取钱之后,我可以单独干我自己事。
     */
    public void playGame(){
        Log.i("tag","i want to play game");
    }
}

定位ios开发者

 * Created by chenjk on 2018/8/7.
 */

public class IOSDeveloper extends BaseSubject {
    public IOSDeveloper(ISubject proxy){
        super(proxy);
    }

    /**
     *  出了买饭,取钱,我想自己空点时间去取钱
     */
    public void doWork(){
        Log.i("tag","I want to work");
    }
}

 

定义web开发者,他只是个被代理者,真正的执行者

** 被代理类
 * Created by chenjk on 2018/8/7.
 */

public class WebDeveloper implements ISubject {

    @Override
    public String buyFood() {
        return "chiken";
    }

    @Override
    public void drawMoney() {
        Log.i("tag","$100000000");
    }
}

让我们写个类是去测试

public class TestProxy {

    private void testProxy(){
        WebDeveloper webDeveloper = new WebDeveloper();
        //ios买饭取钱,代理web开发去做
        IOSDeveloper iosDeveloper = new IOSDeveloper(webDeveloper);
        //android 买饭取钱,代理ios去做;
        AndroidDeveloper developer = new AndroidDeveloper(iosDeveloper);
        //最后让web开发去做
        webDeveloper.buyFood();
        webDeveloper.drawMoney();
    }
}

  5、观察者模式

   观察者模式在android开发中比较常见,相信使用过eventbus的开发者对观察者模式并不陌生,运行的就是订阅/被订阅的观察者模式。像我们baseAdapter也是用了观察者模式通知数据变化的。 你可以使用系统提供的Observable和Observer,但是Observable是个类,由于单继承的限制,使用上难免会有限制,下面我将使用我的方式来实现广播

   类似Observer,我们定义一个 类似Observer接口。如下,采用泛型的方式,支持可以收到的数据

/** 观察者抽象接口
 * @note 可以收到监听的数据
 * Created by chenjk on 2018/8/8.
 */

public interface IObserver{
    void onChange(T data);
}

下面我们定义两个观察者,android开发观察者和ios开发观察者

public class AndroidDev implements IObserver {
    @Override
    public void onChange(String data) {
        Log.i("data",data);
    }
}
public class IOSDev implements IObserver {
    @Override
    public void onChange(String data) {
        Log.i("data",data);
    }
}

收到数据后他们将打印出收到的内容。

由于单继承的限制,使得我们在使用上不方便,我们将采用接口的方式取代Observable。如下

/** 被观察者抽象接口
 * Created by chenjk on 2018/8/8.
 */

public interface IObserverable{
    /**
     *  订阅观察
     *  定义能注册Obect类型
     */
    boolean registObserve(IObserver o);

    /** 取消订阅观察
     * @param o
     * @return
     */
    boolean unRegistObserve(IObserver o);

    /**
     *   给所有订阅者发送通知
     */
    void sendChange();

    void sendChangWithData(T data);
}

 接下定义被观察者

public class ChatManager implements IObserverable{
    private List iObserverList;
    @Override
    public boolean registObserve(IObserver o) {
        if (iObserverList==null){
            iObserverList = new ArrayList<>();
        }
        return  iObserverList.add(o);//把它加入观察者队列
    }

    @Override
    public boolean unRegistObserve(IObserver o) {
        if (iObserverList!=null){
            return iObserverList.remove(o);
        }
        return false;
    }

    @Override
    public void sendChange() {
         for (IObserver iObserver:iObserverList){
             iObserver.onChange("");
         }
    }

    @Override
    public void sendChangWithData(String data) {
        for (IObserver iObserver:iObserverList){
            iObserver.onChange("");
        }
    }

}
public class ChatManager implements IObserverable{
    private List iObserverList;
    @Override
    public boolean registObserve(IObserver o) {
        if (iObserverList==null){
            iObserverList = new ArrayList<>();
        }
        return  iObserverList.add(o);//把它加入观察者队列
    }

    @Override
    public boolean unRegistObserve(IObserver o) {
        if (iObserverList!=null){
            return iObserverList.remove(o);
        }
        return false;
    }

    @Override
    public void sendChange() {
         for (IObserver iObserver:iObserverList){
             iObserver.onChange("");
         }
    }

    @Override
    public void sendChangWithData(String data) {
        for (IObserver iObserver:iObserverList){
            iObserver.onChange("");
        }
    }

}

 

如果你觉得每次都要去写这些复杂的操作,我建议将这个作为一个基类,定义为  abstract class(这样就跟系统的Observable一样了。)

 

            

你可能感兴趣的:(android架构思想,android设计模式)