Skip to content

设计模式

设计模式是在大量的实践中总结和理论化之后的代码结构、编程风格、以及解决问题的思考方式。设计模式就像经典的棋谱,不同的棋局,我们使用不同的棋谱,免去我们自己再思考和摸索


单例模式

单例(单个实例)设计模式,就是采取一定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例,并且该类只提供一个取得其对象实例的方法(在软件运行的时候,我们要保证某一个类只能有一个实例化对象)

单例模式有两种方式:饿汉式和懒汉式

  • 两者最主要的区别在于创建对象的时机不同,饿汉式是在类加载就创建了对象实例,而懒汉式是在使用时才创建对象
  • 饿汉式不存在线程安全问题,而懒汉式存在线程安全问题
  • 饿汉式存在浪费资源的可能,因为如果程序员一个对象实例都没有使用,那么饿汉式创建的对象就浪费了

饿汉式

饿汉式的单例模式,只要类一加载,就会在其内部创建对象(饿汉式方式可能创建了对象但是没有使用)

饿汉式单例设计模式具体步骤如下:

  1. 构造器私有化,防止在类的外部直接通过new方法实例化对象
  2. 类的内部创建对象(该对象是静态的)
  3. 向外暴露一个静态的公共方法,getInstance()
java
package com.jlctest.single;

public class SingleTon {
    public static void main(String[] args) {
        // 通过公共的静态方法可以获取对象(且只能是一个)
        GirlFriend instance = GirlFriend.getInstance();
        // GirlFriend.getInstance()重复执行,还是返回在类中创建的那个对象
    }
}

// 有一个类,GirlFriend   使用饿汉式的单例设计模式  软件运行过程中只能实例化一个对象
class GirlFriend {
    private String name;
    
    // 2.在类的内部创建对象,设置为静态属性,我们后续的静态方法可以访问到
    // 同时静态的方法,只会在类创建的时候初始化一次,后续不会重复初始化
    private static GirlFriend gf = new GirlFriend("小红");
    
    // 1.将构造器私有化
    private GirlFriend(String name) {
        this.name = name;
    }
    
    // 3.提供一个公共的static方法,返回gf对象
    public static GirlFriend getInstance() {
        return gf;
    }
}

懒汉式

与饿汉式的单例模式不同,懒汉式的单例模式,只有在调用暴露的静态公共方法时,才会在类的内部创建实例(防止了饿汉式的情况:可能出现创建了对象但是没有使用),在后面再次调用时,会返回上次创建的对象(因为是静态属性),从而保证单例

懒汉式单例设计模式具体步骤如下:

  1. 构造器私有化,防止在类的外部直接通过new方法实例化对象
  2. 类的内部创建对象(该对象是静态的)
  3. 向外暴露一个静态的公共方法,getInstance()
java
package com.jlctest.single;

public class SingleTon {
    public static void main(String[] args) {
        // 通过公共的静态方法可以获取对象(且只能是一个)
        GirlFriend instance = GirlFriend.getInstance();
        // GirlFriend.getInstance()重复执行,还是返回在类中创建的那个对象
    }
}

// 有一个类,GirlFriend   使用懒汉式的单例设计模式  软件运行过程中只能实例化一个对象
class GirlFriend {
    private String name;
    
    // 2.在类的内部创建对象,设置为静态属性,我们后续的静态方法可以访问到
    // 同时静态的方法,只会在类创建的时候初始化一次,后续不会重复初始化
    private static GirlFriend gf;
    
    // 1.将构造器私有化
    private GirlFriend(String name) {
        this.name = name;
    }
    
    // 3.提供一个公共的static方法,返回gf对象
    public static GirlFriend getInstance() {
        // 如果对象还没有创建,就创建一个对象
        if(gf == null) {
            gf = new GirlFriend("小红");
        }
        return gf;
    }
}

模板模式

抽象模板模式

抽象类体现的就是一种模板模式的设计,抽象类作为多个子类的通用模板,子类在抽象类的基础上进行扩展、改造,但是子类总体上会保留抽象类的行为方式

模板设计模式能解决的问题:

  • 当功能内部一部分实现是确定的,一部分实现是不确定的。这时可以把不确定的部分暴露出去,让子类去实现
  • 编写一个抽象父类,父类提供了多个子类的通用方法,并把一个或多个方法留给其子类实现,这就是一种模板模式

设计一个抽象类(Template),完成如下功能:

  1. 编写方法calculateTime(),用于计算某段代码的消耗时间
  2. 编写抽象方法job()
  3. 编写一个子类Sub,继承抽象类Template,并实现job()方法
  4. 编写一个测试类,看看是否好用
java
package com.jlctest.abstract;

// 抽象父类
abstract class Template {
    public abstract void job();  // 抽象方法
    
    // 统计耗时时间,具体的实现方法,调用了job()抽象方法
    public void calculateTime() {
        // 统计当前时间距离 1970-1-1 0:0:0的时间差,单位为ms
        long start = System.currentTimeMillis();
        job();   // 体现了动态绑定机制
        long end = System.currentTimeMillis();
        System.out.println("耗时:" + (end - start));
    }
}

子类去继承父类,实现父类中的抽象方法:

java
package com.jlctest.abstract;

public class AA extends Template {
    // 实现了父类中的抽象方法
    @Override
    public void job() {
        long num = 0;
        for(long i = 1; i <= 800000; i++) {
            num += i;
        }
    }
}

在测试文件中执行:

java
package com.jlctest.abstract;

public class Test {
    public static void main(String[] args) {
        AA a = new AA();
        a.calculateTime();
    }
}

Released under the MIT License.