android基础-Java篇07:常用的三种设计模式:Singleton、Template、Strategy模式

一、Singleton单例模式

    单例指的只能存在唯一的一个实例对象(单例)

    单例模式的设计思路:先阻止类可以类外部通过new的方式(构造函数)创建实例,并在类的内部创建一个获得该类实例的静态方法,用来创建该类实例(不存在实例时)或者返回实例(存在实例时)从而实现单一实例的控制。

实现例程如下,经典的饿汉式例程和懒汉式例程:

饿汉式例程:

public class HungryMan{

    private HungerMan(){};

    privatestatic final HungerMan hungerman = new HungerMan();

    publicstatic HungerMan getInstance(){

        return hungerman;

    }

}

懒汉式例程:

Public class LazyMan{

    private LazyMan(){}

    private static LazyMan lazyman = null;

    public static LazyMan getlazyman(){

        if(lazyman== null){

            synchronized(LazyMan.class){

                if(lazyman== null){lazyman = new LazyMan();}

            }

        }

    }

    return lazyman;

}

(所谓的饿汉式和懒汉式的定义,并不是站在上帝视角去定义的,而是从程序视角定义的,在定义hungerman时,饿汉式就一股劲的迫不及待的去定义完整(因为很饿),懒汉式就先声明个对象引用就不继续了(因为很懒,老想着以后的事情以后再做好了),所以把定义工作放在要用到的时候再去定义,所以放在getlazyman上。)

    可以看到,Singleton模式首先先对其构造方法的权限声明为private,阻止类外部通过构造方法创建实例,再提供get方法来获取唯一实例。但是要特别注意的是,在懒汉式例程中get方法内部采用了synchronized锁声明(只允许一个线程进入)。如果没有声明的情况下,如下:

public static LazyMan getlazyman(){

    if(lazyman== null){ lazyman = new LazyMan(); }

    return lazyman;

}

    在多线程下使用是非常危险的(不安全的),有可能出现这种情况,唯一实例并未创建时,多个线程都调用类内部创建类的方法,而且都运行到if(lazyman == null)内部而且在运行lazyman = newLazyMan();之前的地方,这就非常尴尬了,这个时候lazyman=null,if里的条件语句是true,所以可以进入到if内部,也就多个线程都通过了我们原本为了限制实例数量的判断语句,而且下一步都是lazyman= new LazyMan();,这样在堆中就存在多个LazyMan实例了,这就和我们预期遐想的不同了。


二、Template模式(模板模式)

    模板模式,顾名思义,设定了模板,并让接下来代码实现都按照一个模板进行,说到模板,很容易就联想到了抽象类和接口的运用,定义了方法名,没有方法体,然后让子类去实现、继承、扩展他们的方法,那么,抽象类和接口的方法不妨就充当了“模板”的作用,也就是骨架,这就是模板模式。

在模板模式中,可分为抽象模板(AbstractTemplate)和具体模板(Concrete Template)

抽象模板也就是骨架,定义一个或多个操作(方法),以便被子类实现。

具体模板指的就是对抽象模板的实现,也可以说就是子类。


在抽象模板中的基础方法又可以分为:抽象方法(AbstractMethod)、具体方法(Concrete Method)、钩子方法(Hook Method)

抽象方法对应抽象类中的抽象方法,具体方法对应抽象类中具体方法,钩子方法对应抽象类(接口)中的空方法。

例程:

//定义了一个抽象类,名字为SteamRice(煮饭、蒸饭),方法分别为PutRice(下米)、WashRice(洗米)、CookRice(煮米)

//这个类说明了煮饭的基本过程,是煮饭的骨架,什么饭都是这个步骤。

//而它的子类就对其进行了不同的实现,但是骨架还是不变的。

public abstract class SteamRice{

    public abstract void PutRice();

    public abstract void WashRice();

    public abstract void CookRice();

}

public class ZhenZhuMi extends SteamRice{

    public void PutRice(){System.out.println("下珍珠米");}

    public void WashRice(){System.out.println("洗一次");}

    public void CookRice(){System.out.println("水位高于米3cm,用砂锅煮");}

}

public class JianMi extends SteamRice{

    public void PutRice(){System.out.println("下尖米");}

    public void WashRice(){System.out.println("洗两次");}

    public void CookRice(){System.out.println("水位高于米1.5cm,用电饭锅煮");}

}

 

三、Strategy策略模式

    在模板设计模式中,我们是通过抽象类(或者实现接口)制作模板,通过继承抽象类(或者实现接口)来实现模板,是一种重心放在子类上的逻辑。而策略模式其逻辑是反过来的,是一种重心放在父类上的逻辑,主要是通过父类对象对子类改写的方法进行调用。

    在策略模式中,可以通过策略(Strategy)一词来理解这个模式的逻辑,在逻辑上将策略的作用(目的)和策略的具体实施计划分开,父类被称为抽象策略(Strategy),也就是相当策略的作用(目的),只提供一个骨架,而其子类被称为具体策略(ConcreteStrategy),也就是相当策略的具体实施计划,每个子类都是一个计划。当然,既然是策略,那么就有策略的使用者,这个使用者在策略模式中称为Context(上下文、环境),正如上面所说的,在Context中创建一个Strategy的对象引用去调用ConcreteStrategy的具体实现。

    所以,策略模式是相当于对一系列解决方案(或算法等)包装到一系列的策略类里面去,然后通过父类对象去访问具体实现策略的子类,而提供多种解决方案,因为这些方案都是解决相同的问题,所以这些方案都可以互换,都不会影响使用方案的客户端。

采用了模板模式的例子进行补充:

例程一:通过传入米的类型

public class Context {

    private SteamRice steamRice;

    private String RiceType;

    public Context(String RiceType){

        this. RiceType = RiceType;

    }

    public void contextInterface(){

        if(RiceType. equals(珍珠米)){

            steamRice= new ZhenZhuMi();

        }else if(RiceType. equals(尖米)){

            steamRice = new JianMi();

        }

        steamRice.PutRice();

        steamRice.WashRice();

        steamRice.CookRice();

    }

}


例程二:直接传入子类对象向上转型

public class Context {

    private SteamRice steamRice;

    public Context(SteamRice steamRice){

        this. steamRice = steamRice;

    }

    public void contextInterface(){

        steamRice.PutRice();

        steamRice.WashRice();

        steamRice.CookRice();

    }

}

 

------------------------------------------------分割线----------------------------------------------------------

上文如有错误、写得不合理以及有疑惑的地方,希望您可以在评论区提出。

在下十分感谢。

如果只是想在评论区吐吐槽、聊聊心得、卖个萌,同样也十分欢迎。

祝大家生活美好,干杯!~( ゜▽゜)つロ

 

转载请注明原作者以及附上原文章地址,谢谢。

你可能感兴趣的:(android基础-Java篇07:常用的三种设计模式:Singleton、Template、Strategy模式)