单例模式和模板方法设计模式

什么是模式?

模式就是别人写出来的一套解决问题的方式。

单例模式:

 什么是单例模式:   

     单例模式就是在程序的运行过程中只有一个实例的存在。

单例模式是为了解决什么问题存在的:

        在程序中多次使用同一个对象且作用相同时,为了防止频繁地创建对象使得内存飙升,单例模式可以让程序仅在内存中创建一个对象,让所有需要调用的地方都共享这一单例对象。

单例模式分为两类:

1,饿汉式:在类加载时已经创建好该对象,在程序调用时直接返回该单例对象即可,即我们在编码时就已经指明了要马上创建这个对象,不需要等到被调用时再去创

        饿汉式优点:线程安全,

        饿汉式缺点:但是耗费内存(如果这个对象我们并不需要,在类加载的时候依旧会存储到内存当中)        

        

2,懒汉式:懒汉式创建对象的方法是在程序使用对象前,先判断该对象是否已经实例化(判空),若已实例化直接返回该类对象。,否则则先执行实例化操作。

        懒汉式优点:能够更好的服务,不会占用内存空间

        懒汉式缺点:线程不安全。

单例模式的步骤:

饿汉式:

1,构造器私有化。(让外部不能直接创建对象)

2,在本类中创建成员变量,指向本类对象。

3,创造一个public方法,return(返回)本类对象。(注意要设置成静态的方法,因为不能new对象,只能通过类名调用。)

4,把本类中创建的对象的变量改为静态的。(静态方法只能访问静态的变量)

        

懒汉式:

1,构造器私有化。(让外部不能直接创建对象)

2,创建一个本类类型的变量,但是不赋值。

3,创造一个public方法,在方法中给本类类型变量赋值。(注意要设置成静态的方法,因为不能new对象,只能通过类名调用。)

4,需要在方法中判断该对象是否已经创建。

饿汉式

package singleton;

//饿汉式单例模式
public class Singleton01 {

    //构造器私有化
    private Singleton01(){
    }

    //在本类中创建一个对象
    public  static Singleton01 s= new Singleton01();

    //提供一个public方法获取该对象。
    public static Singleton01 getSingletonTest01(){
        return s;
    }
}

懒汉式:

package singleton;

//懒汉式单例模式,但是线程不安全。
public class Singleton02 {
    private Singleton02(){}

    private static Singleton02 s=null;

    public static Singleton02 getSingleton02(){
         if(s==null) {
             s = new Singleton02();
         }
         return s;
    }
}

解决饿汉式的线程不安全问题

如果是以下代码会出现创建多次对象的问题,不满足单例的要求。

同时开启100个线程,总会有线程在没有赋值之前进来并同时new对象。

package singleton;

public class Test02 {
    public static void main(String[] args) {

    for (int i=0;i<100;i++) {
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                Singleton02 s = Singleton02.getSingleton02();
                System.out.println(s);
            }
        });
        t1.start();
    }
  }
}

添加synchronized 来实现线程安全(加锁),但是在方法上加锁,会降低效率。

package singleton;

//懒汉式单例模式,但是线程不安全。
public class Singleton02 {
    private Singleton02(){}

    private static Singleton02 s=null;

    public synchronized static Singleton02 getSingleton02(){
         if(s==null) {
             s = new Singleton02();
         }
         return s;
    }
}

效率更高,如果不是null直接没有影响了。

注意:里面要重新判断一下,要不然无法解决线程不安全的问题。

package singleton;

//懒汉式单例模式,但是线程不安全。
public class Singleton02 {
    private Singleton02(){}

    private static Singleton02 s=null;

    public static Singleton02 getSingleton02(){
         if(s==null) {
             synchronized(Singleton02.class){
                if (s==null) {
                    s = new Singleton02();
                }
             }
         }
         return s;
    }
}

模板方法设计模式:

什么是模板方法设计模式?

  • 在模板类的模板方法当中定义核心算法骨架,具体的实现步骤可以延迟到子类当中完成。

  • 模板类通常是一个抽象类,模板类当中的模板方法定义核心算法,这个方法通常是 final的(不是必须的)

  • 模板类当中的抽象方法就是不确定实现的方法,这个不确定怎么实现的事情交给子类去做

没有使用模板方法设计模式

package com.template1;


/**
 * 存在的问题:
 *  1,算法没有得到重复使用
 *  2,代码没有得到复用
 */
public class Student {

    /**
     * 这个方法描述的是学生的一天
     */
    public void day(){
        //和teacher算法相同
        this.qiChuang();//this可以省略
        xiShu();
        chiZanCan();
        doSome();
        chiWanFan();
        suiJiao();
    }


    public void qiChuang(){
        System.out.println("起床");
    }

    public  void xiShu(){
        System.out.println("洗漱");
    }

    public void chiZanCan(){
        System.out.println("吃早餐");
    }

    public void doSome(){
        System.out.println("学生上学去学习");
    }

    public void chiWanFan(){
        System.out.println("吃晚饭");
    }

    public void suiJiao(){
        System.out.println("睡觉休息");
    }
}
package com.template1;

public class Teacher {

    /**
     * 这个方法描述的是老师的一天
     */
    public void day(){
        //和student算法相同
        this.qiChuang();//this可以省略
        xiShu();
        chiZanCan();
        doSome();
        chiWanFan();
        suiJiao();
    }


    public void qiChuang(){
        System.out.println("起床");
    }

    public  void xiShu(){
        System.out.println("洗漱");
    }

    public void chiZanCan(){
        System.out.println("吃早餐");
    }

    public void doSome(){
        System.out.println("老师去学校教学生知识");
    }

    public void chiWanFan(){
        System.out.println("吃晚饭");
    }

    public void suiJiao(){
        System.out.println("睡觉休息");
    }
}

使用模板方法设计模式

package com.template2;

/**
 * Teacher和Student都是Person
 *
 * 1,Person就是模板方法设计模式当中的模板类
 * 2,day()方法就是模板方法设计模式当中的模板方法。
 *
 */
public abstract class Person {//模板类通常是抽象类

    //模板方法
    //添加了final 之后,这个方法无法被覆盖,这样核心的算法也可以得到保护(final不是必须的)
    //模板方法定义核心的算法骨架,具体地实现步骤可以延迟到子类当中去实现。
    //核心算发一方面是得到了保护,不能被改变。另一方面就是算法得到了重复使用
    //另外代码也得到了复用,因为算法中某些步骤的代码是固定的。这些固定的代码不会随着子类的变化而变化,这一部分代码可以写到模板类中
    public final void day(){
        this.qiChuang();//this可以省略
        xiShu();
        chiZanCan();
        doSome();
        chiWanFan();
        suiJiao();
    }

    //其中的某些步骤不会随着子类的变化而变化
    public void qiChuang(){
        System.out.println("起床");
    }

    public  void xiShu(){
        System.out.println("洗漱");
    }

    public void chiZanCan(){
        System.out.println("吃早餐");
    }


    public abstract void doSome();

    public void chiWanFan(){
        System.out.println("吃晚饭");
    }

    public void suiJiao(){
        System.out.println("睡觉休息");
    }
}
package com.template2;


public class Student extends Person {


    @Override
    public void doSome() {
        System.out.println("学生去学校学习");
    }
}
package com.template2;

public class Teacher extends Person{

    @Override
    public void doSome() {
        System.out.println("老师去学校教学生知识");
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值