Android设计模式

目录

  • 单例模式
  • 适配器模式
  • Builder模式
  • 简单工厂

单例模式

声明:我是全部抄这位大神的文章,作为学习笔记

http://www.cnblogs.com/yinxiaoqiexuxing/p/5605338.html

SingleTon是一种创建模型,指某个类采用了singleton模式,则这个类被创建后,只可能产生一个实例供外部访问,并且提供一个全局的访问点。

核心知识点:

  • 单例模式的类的构造方法私有化(采用private修饰)
  • 在其内部产生该类的实例化对象,并用private static修饰
  • 定义一个静态的方法,返回该类的实例
/** 
 * 方法一:饿汉式,线程安全,效率低 
 * 优点:简单,不存在多线程问题,避免了synchronized所造成的性能问题
 * 缺点:当SingleTon类被加载的时候,会初始化static的singleTon,静态变量被创建并分配内存空间,
 *      从这以后这个static的singleTon对象就一直占用这块内存, 即便你用不到这个实例,
 *      当类被卸载的时候,静态的变量被销毁,并释放内存,因此在某些特定的条件下回耗费内存   
 */ 

public class SingleTon{
    //static和final修饰
    private static final SingleTon singleTon = new SingleTon();  

    private SingleTon(){ }  

    public static SingleTon getInstance(){
        return singleTon;
    }
}
/**  
 * 方法二:饱汉式,非线程安全   
 * 优点:简单,当SingleTon类被加载的时候,静态变量singleTon未被创建并分配内存,当getInstance第一次被执行的时候,singleTon的实例才会被
 * 创建,并分配内存,所以某些特定条件下节约了内存。
 * 缺点:线程并发环境下可能会出现多个SingleTon实例
 */

public class SingleTon{
    private static SingleTon singleTon;

    private SingleTon(){ }

    public static SingleTon getInstance(){
        if(singleTon==null){
            singleTon = new SingleTon();
        }
        return singleTon;
    }
}
/**  
 * 方法三:饱汉式,线程安全简单实现
 * 优点:使用synchronized关键字避免多线程访问时,出现多个SingleTon实例
 * 缺点:同步方法频繁调用时,效率略低   
 */

public class SingleTon{
    private static SingleTon singleTon;

    private SingleTon(){}

    public static synchronized SingleTon getInstance(){
          if(singleTon==null){
              singleTon = new SingleTon();
          }
          return singleTon;
    }

}
/**  
 * 方法四:单例模式最优方案,线程安全且效率高  
 * 
 */ 

public class SingleTon{
    private static volatile SingleTon singleTon; //volatile修饰,保证了多线程访问的一个变量值统一

    private SingleTon(){}

    public static SingleTon getInstance(){
        if(singleTon==null){
              synchronized(SingleTon.class){
                    if(singleTon==null){
                            singleTon=new SingleTon();
                    }
              }
        }
        return singleTon;
    }
}
/**
 * 方法五:简单高效,多线程可用,按需创建,节省空间
 * SingleTon创建内部类SingleLoader不会创建
 * 只有外部调动SingleTon.getInstance时,才会加载内部类
 */

public class SingleTon {

    private SingleTon(){}

    private static class SingleLoader{
        private static final SingleTon instance = new SingleTon();
    }

    public static SingleTon getInstance(){
        return SingleLoader.instance;
    }
}

适配器模式

参考资料:
http://www.cnblogs.com/imeiling/p/6394738.html
http://blog.csdn.net/u011240877/article/details/52601040

什么是适配器模式,简单的说就是开发中我们设计了一个接口,但是由于某种原因这个接口不满足我们的需求,比如处理的逻辑不同等导致我们不能复用这个接口,这时就需要自己创造一个适配器,来满足需求,提高代码的兼容性。这个适配器可以是一个类也可以是一个对象。

应用场景

A类需要调用M方法,B类中有M方法,但是如果A直接调用B的M方法,得到的结果并不满足A的需求。这样的设计B类被写死,不符合我们编程复用性的思想。所以我们可以把B类设计成一个接口,再实现出一些其他类,供其他有特殊需求的类使用,比如A类。

两种类型
  • 类适配器
  • 对象适配器

类适配器:

  1. 设计一个接口K,让他有M方法
  2. 在B类中创建一个specialM方法,处理A类的特殊需求
  3. 让A类继承B类,并实现K接口,A中拥有了M方法
  4. 在A类的M方法中,用super.specialM()方式调用B类的M方法

对象适配器:

  1. 设计一个接口K,让他有M方法
  2. 在B类中创建一个specialM方法,处理A类的特殊需求
  3. A类实现K接口,并在A类中声明一个B类成员变量,通过构造方法传入。
  4. 如果需要,在A的M方法中,调用b变量的specialM方法

总之,两端不变,通过我们创建的适配器来,满足需求,这就是适配器。

代码

场景:一位中国人不会英语,他需要通过翻译来和外国人交流

// 说汉语的接口
public interface SayChinese {
    void sayChinese(String s);
}
// 能说英语的类适配器
public class SayEnglish {
    public void sayEnglish(String s){
        // 说的英文
        Log.e("TAG","my god, I can speak english"+s);
    }
}

类适配器写法:

// 翻译类
public class Translator extends SayEnglish implements SayChinese {
    // 翻译类拥有了说汉语的方法
    @Override
    public void sayChinese(String s) {
        // 调用说英文的方法
        super.sayEnglish(s);
    }
}
Translator translator = new Translator();
translator.sayChinese("我是中国人");

对象适配器写法:

public class Translator implements SayChinese {

    public SayEnglish english;

    public Translator(SayEnglish sayEnglish){
        this.english = sayEnglish;
    }

    // 翻译类用有了说中文的方法
    @Override
    public void sayChinese(String s) {
        // 调用说英文的方法
        //super.sayEnglish(s);

        english.sayEnglish(s);
    }
}

SayEnglish english = new SayEnglish();
Translator translator = new Translator(english);
translator.sayChinese("我是中国人");

Builder模式

学习资料(非常敬佩这位作者,原来知识可以这样讲)
http://blog.lmj.wiki/2016/11/13/design-pattern/builder/

什么是Builder模式,先从字面意思可以知道是创建者、构造者的意思。那作为创建者,我们就有很大的权利来决定怎样去创造一个对象。比如我们平时创建一个对象,构造方法里面有3个参数,那我们创建对象时,就必须按照顺序传入参数,有一定的限制。那通过builder模式后,我创建复杂的对象时,很自由,有种无拘无束的感觉,以可以少传参数,你再也不用担心顺序的问题。

场景及代码

做为程序员的小光逃离北上广,回家创业卖热干面了,热干面的配料有葱花、香菜、辣椒、酸菜,不同人有不同的需求。期初小光这样做热干面。


public class HotNoodls {
    
    private boolean conghua;
    private boolean xiangcai;
    private boolean lajiao;
    private boolean suancai;

    public HotNoodls(boolean conghua, boolean xiangcai, boolean lajiao, boolean suancai) {
        this.conghua = conghua;
        this.xiangcai = xiangcai;
        this.lajiao = lajiao;
        this.suancai = suancai;
    }

    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();
        if (conghua) {
            builder.append("葱花.");
        } else if (xiangcai) {
            builder.append("香菜.");
        } else if (lajiao) {
            builder.append("辣椒.");
        } else if (suancai) {
            builder.append("酸菜.");
        }
        return builder.toString();
    }
}

来了位客人要一份人干面,只要葱花、香菜,小光做出的热干面:

HotNoodls hotNoodls = new HotNoodls(true,true,false,false);

突然有一天一位客人不要辣椒,方葱花,结果小光做错了,因为这哥们不安套路出牌,导致小光放错配料了。
后来小光想了想,让客户自己放配料,然后我直接拿去做,这样就不会出现错了。于是热干面就成这样的了

public class HotNoodls {

    private boolean conghua;
    private boolean xiangcai;
    private boolean lajiao;
    private boolean suancai;

    public HotNoodls(Builder builder) {
        this.conghua = builder.conghua;
        this.xiangcai = builder.xiangcai;
        this.lajiao = builder.lajiao;
        this.suancai = builder.suancai;
    }

    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();
        if (conghua) {
            builder.append("葱花.");
        } else if (xiangcai) {
            builder.append("香菜.");
        } else if (lajiao) {
            builder.append("辣椒.");
        } else if (suancai) {
            builder.append("酸菜.");
        }
        return builder.toString();
    }

    public static class Builder{

        public boolean conghua;
        public boolean xiangcai;
        public boolean lajiao;
        public boolean suancai;
        
        public Builder withCongHua(){
            this.conghua = true;
            return this;
        }
        
        public Builder withXiangCai(){
            this.xiangcai = true;
            return this;
        }
        
        public Builder withLaJiao(){
            this.lajiao = true;
            return this;
        }
        
        public Builder withSuanCai(){
            this.suancai = true;
            return this;
        }
        
        public HotNoodls build(){
            return new HotNoodls(this);
        }
    }
}

一份热呼呼的热干面上来啦,这下就不会出现给客人放错配料的问题了

HotNoodls hotNoodls = new HotNoodls.Builder()
                .withCongHua()
                .withLaJiao()
                .build();

简单工厂模式

继小光卖热干面后,他又卖饮料来作为一种配套营销模式,开始小光这样做饮料,如橙汁:

public class OrangeJuice {
    public void make(){
        // 1. 拿出一次性饮料杯
        System.out.println("拿出一次性饮料杯");
        // 2. 加入速溶橙汁粉
        System.out.println("加入速溶橙汁粉");
        // 3. 加水冲兑
        System.out.println("加水");
        // 4. 加盖, 打包
        System.out.println("加盖, 打包");
    }
}

因为加入不同的速溶粉,才能制作出不同的果汁,所以这样的方式肯定不合理,于是效果这样做果汁,提高了扩展性。

public abstract class Drink {

    public void make(){
        // 1. 拿出一次性饮料杯
        System.out.println("拿出一次性饮料杯");
        // 2. 加入速溶橙汁粉
        System.out.println("加入"+getInstanceName());
        // 3. 加水冲兑
        System.out.println("加水");
        // 4. 加盖, 打包
        System.out.println("加盖, 打包");
    }

    abstract String getInstanceName();
}
public class OrangeJuice extends Drink {
    @Override
    String getInstanceName() {
        return "橙汁";
    }
}
public class AppleJuice extends Drink {
    @Override
    String getInstanceName() {
        return "苹果汁";
    }
}

这样的话,小光每次制作不同的饮料的时候都需要这样

OrangeJuice orangeJuice = new OrangeJuice();
orangeJuice.make();

而我们的工厂模式是想通过向工厂中传入一些参数就会创建出对应的实力。所以我们还需要改造,如下:

public class DrinkFactory {
    public static Drink creat(String drinkName){
        switch (drinkName){
            case "橙汁":
                return new OrangeJuice();
            case "苹果":
                return new AppleJuice();
            default:
                return new OrangeJuice();
        }
    }
}

这样就是我的工厂模式的freestyle了

Drink drink = DrinkFactory.creat("橙汁");
drink.make();
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,378评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,356评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,702评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,259评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,263评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,036评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,349评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,979评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,469评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,938评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,059评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,703评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,257评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,262评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,485评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,501评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,792评论 2 345

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,599评论 18 139
  • 适配器模式是咋Android中使用非常广泛的一种设计模式,总到处可见的Adapter就可以看出来。适配器模式类似于...
    喵了个呜s阅读 575评论 0 1
  • 适配器模式 适配器模式数据结构型设计模式. 适配器模式主要用于将2个不能兼容的物件结合在一起.分为类适配器和对象适...
    Ch3r1sh阅读 254评论 0 0
  • 本章是我们的API之旅的转折点。我们已经结束了基础部分的浏览,准备来看看之前的概念如何与构建API结合起来。在这一...
    IT宅男阅读 1,157评论 0 10
  • 这本书为日本高桥政史写的,主要是运用一张纸来完成工作。读完后印象比较深的就是用16格来做笔记, 思维导图的运用,结...
    e5e98276a29c阅读 2,126评论 0 8