Android应用开发之Android设计模式-- 单例模式、建造者模式
凌雪 2018-10-24 来源 :网络 阅读 1117 评论 0

摘要:本文将带你了解Android应用开发之Android设计模式-- 单例模式、建造者模式,希望本文对大家学Android有所帮助。

本文将带你了解Android应用开发之Android设计模式-- 单例模式、建造者模式,希望本文对大家学Android有所帮助。


如果作为低年级入门的同学学习设计模式是比较困难的,建议先补充基础,积累经验再回过头进行学习设计模式,因为其中的重要性关乎到我们是否能够进阶成为相对优秀的Android工程师,高年级大佬麻烦多多指导。在阅读或者分析源码的时候,或多或少离不开设计模式,下面我只是挑了几个来谈谈我学习的理解。
在分享设计模式之前,我们先了解下设计模式的六大原则:
1.单一职责原则:对于一个类而言,应该仅有一个引起它变化的原因。通俗地理解是不要在Activity中写Bean文件、网络请求处理和Adapter等。
2.开放封闭原则:类、模块、函数等应该是可以拓展,但是不可以修改。在开发中,需求是变化的,如果有新的需求,我们就要重新把类改一遍显然是很爆炸的,所有进来通过扩展的方式实现
3.迪米特原则:一个软件应当尽可能少地和其他实体发生相互作用。
4.接口隔离原则:一个类对另一个类的依赖应该建立在最小的接口上,接口的负责化要适度
5.依赖倒置原则:高层模块不应该依赖底层模块,两者都应该依赖于抽象。抽象不应该依赖细节,细节应该依赖与抽象。读起来很拗口,在Java中,抽象是指接口和抽象类;细节是实现类;高层模块就是调用者,底层模块就是具体的实现类,我的理解是类跟类之间的依赖通过抽象产生的。
6.里氏替换原则:所有引用基类的地方必须能透明地使用其子类的对象。
下面进入设计模式的话题,包括了:
创造型设计模式:单例模式、建造者模式(ps:简单工厂模式和抽象工厂模式理解的还不是很好,所以先不做分享)、结构型模式中的享元模式和行为型设计模式中的策略模式、观察者模式
一、单例模式:保证一个类仅有一个实例,并且提供一个可以访问的方法
/** * 6种单例模式写法 * Created by XQM on 2018/5/13. */ //第一种,饿汉式.基于类加载机制,在类加载的时候就完成实例化,如果至始至终没有使用到该类会造成内存浪费public class SingleDemo {    private static   SingleDemo instance = new SingleDemo();     public   static SingleDemo   getInstance(){        return   instance;    }} //第二种,懒汉式,第一次加载时需要实例化,反应慢,在多线程并发不能保证单例public class SingleDemo{    private static   SingleDemo instance;     public static SingleDemo   getInstance() {        if (instance   == null){            instance   = new   SingleDemo();        }        return   instance;    }} //每次调用都需要同步,造成不必要的同步开销public class SingleDemo{    private static   SingleDemo instance;     public static synchronized   SingleDemo getInstance() {        if   (instance == null){            instance   = new   SingleDemo();        }        return   instance;    }} //双重检查模式DCL,在某些情况下会失效public class SingleDemo{    private static   SingleDemo instance;     public static SingleDemo   getInstance() {        if (instance   == null){            synchronized   (SingleDemo.class){                if   (instance ==   null){                    instance   = new   SingleDemo();                }            }        }        return   instance;    }} //静态内部类单例模式,第一次类加载的时候并不会初始化instance,//当且仅当调用了getInstance()时JVM加载SingleDemoHolder初始化instance,//所以保证了线程安全和单例,推荐使用public class   SingleDemo{     public static SingleDemo   getInstance() {       return   SingleDemoHolder.instance;    }     private   static class SingleDemoHolder{        private   static final SingleDemo instance = new   SingleDemo();    }} /** * 枚举单例 */public enum    SingleDemo{    INSTANCE;     private   void doSomThing(){     }}
补充下JVM对内部类的加载顺序
//静态内部类单例模式,推荐使用public class SingleDemo{    public static   SingleDemo getInstance() {       return   SingleDemoHolder.instance;    }     //类静态属性    public   static SingleDemo testOut = new   SingleDemo(1);     static   {        System.out.println("调用静态代码块:Static   function");    }    private   static class   SingleDemoHolder{        static   {            System.out.println("调用匿名内部类:Inner   Static");        }        private   static final SingleDemo instance = new   SingleDemo(3);     }     public   SingleDemo(int i) {        switch   (i){            case   1:                System.out.println("调用静态属性: " +" Construct!   "+i);                break;            case   2:                System.out.println("调用自身构造方法: " +" Construct!   "+i);                break;            case   3:                System.out.println("调用匿名内部类静态属性: " +"   Construct!   "+i);                break;        }    }} //主函数测试,根据下面的结果发现,初始化的时候,静态块和静态变量是按顺序的,内部类按需调用public class BuilderClient {    public   static void main(String[]   args){        SingleDemo singleDemo =   new   SingleDemo(2);        SingleDemo.getInstance();     }}
   
    二、建造者模式:用来创建复杂对象的模式,将其部件解耦。通常Android中的Dialog或者EventBus使用的时候会碰到。
/** * 定义产品 * Created by XQM on 2018/5/13. */public class   Computer {    private String   mCpu;    private String   mMain;    private String   mCard;    private String mRam;     public   String getmCpu() {        return   mCpu;    }     public void   setmCpu(String mCpu)   {        this.mCpu =   mCpu;    }     public String   getmMain() {        return   mMain;    }     public void   setmMain(String mMain) {        this.mMain   = mMain;    }     public String   getmCard() {        return   mCard;    }     public void   setmCard(String mCard)   {        this.mCard =   mCard;    }     public String   getmRam() {        return   mRam;    }     public void   setmRam(String mRam)   {        this.mRam =   mRam;    }     @Override    public   String toString() {        return   "Computer{"   +                "mCpu='"   + mCpu + '\'' +                ",   mMain='" + mMain + '\''   +                ",   mCard='" + mCard + '\'' +                ",   mRam='" + mRam + '\''   +                '}';    }}  /** *   抽象产品的组建 * Created   by XQM on 2018/5/13. */public abstract class Builder   {    public abstract void buildCpu(String   cpu);    public abstract void buildMainboard(String   main_board);    public abstract void   buildGraphicsCard(String graphics_card);    public   abstract void buildRam(String ram);     public   abstract Computer create();} /** * 真正的建造者,实现build的方法,然后返回组建好的对象 * Created by XQM on 2018/5/13. */public class   BuildComputer extends Builder {    private Computer   computer = new   Computer();     @Override    public   void buildCpu(String cpu) {        computer.setmCpu(cpu);    }     @Override    public   void buildMainboard(String main_board)   {        computer.setmMain(main_board);    }     @Override    public   void buildGraphicsCard(String graphics_card)   {        computer.setmCard(graphics_card);    }     @Override    public   void buildRam(String ram)   {        computer.setmRam(ram);    }     @Override    public   Computer create() {        return   computer;    }} public class Assembly   {    Builder builder;     public   Assembly(Builder builder)   {        this.builder =   builder;    }     public   Computer CreateComputer(String cpu ,String main,String card,String   ram){        builder.buildCpu(cpu);        builder.buildMainboard(main);        builder.buildRam(ram);        builder.buildGraphicsCard(card);        return   builder.create();    }} //测试主类public class BuilderClient {    public   static void main(String[]   args){        Builder builder = new   BuildComputer();        Assembly   assembly = new Assembly(builder);         Computer   sc = assembly.CreateComputer("i7-6700","联想","890","金士顿DDR4");         System.out.println(sc.toString());     }}
三、享元模式:是池技术的重要实现方式,可以减少应用程序创建对象,降低产生OOM风险,提高程序的性能。
/** * 抽象享元角色 * Created by XQM on 2018/5/13. */public interface   IGoods {    void showGoodsPrice(String   name);} /** * 具体享元角色,实现抽象享元角色 * Created by XQM on 2018/5/13. */public class Goods   implements IGoods {    private String name;//名称,内部状态    private   String attribute;//属性,外部状态     public Goods(String name)   {        this.name =   name;    }     @Override    public   void showGoodsPrice(String attribute)   {        if (attribute.equals("红色")){            System.out.println("有货,价格是:8974元");        }else   {            System.out.println("有货,价格是:8974元");        }    }} /** *   享元工厂用来创建具体的享元角色,通过map来缓存对象 * 如果系统存在大量的相似对象或者缓存池的场景可以使用 *   Created by XQM on 2018/5/13. */public class GoodsFactory   {    private static Map<string,goods> goodsMap =   new HashMap<>();     public static Goods   getGoods(String name){        if   (goodsMap.containsKey(name)){            System.out.println("缓存中找到商品,key:"+name);            return   goodsMap.get(name);        }else   {            Goods   good = new   Goods(name);            goodsMap.put(name,good);            System.out.println("创建商品,key:"+name);            return   good;        }    }}  /** *测试类 * 享元模式缓存对象,避免OOM * Created by XQM on 2018/5/13. */public class   FlywightClient {    public static void main(String[]   args){        Goods goods =   GoodsFactory.getGoods("华为3e");        goods.showGoodsPrice("红色");         Goods   goods1 = GoodsFactory.getGoods("华为3e");        goods1.showGoodsPrice("幻影黑");         Goods   goods2 = GoodsFactory.getGoods("华为9");        goods2.showGoodsPrice("幻影黑");     }}</string,goods>
   
    四、策略模式:定义一系列的算法,把算法封装起来,并且是它们可以相互替换,使得算法可以独立于使用它的客户而独立变化。比如代码有很多if…else或者case,会变得比较臃肿,维护成本也比较高,违背开放封闭原则,通过策略模式就可以简化。
/** * 定义一个程序开发的接口 * 抽象策略角色 * Created by XQM on 2018/5/13. */public interface   IDevelopStrategy {    void develop();} /** * 开发 * Created by XQM on   2018/5/13. */public class APPStrategy implements IDevelopStrategy   {    @Override    public void   develop()   {        System.out.println("产品发话了,需要开发APP");    }} /** *   具体的策略 * Created by   XQM on 2018/5/13. */public class WebSiteStrategy implements   IDevelopStrategy   {    @Override    public void   develop()   {        System.out.println("产品发话了,需要开发网站");     }} /** *   上下文角色的构造方法根据传递进来不同的具体策略来调用不用的develop() *   屏蔽调用者对策略的直接访问,启动承上启下作用 *   Created by XQM on 2018/5/13. */public class Context   {   private IDevelopStrategy   strategy;     public Context(IDevelopStrategy   strategy) {        this.strategy =   strategy;    }     public void   develop(){        strategy.develop();    }} /** *   每一个策略都是一个类,复用性小 * 上层模块必须知道有哪些策略才可以使用 * Created by   XQM on 2018/5/13. */public class StrategyClient   {    public static void main(String[]   args){        Context   context;         //开发APP        context   = new Context(new   APPStrategy());        context.develop();        //开发网站        context   = new Context(new   WebSiteStrategy());        context.develop();    }}
   
    五、观察者模式:定义对象间一对多的依赖关系,每当一个对象改变状态时,则所有依赖于它的对象都会得到通知并且被自动更新。常见运用在发布-订阅事件总线。
/** * 把所有的观察者对象保存在一个集合中,其中每一个主题可以有任意数量的观察者,可以想象为公众号 * Created by XQM on 2018/5/13. */public interface   ObservedSubject {    /**     * 增加观察者     *   @param observer     */    void   add(Observer   observer);     /**     * 删除观察者     *   @param observer     */    void   delete(Observer   observer);     /**     * 通知更新     *   @param message     */    void   notify(String message);} /** * 抽象被观察者的实现类,实现添加、删除和通知观察者的方法 * Created by XQM on 2018/5/13. */public class   SubcriptionSubject implements ObservedSubject   {    private List<observer> subscriberUsers = new   ArrayList<observer>();    @Override    public   void add(Observer oberver)   {        subscriberUsers.add(oberver);    }     @Override    public   void delete(Observer observer) {        subscriberUsers.remove(observer);    }     @Override    public   void notify(String message)   {        for (Observer   observer:subscriberUsers){            observer.update(message);        }    }} /** *   抽象观察者 * Created by   XQM on 2018/5/13. */public interface Observer   {    void update(String message);}/** * 具体观察者 * Created by XQM on   2018/5/13. */public class SubscriberUser implements Observer   {    private String   name;     public SubscriberUser(String name)   {        this.name =   name;    }     @Override    public   void update(String message)   {        System.out.println(name+"更新了:"+message);    }} /** *   优点:观察者和被观察者之间是抽象耦合,容易扩展 *   缺点:在Java中消息的通知一般是按照顺序的,如果每个观察者造成卡顿,会影响整体的效率,采用异步解决 * Created by XQM on 2018/5/13. */public class   ObserverClient {    public static void main(String[]   args){        SubcriptionSubject   subcriptionSubject = new SubcriptionSubject();         SubscriberUser   user1 = new SubscriberUser("下雨了");        SubscriberUser   user2 = new SubscriberUser("下雪了");        SubscriberUser   user3 = new SubscriberUser("落花了");         //注册订阅        subcriptionSubject.add(user1);        subcriptionSubject.add(user2);        subcriptionSubject.add(user3);         //发送更新给订阅者        subcriptionSubject.notify("不一样的博客更新了");     }</observer></observer>
   
    对比下Java中的观察者实现:
import java.util.Observable; /** * 继承Observable类(被观察者发送消息),notifyObservers发送通知 * Created by XQM on   2018/3/22. */public class Gamedaily extends Observable   {    public void postNewArticle(String   content){        //内容改变        setChanged();         //通知所有订阅者改变内容        notifyObservers(content);    }} import   java.util.Observable;import java.util.Observer; /** * 定义观察者,继承observer接口,实现update方法 * Created by XQM on 2018/3/22. */public class User   implements Observer{    public String   name;     public User(String name)   {        this.name = name;    }     @Override    public   void update(Observable observable, Object o)   {        System.out.println("Hi   "+name +",公众号更新了内容:"+o);    }}  /** *   Created by XQM on 2018/3/22. */public class Client   {    public static void main(String[]   args){        Gamedaily gamedaily =   new Gamedaily();        User user0 =   new   User("user0");        User   user1 = new   User("user1");        User   user2 = new User("user2");         gamedaily.addObserver(user0);        gamedaily.addObserver(user1);        gamedaily.addObserver(user2);         gamedaily.postNewArticle("有新文章更新了");    }}    

本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标移动开发之Android频道!

本文由 @凌雪 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式AI+学习就业服务平台 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved