设计模式-1 概念 & 创建型模式

一、设计模式概念

1、设计模式分类(23种)

分类

成员

创建模式(5种)

提供创建对象的机制,提升已有代码的灵活性和可复用性;

常用:

1、单例;

2、工厂:(工厂方法、抽象工厂);

3、建造者;

不常用:

1、原型模式;

结构模式(7种)

如何将对象和类组装成较大的结构,并同时保持结构的灵活和高效;

常用:

1、代理;

2、桥接;

3、装饰;

4、适配器;

不常用:

1、外观;

2、组合;

3、享元;

行为模式(11种)

负责对象间的高效沟通和职责传递委派;

常用:

1、观察者;

2、模板方法;

3、策略;

4、责任链;

5、迭代器;

6、状态;

不常用:

1、访问者;

2、备忘录;

3、命令;

4、解释器;

5、中介者;

2、六大设计原则(SOLID)

名称

定义

单一职责原则

Single Responsibitiyty Principle

1、一个类(一个模块)只管一件事;

2、粒度小,功能单一;

开闭原则

Open Close Principle

1、对扩展开放,对修改封闭(是所有设计模式的最核心目标)

优点:

2、新老逻辑解耦,添加需求不会影响旧的逻辑;

3、改动成本低,不需要改原有逻辑;

4、提高代码的可扩展性和稳定性;

里氏替换原则

Liskov Substitution ​Principle

1、出现在多态中:接口中的方法可以被多个类实现,使用不同的实现类调用这个方法;

2、示例:interface = new Class();

3、实际执行的是Class里面的方法;

接口分离原则

Interface Segregation ​Principle

1、应该创建职责少的interface;

依赖倒置原则

Dependence Inversion ​Principle

1、高层模块不应该直接依赖低层模块,它们都应该直接依赖抽象;

2、高层依赖interface,低层实现interface;

迪米特法则

Least Knowledge ​Principle

1、类知道的越少越好;

2、多使用中间人;

二、创建型设计模式

创建型模式说明:创建对象的机制,提升已有代码的灵活性和复用性;

一、单例

一个类在运行的时候,只有一个实例。

使用方法:

保证一个类只有一个实例。

为这个实例提供一个全局访问点。

1、饿汉单例

package creationPattern.Singleton;

/**
 * 单例模式-饿汉式
 * 特点:
 *      1、在类加载的时候创建【静态的私有的】对象,保证创建过程是线程安全的;
 *      2、不支持延时加载,获取对象的速度快;
 *      3、但如果对象比较大,而且一直没使用,就会浪费内存;
 */
public class Singleton_01 {
    // 1.私有构造方法
    private Singleton_01() {
    }

    // 2.创建私有的静态的全局对象
    private static Singleton_01 instance = new Singleton_01();

    // 3.给外部提供全局访问点
    public static Singleton_01 getInstance() {
        return instance;
    }
}

2、懒汉单例 - 线程不安全

package creationPattern.Singleton;

/**
 * 单例模式-懒汉式
 *      1、支持延时加载,调用get方法时才会创建对象;
 *      2、线程不安全
 */
public class Singleton_02 {
    // 1.私有构造方法
    private Singleton_02() {
    }

    // 2.创建私有的静态的全局对象
    private static Singleton_02 instance;

    // 3.给外部提供全局访问点
    public static Singleton_02 getInstance() {
        if (null == instance)
            instance = new Singleton_02();
        return instance;
    }
}

3、懒汉单例 - 线程安全

package creationPattern.Singleton;

/**
 * 单例模式-懒汉式
 *      1、支持延时加载,调用get方法时才会创建对象;
 *      2、线程安全,但是因为加了锁,导致并发度降低;
 */
public class Singleton_03 {
    // 1.私有构造方法
    private Singleton_03() {
    }

    // 2.创建私有的静态的全局对象
    private static Singleton_03 instance;

    // 3.给外部提供全局访问点
    // 添加同步锁
    public static synchronized Singleton_03 getInstance() {
        if (null == instance)
            instance = new Singleton_03();
        return instance;
    }
}

4、懒汉单例 - 双重校验:代码相对复杂

package creationPattern.Singleton;

/**
 * 双重校验
 *      1、get方法里面判断两次是否为null;
 *      2、外层判断不空,就直接返回;
 *      3、外层判断空,就抢资源,抢到资源后还需要防止前面进去的线程已经创建了;
 */
public class Singleton_04 {
    // 1.私有构造方法
    private Singleton_04() {
    }

    // 2.创建私有的静态的全局对象
    // volatile 这个关键字可以保证变量的可见性,屏蔽指令重排序
    private volatile static Singleton_04 instance;

    // 3.给外部提供全局访问点
    public static Singleton_04 getInstance() {
        if (null == instance)
            synchronized (Singleton_04.class){
                // 抢到锁之后,第二次判断
                // 进入同步代码块的线程需要防止之前进来的线程创建对象,所以需要再判断一次;
                if (null == instance)
                    instance = new Singleton_04();
            }
        return instance;
    }
}

5、懒汉单例 - 静态内部类:代码简单

package creationPattern.Singleton;

/**
 * 静态内部类
 * 1、利用静态内部类的特性:外部类使用到了内部类的属性或者方法时,才会加载内部类;
 * 2、实现延时加载、线程安全、代码简单
 * 3、静态内部类里面实际上也是一个饿汉加载,只是类不被加载,它没办法创建实例;
 */
public class Singleton_05 {
    // 1.私有构造方法
    private Singleton_05() {
        if (null != SingletonHandler.instance) {
            throw new RuntimeException("非法访问构造方法");
        }
    }

    // 2.创建静态内部类
    private static class SingletonHandler {
        // 3.创建私有的静态的全局对象
        private static Singleton_05 instance = new Singleton_05();
    }

    // 4.提供外部方法
    public static Singleton_05 getInstance() {
        return SingletonHandler.instance;
    }
}

6、反射对单例的破坏

package creationPattern.Singleton;

import java.lang.reflect.Constructor;

/**
 * 反射对单例的破坏
 */
public class Test_Reflect {
    public static void main(String[] args) {
        Class<Singleton_05> clazz = Singleton_05.class;
        try {
            // 获取私有构造方法
            Constructor<Singleton_05> constructor = clazz.getDeclaredConstructor();
            constructor.setAccessible(true);
            Singleton_05 singleton05 = constructor.newInstance();

            System.out.println(singleton05);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

-- 加个判断解决

9、序列化对单例有破坏

10、系列化对单例有破坏

11、使用枚举实现的单例模式具有懒加载、线程安全、不被反射和序列化破坏的特点;

  • 7
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值