# DesginPattern **Repository Path**: Runbin-Su/desgin-pattern ## Basic Information - **Project Name**: DesginPattern - **Description**: 记录学习设计模式 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2023-09-17 - **Last Updated**: 2023-09-27 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 第1章 设计模式七大原则 ## 1.1 设计模式目的 - **代码复用性**(即:相同功能代码,不多次编写) - **可读性**(即:编程规范性,便于其他程序员的阅读) - **可扩展性**(当需要添加新功能,非常方便) - **可靠性**(增加新功能,对原来的功能没有影响) - 使程序呈现**高内聚,低耦合**特性 ## 1.2 设计七大原则 ### (1)**单一职责原则** 定义:即**一个类只负责一项职责**。 注意事项: - **降低类的复杂度**,一个类只负责一项职责 - 提高类的**可读性**,**可维护性** - 降低变更引起的风险 - 通常情况下,我们应当遵守单一职责原则。只有逻辑足够简单,才可以在打码级违反单一职责原则;只有**类中方法数量足够少**时,可将**类级别的细粒度到方法级别**保持单一职责原则。 ### (2)**接口隔离原则** 定义:**客户端不需要的行为则隐藏起来**(**一个类对另外一个类的依赖应该建立在最小接口**) **改造前**: ![image-20230918182029961](README.assets/image-20230918182029961.png) **改造后:** ![image-20230918182152805](README.assets/image-20230918182152805.png) **传统出现问题** 类A 通过接口 Interlacel 依赖类 B,类C 通过接口Interfacel依赖类 D,如果接口Interfacel 对于类A 和类C来说不是最小接口,那么类 B 和类 D 必须去实现他们不需要的方法 **解决方案** 将接口 Interfacel 拆分为独立的几个接口,类 A 和类 C 分别与他们需要的接口建立依赖关系。也就是采用接口隔离原则 ### **(3) 依赖倒转原则** - **低层模块**尽量有**抽象类或接口**,程序稳定性更好(**细节依赖抽象**) - 变量的声明类型尽量是抽象类或接口。这样可以通过**多态**,利于程序扩展 - **面向接口编程** ### **(4)里氏替换原则** - **子类可以扩展父类的功能,但不能改变父类原有的功能。** ### **(5)开闭原则**(**扩展开放、修改关闭**) - 类,模块和函数应该对**扩展开放**(**提供方**),对**修改关闭**(**使用方**)。用**抽象**构建框架,用实现扩展细节 ### (6)**迪米特法则** - 一个类对**自己依赖的类知道的越少越好**。也就是说,对于被依赖的类不管多么复杂,都尽量将逻辑**封装**在类的内部。对外除了**提供的public 方法**,不对外泄露任何信息。 - **直接朋友**:一个类中其**成员变量**,**方法入参**,**方法返回值**关联其他类。迪米特法则即**打破非直接朋友的耦合关系** ### (7)合成复用原则 # 第2章 UML类图 ## 2.1 UML符号 ![image-20230920185158924](README.assets/image-20230920185158924.png) # 第3章 23种设计模式 ## 3.1 单例模式 ​ 在**JVM**当中保障一个类**只能存在一个对象实例**。 **1.实现方式** ​ (1)**饿汉式(静态常量)** ~~~java private final static Singleton singleton = new Singleton(); //构造器私有化 private Singleton(){}; //public 外接访问 public static Singleton getSingleton(){ return singleton; } ~~~ ​ **优点**:实现简单,类加载时完成实例化,**线程安全** ​ **缺点**:无法懒加载,若从未使用该实例。造成**内存浪费** ​ (2)**饿汉式(静态代码块)** ~~~java class Singleton{ private final static Singleton singleton; static { singleton = new Singleton(); } //构造器私有化 private Singleton(){}; //public 外接访问 public static Singleton getSingleton(){ return singleton; } } ~~~ ​ (3)**懒汉式(线程不安全)** ~~~java class Singleton{ private static Singleton singleton; //构造器私有化 private Singleton(){}; //public 外接访问 public static Singleton getSingleton(){ //先判断 当前是否已经有实例 if (singleton == null){ singleton = new Singleton(); } return singleton; } } ~~~ ​ **优点**:懒加载,**内存友好** ​ **缺点**:多线程环境下,会出现多个实例情况。**线程不安全** ​ (4)**懒汉式(线程安全)** ~~~java class Singleton{ private static Singleton singleton; //构造器私有化 private Singleton(){}; //public 外接访问 public static Singleton getSingleton(){ //先判断 当前是否已经有实例 if (singleton == null){ synchronized (Singleton.class){ singleton = new Singleton(); } } return singleton; } } ~~~ ​ **缺点**:多线程环境下,会出现多个实例情况。**线程不安全** ​ (5)懒汉式(双检锁) ~~~java class Singleton{ private volatile static Singleton singleton; //构造器私有化 private Singleton(){}; //public 外接访问 public static Singleton getSingleton(){ //先判断 当前是否已经有实例 if (singleton == null){ synchronized (Singleton.class){ if (singleton == null){ singleton = new Singleton(); } } } return singleton; } } ~~~ ​ **(6)静态内部类** ~~~java class Singleton{ //构造器私有化 private Singleton(){}; private static class demo{ private static final Singleton singleton = new Singleton(); } //public 外接访问 public static Singleton getSingleton(){ return demo.singleton; } } ~~~ ​ 优点:线程安全;不会立即加载。对内存友好 **(7)枚举** ~~~java public enum Singleton { INSTANCE; //属性 } ~~~ ​ 优点:**线程安全**;防止**反序列化重新创建对象** **2.使用场景** - 需要频繁创建和销毁对象 - 创建对象时过多或消耗资源过多 - 工具类对象 - 频繁访问数据库或文件的对象(Session) ## 3.2 工厂模式 1.什么是工厂模式 工厂模式将目的**将创建对象的具体过程屏蔽隔离**起来,从而达到更高的灵活性,工厂模式可以分为三类: - **简单工厂模式** - **工厂方法模式** - **抽象工厂模式** 2.简单工厂模式 简单工厂模式的核心是**定义一个创建对象的接口,将对象的创建和本身的业务逻辑分离**,降低系统的耦合度,使得两个修改起来相对容易些,当以后实现改变时,只需要修改工厂类即可。 ![image-20230921220551191](README.assets/image-20230921220551191.png) 优点:提供专门的**工厂类**用于创建对象,实现了**对象创建和使用的职责分离** 缺点:**不符合开闭原则**,每次添加新产品就需要修改工厂类。 3.工厂方法模式 工厂方法模式将工厂抽象化,并定义一个创建对象的接口。**每增加新产品,只需增加该产品以及对应的具体实现工厂类**,由具体工厂类决定要实例化的产品是哪个,将对象的创建与实例化**延迟到子类**,这样工厂的设计就符合“开闭原则”了,扩展时不必去修改原来的代码 ![image-20230921221249938](README.assets/image-20230921221249938.png) 缺点:每增加一个产品都需要增加一个具体产品类和实现工厂类,使得**系统中类的个数成倍增加** 4.抽象工厂模式 抽象工厂模式主要用于创建相关对象的家族。当一个产品族中需要被设计在一起工作时,通过抽象工厂模式,能够保证客户端始终只使用同一个产品族中的对象; 5.小结 (1)**工厂方法**只有**一个抽象产品类**和**一个抽象工厂类**,但可以派生出多个具体产品类和具体工厂类,每个具体工厂类只能创建一个具体产品类的实例。 (2)**抽象工厂**模式拥有**多个抽象产品类**(产品族)和**一个抽象工厂类**,每个抽象产品类可以派生出多个具体产品类;抽象工厂类也可以派生出多个具体工厂类,同时每个具体工厂类可以创建多个具体产品类的实例