尚硅谷—韩顺平—图解 Java设计模式(创建型)(28~54)

本文深入讲解了Java设计模式中的创建型模式,包括单例模式的8种实现方式、简单工厂和工厂方法模式的原理与应用场景、抽象工厂模式的结构及其实现,以及原型模式和建造者模式的细节和源码分析。通过实例和代码,阐述了每种模式的优缺点及其在实际开发中的应用。
摘要由CSDN通过智能技术生成

​视频链接

设计模式 概述 & 分类(28~28)

1.:设计模式概述:

   1)掌握设计模式的层次:(5个阶段)
在这里插入图片描述
   2)设计模式介绍:(Design Pattern)
在这里插入图片描述

2.:设计模式分类:(3种类型)

   1)创建型类型(5种):
    -1:单例模式:让系统中,某个类的实例只能有一个。
    -2:抽象工厂模式:(简单工厂模式 + 工厂方法模式)
    -3:原型模式:克隆一个对象,深拷贝 / 浅拷贝。
    -4:建造者模式:
    -5:工厂模式:

   2)结构型类型(7种):
站在软件结构的角度思考的,怎么样软件结构扩展性更好。
    -1:适配器模式:
    -2:桥接模式:
    -3:装饰模式:解决类爆炸问题。
    -4:组合模式:
    -5:外观模式:
    -6:享元模式:
    -7:代理模式:

   3)行为型类型(11种):
    -1:模版方式模式:
    -2:命令模式:
    -3:访问者模式:
    -4:迭代器模式:
    -5:观察者模式:
    -6:中介者模式:
    -7:备忘录模式:
    -8:解释器模式(Interpreter 模式):
    -9:状态模式:
    -10:策略模式:
    -11:职责链模式(责任链模式):




一.:创建型—单例模式(29~38)

单例设计模式介绍:(Singleton)(8种)

   1)单例设计模式:
    -1:所谓的单例设计模式:就是采取一定的方法,保证在整个的软件系统中,对某个类,只能存在一个对象实例。并且该类,只提供一个取得其对象实例的方法。
    -2:比如:
  a、Hibernate 的 SessionFactory,它充当数据存储源的代理,并负责创建 Session 对象。
  b、一般情况下,一个项目通常只需要一个 SessionFactory 就够,这时就会使用到 单例模式。
   2)单例设计模式 分类:
    -1:饿汉式:类加载时立即创建对象,会导致对象存在时间过长。【 线程安全(static 天然的线程安全的) 】
    -2:懒汉式:延迟创建对象,用的时候才创建。【(降低内存消耗,比较好)( 但线程不安全,可手动安全)】
    -3:双重检查:可以解决线程安全问题 和 效率问题)
    -4:静态内部类:同上
    -5:枚举:

1.:饿汉式(1)(静态常量):

   1)基本步骤:
    -1:构造器私有化:防止外部 new 得到实例。
    -2:类的内部创建对象:
    -3:向外暴露一个静态的公共方法,获取实例:getInstanse()

   2)优缺点说明:
    -1:优点:
  a、这种写法比较简单,就是在 类装载的时候,就完成实例化,避免了同步问题。
    -2:缺点:
  a、在类装载的时候,就完成实例化,没有达到 Lazy Loading 的效果。
  b、如果从始至终,从未使用过这个实例,则会造成内存的浪费。
    -3:说明:
  a、这种方式,基于 classloader 机制,避免了多线程同步的问题。
  b、不过,instance 在类装载时,就实例化。在单例模式中大多数都是调用 getInstance 方法。
  c、但是导致类装载的原因有很多种,因此不能确定有其他的方式(或其他的静态方法)导致类装载。
  d、这时候,初始化 instance,就没有达到 Lazy loading 的效果。
    -4:结论:
  a、这种单例模式可用,可能会造成内存的浪费。

   3)代码实现:

/**
 * @author zhangxudong@chunyu.me
 * @date 2022/3/3 10:48 上午
 */
public class Type1 {
   

    public static void main(String[] args) {
   
        Singleton1 instance1 = Singleton1.getInstance1();
        Singleton1 instance2 = Singleton1.getInstance1();
        // true
        System.out.println(instance1 == instance2);
    }
}

class Singleton1 {
   

    //1、构造方法私有化,外部能 new
    private Singleton1() {
    }

    //2、本类内部,创建对象实例
    private static final Singleton1 singleton = new Singleton1();

    //3、提供一个公有的静态方法,返回实例对象
    public static Singleton1 getInstance1() {
   
        return singleton;
    }
}

2.:饿汉式(2)(静态代码块):.

   1)说明:
    -1:这种方式,和【静态常量实现饿汉式】其实类似:
  a、只不过将类实例化的过程,放在了静态代码块中。
  b、也是在类装载的时候,就执行静态代码块中的代码,初始化类的实例。
    -2:优缺点和上面一样的:
    -3:结论:这种单例模式可用,但是可能造成内存浪费。

   2)代码实现:

/**
 * @author zhangxudong@chunyu.me
 * @date 2022/3/3 11:07 上午
 */
class Singleton2 {
   

    // 1、构造起私有化
    private Singleton2() {
    }

    // 2、
    private static final Singleton2 singleton;

    // 3、在静态代码块中,创建单例对象
    static {
   
        singleton = new Singleton2();
    }

    public static Singleton2 getInstance() {
   
        return singleton;
    }

}

3.:懒汉式(1)(线程不安全):

   1)说明:
    -1:提供一个静态共有方法,当使用到该方法时,才去创建实例对象。
    -2:优点:
  a、起到了 Lazy loading 的效果,但是 只能在单线程情况下使用。
    -3:缺点:
  a、如果在多线程下,多个线程同时进入了 if(singleton == null)判断,这时会创建多个实例。
  b、所以:在多线程环境下,不可以使用这种方式。
    -4:结论:在实际开发中,不要使用这种方式。

   2)代码实现:

/**
 * @author zhangxudong@chunyu.me
 * @date 2022/3/3 11:21 上午
 */
public class Type3 {
   
    public static void main(String[] args) {
   
        Singleton3 instance1 = Singleton3.getInstance();
        Singleton3 instance2 = Singleton3.getInstance();
        System.out.println(instance1 == instance2); // true
    }
}

class Singleton3 {
   

    private Singleton3() {
    }

    private static Singleton3 singleton3;

    // 提供一个静态共有方法,当使用到该方法时,才去创建实例对象。
    public static Singleton3 getInstance() {
   
        if (singleton3 != null) {
   
            singleton3 = new Singleton3();
        }
        return singleton3;
    }
}

4.:懒汉式(2)(线程安全,方法同步):

   1)说明:
    -1:优点:
  a、解决了线程不安全问题。
    -2:缺点:
  a、效率太低了,每个线程在想获得类的实例的时候,执行 getInstance() 方法,都要进行同步。方法进行同步效率太低。
  b、而其实,这个方法只执行一次实例化代码就够了,后面想要获得该类实例,直接 return 就行了。
    -3:结论:在实际开发中,不推荐使用这种方式。

   2)代码:

/**
 * @author zhangxudong@chunyu.me
 * @date 2022/3/3 11:34 上午
 */
class Singleton4 {
   

    private Singleton4() {
    }

    private static Singleton4 singleton4;

    // 提供了一个静态共有方法
    // 加入了 同步处理 代码,解决了线程安全问题
    public static synchronized Singleton4 getInstance() {
   
        if (singleton4 == null) {
   
            singleton4 = new Singleton4();
        }
        return singleton4;
    }
}

5.:懒汉式(3)(线程安全,同步带代码块):

   1)说明:
    -1:这种方式:本意是对第四种方式的改进,因为前面同步方法效率太低。
    -2:但是,这种同步,并不能起到线程同步的作用:
  a、跟第三种实现方式,遇到的情形一致,
  b、如果在多线程下,多个线程同时进入了 if(singleton == null)判断,这时会创建多个实例。
    -3:结论:在实际开发中,不能使用。

   2)代码实现:

/**
 * @author zhangxudong@chunyu.me
 * @date 2022/3/3 11:47 上午
 */
class Singleton5 {
   

    private Singleton5() {
   
    }

    private static Singleton5 singleton5;

    public static Singleton5 getInstance() {
   
        if (singleton5 == null) {
   
            synchronized (Type5.class) {
   
                singleton5 = new Singleton5();
            }
        }
        return singleton5;
    }
}

6.:双重检查:(推荐使用)

   1)说明:
    -1:Double-check 概念:是多线程开发中常用到的。
  a、如代码中所示:我们进行了两次 if(singleton == null )检查,这样可以保证线程安全了。
  b、双重检查模式,进行了两次的判断,第一次是为了避免不要的实例,第二次是为了进行同步,避免多线程问题。
  c、由于 singleton=new Singleton() 对象的创建在 JVM 中可能会进行重排序,在多线程 访问下存在风险,使用 volatile 修饰 singleton 实例变量,可以有效解决该问题。
    -2:可以保证 实例化代码只执行一次,避免了多次创建对象。同时避免了反复进行方法同步,效率较高。
    -3:优点:
  线程安全,延迟初始化。这种方式采用双锁机制,安全且在多线 程情况下能保持高性能。
    -4:结论:在实际开发中,推荐使用这种单例设计模式。

   2)代码实现:

/**
 * @author zhangxudong@chunyu.me
 * @date 2022/3/3 11:47 上午
 */
class Singleton5 {
   

    private Singleton5() {
    }

    // 用 volatile 关键字修饰
    // 可以理解为:如果有修改,会立刻更新到储存。(一定程度上可以达到同步效果)
    private static
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值