单例模式与工厂模式

设计模式

单例模式

什么是单利设计模式?

保证一个类只有一个实例,并且提供一个访问该全局访问点。一个jvm中只能存在一个实例,保证对象唯一性。

单例模式应用场景

​ servlet、struts2、springmvc、连接池、线程池、spring

单例优缺点:

​ 优点:节约内存、重复利用、方便管理

​ 缺点:线程安全问题

单例创建方式(7种)

​ 饿汉式:类初始化时,会立即加载该对象,线程天生安全,调用效率高。

/**
 * @program: JAVATest
 * @author: 王新春
 * @create: 2018-10-30 21:50
 * @description:   单例模式---饿汉式
 **/

public class Singleton1 {
    //2.创建私有化唯一的对象,存在永久区,垃圾回收机制是不会回收
    private static final Singleton1 SINGLETON_1 = new Singleton1();

    //类初始化的时候,就会创建对象,天生线程安全,如果不使用对象时,会浪费内存

    //1.构造函数私有化
    private Singleton1() {
    }
    public static void main(String[] args) {
        Singleton1 singleton1 = Singleton1.getInstance();
        Singleton1 singleton2 = Singleton1.getInstance();
        System.out.println(singleton1 == singleton2);
    }
    /*
        为什么不会存在线程安全问题?
        对象唯一不会再被创建
     */
    //3.提供外部调用接口
    public static Singleton1 getInstance(){
        return SINGLETON_1;
    }
}

​ 懒汉式:类初始化时,不会初始化该对象,真正需要使用时才会创建该对象,具备懒加载功能。

/**
 * @program: JAVATest
 * @author: 王新春
 * @create: 2018-10-30 21:59
 * @description: 单例模式---懒汉式
 **/

public class Singleton2 {
    //2.创建私有化唯一的对象
    private static Singleton2 singleton2;
    //类初始化时,不会创建该对象,真正需要时才会被加载(创建),天生线程不安全,,需要解决线程安全问题,所以效率低

    //1.构造函数私有化
    private Singleton2() {
    }

    public static void main(String[] args) {
        Singleton2 singleton2 = Singleton2.getInstance();
        Singleton2 singleton1 = Singleton2.getInstance();
        System.out.println(singleton1 == singleton2);
    }

    //3.提供外部调用接口
    /*
    线程安全问题
    多个线程时,存在创建多个对象的情况
    需要解决线程安全问题
     */
    public static synchronized Singleton2 getInstance() {
        if (singleton2 == null) {
            singleton2 = new Singleton2();
        }
        return singleton2;
    }
}

​ 静态内部方式:结合了懒汉式和饿汉式的各自优点,真正需要对象的时候才会加载,加载类是线程安全的。

​ 枚举单例:使用枚举实现单例模式,优点:实现简单、调用效率高,枚举本身就是单例由jvm从根本上提供保障,避免通过反射和反序列化的漏洞,缺点:没有延迟加载功能。

/**
 * @program: JAVATest
 * @author: 王新春
 * @create: 2018-10-30 22:09
 * @description:   单例模式---枚举方式
 **/

public class Singleton3 {

    private Singleton3() {
    }

    public static Singleton3 getInstance(){
        return Singleton3Enum.INSTANCE.getInstance();
    }
    static enum Singleton3Enum{
        INSTANCE;
        private Singleton3 singleton3;
        private Singleton3Enum() {
            this.singleton3 = new Singleton3();
        }
        public Singleton3 getInstance(){
            return this.singleton3;
        }
    }
    public static void main(String[] args) {
        Singleton3 singleton3 = Singleton3.getInstance();
        Singleton3 singleton2 = Singleton3.getInstance();
        System.out.println(singleton3 == singleton2);
    }
}

​ 双重检测锁方式(因为jvm本质重排序的原因,可能会初始化多次,不推荐使用)

/**
 * @program: JAVATest
 * @author: 王新春
 * @create: 2018-10-30 22:36
 * @description:   单例模式---双重检验锁
 **/

public class Singleton4 {
    //volatile   本身禁止重排序
    private static volatile Singleton4 singleton4;

    //1.构造函数私有化
    private Singleton4() {
    }

    public static void main(String[] args) {
        Singleton4 singleton2 = Singleton4.getInstance();
        Singleton4 singleton1 = Singleton4.getInstance();
        System.out.println(singleton1 == singleton2);
    }

    //3.提供外部调用接口
    /*
    线程安全问题
    多个线程时,存在创建多个对象的情况
    需要解决线程安全问题,使用双重检验锁,可以增加安全性,但是会降低效率
     */
    public static Singleton4 getInstance() {

        if (singleton4 == null) {
            synchronized (Singleton4.class){
                if (singleton4 == null) {
                    singleton4 = new Singleton4();//存在重排序问题
                }
            }
        }
        return singleton4;
    }
}
工厂模式

什么时工厂模式?

实现了创建者和调用者分离,工厂模式分为简单工厂、工厂方法、抽象工厂模式。

简单工厂设计模式(不属于23种设计模式)

简单工厂模式是属于创建型模式,又叫做静态工厂方法(Static Factory Method)模式,但不属于23种GOF设计模式之一。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式,可以理解为是不同工厂模式的一个特殊实现。

优点:简单工厂模式能够根据外界给定的信息,决定究竟应该创建哪个具体类的对象。明确区分了各自的职责和权力,有利于整个软件体系结构的优化

缺点:很明显工厂类集中了所有实例的创建逻辑,容易违反GRASPR的高内聚的责任分配原则

举一个去4s点买汽车的例子

汽车接口

/**
 * @program: JAVATest
 * @author: 王新春
 * @create: 2018-10-31 22:30
 * @description:  总汽车类型
 **/

public interface Car {
    void run();
}

汽车子类

/**
 * @program: JAVATest
 * @author: 王新春
 * @create: 2018-10-31 22:31
 * @description: 比亚迪汽车
 **/

public class Byd implements Car {
    @Override
    public void run() {
        System.out.println("比亚迪汽车在跑。。。。");
    }
}
/**
 * @program: JAVATest
 * @author: 王新春
 * @create: 2018-10-31 22:33
 * @description:   奔驰G500
 **/

public class BCG500 implements Car {
    @Override
    public void run() {
        System.out.println("奔驰G500在跑。。。");
    }
}

工厂类

/**
 * @program: JAVATest
 * @author: 王新春
 * @create: 2018-10-31 22:34
 * @description:    工厂模式-----简单工厂
 **/

public class CarFactory {
    public static Car createCar(String name){
        if(name == null || name == ""){
            return null;
        }
        /*
            当类型过多时,不利于维护,也不利于扩展
         */
        switch (name){
            case "比亚迪":
                return new Byd();
            case "奔驰G500":
                return new BCG500();
            default:
                return null;
        }
    }
}

测试类

/**
 * @program: JAVATest
 * @author: 王新春
 * @create: 2018-10-31 22:45
 * @description:   测试类
 **/

public class TestMain {

    public static void main(String[] args) {
        Car bcg500 = CarFactory.createCar("奔驰G500");
        bcg500.run();
    }
}

输出为:奔驰G500在跑。。。


青春短暂,我在路上

你可能感兴趣的:(java)