设计模式-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、使用枚举实现的单例模式具有懒加载、线程安全、不被反射和序列化破坏的特点;

