设计模式
设计模式
常用设计模式
单例模式
核心:确保⼀个类只有⼀个实例,并提供⼀个全局访问点来访问该实例。

优点:可以避免⼀个全局使⽤的类频繁的创建与销毁,耗费系统资源。

关键概念
- ⼀个私有构造函数
- ⼀个私有静态变量
- ⼀个公有静态函数
单例模式的6种实现
懒汉式(线程不安全)
public class Singleton {
// 类加载时就创建实例
private static final Singleton instance = new Singleton();
// 私有构造函数
private Singleton() {}
// 公共静态⽅法,返回实例
public static Singleton getInstance() {
return instance;
}
}
说明: 先不创建实例,当第⼀次被调⽤时,再创建实例,所以被称为懒汉式
优点: 延迟了实例化,如果不需要使⽤该类,就不会被实例化,只有在需要时才创建实例,避免了资源浪费
缺点: 线程不安全,多线程环境下,如果多个线程同时进⼊了 if (uniqueInstance == null) ,若此时还未实例化,也就是 uniqueInstance == null,那么就会有多个线程执⾏ uniqueInstance = new Singleton(); ,就会实例化多个实例
饿汉式(线程安全)
public class Singleton {
// 类加载时就创建实例
private static final Singleton instance = new Singleton();
// 私有构造函数
private Singleton() {}
// 公共静态⽅法,返回实例
public static Singleton getInstance() {
return instance;
}
}
说明: 先不管需不需要使⽤这个实例,直接先实例化好实例,然后当需要使⽤的时候, 直接调⽅法就可以使⽤了
优点: 提起实例化好了⼀个实例,避免了线程不安全问题的出现
缺点: 直接实例化了实例,不再延迟实例化;若系统没有使⽤这个实例,或者系统运⾏很久之后才需要使⽤这个实例,都 会使操作系统的资源浪费
懒汉式(线程安全)
public class Singleton {
private static Singleton uniqueInstance;
private static singleton() {}
private static synchronized Sing leton getUinqueInstance() {
if (uniqueInstance == null) {
uniqueInstance = new Singleton();
}
return uniqueInstance;
}
}
说明:
优点:
缺点:
双重检查锁实现(线程安全)
public class Singleton {
private volatile static Singleton uniqueInstance;
private Singleton() {}
// 使⽤双重检查锁定保证线程安全
public static Singleton getUniqueInstance() {
if (uniqueInstance == null) {
synchronized (Singleton.class) {
if (uniqueInstance == null) {
uniqueInstance = new Singleton();
}
}
}
return uniqueInstance;
}
}
说明:
优点:
缺点:
静态内部类实现(线程安全)
public class Singleton {
private Singleton() {}
// 静态内部类持有实例
private static class SingletonHolder {
private static final Singleton instance = new Singleton();
}
// 公共静态⽅法,返回实例
public static Singleton getInstance() {
return SingletonHolder.instance;
}
}
说明:
优点:
缺点:
枚举类实现(线程安全)
public enum Singleton {
INSTANCE;
// 可以添加其他⽅法和属性
public void doSomething() {
// 实现
}
}
说明:
优点:
缺点:
应用场景
-
资源共享:当多个模块或系统需要共享某⼀资源时,可以使⽤单例模式确保该资源只被创建⼀次,避免重复创 建和浪费资源。
-
控制资源访问:单例模式可以⽤于控制对特定资源的访问,例如数据库连接池、线程池等。
-
配置管理器:当整个应⽤程序需要共享⼀些配置信息时,可以使⽤单例模式将配置信息存储在单例类中,⽅便 全局访问和管理。
-
⽇志记录器:单例模式可以⽤于创建⼀个全局的⽇志记录器,⽤于记录系统中的⽇志信息。
-
线程池:在多线程环境下,使⽤单例模式管理线程池,确保线程池只被创建⼀次,提⾼线程池的利⽤率。
-
缓存:单例模式可以⽤于实现缓存系统,确保缓存只有⼀个实例,避免数据不⼀致性和内存浪费。
使⽤场景总结:
(1)频繁实例化然后⼜销毁的对象,使⽤单例模式可以提⾼性能
(2)经常使⽤的对象,但实例化时耗费时间或者资源多,如数据库连接池,使⽤单例模式,可以提⾼性能,降低资源损坏
(3)使⽤线程池之类的控制资源时,使⽤单例模式,可以⽅便资源之间的通信
工厂模式
核心:在创建对象时,不会对客户端暴露对象的创建逻辑,⽽是通过使⽤共同的接⼝来创建对象。其⽤来封装和管理类的创建,本质是对获取对象过程的抽象。
优点
- 解耦:将对象的创建和使⽤进⾏分离,客户端代码与具体产品类的实例化过程解耦,客户端只需要知道⼯⼚的 接⼝和抽象产品的接⼝,⽽不需要关⼼具体的实现类。
- 可复⽤:对于创建过程⽐较复杂且在很多地⽅都使⽤到的对象,通过⼯⼚模式可以提⾼对象创建的代码的复⽤性。
- 易于扩展:添加新的产品类时,只需要扩展相应的具体产品和具体⼯⼚,⽽不需要修改已有的代码,符合开闭原则。
- 更符合⾯向对象的设计原则:通过⼯⼚模式,将对象的创建封装在⼯⼚类中,使得系统更符合单⼀职责原则。
工程模式分类
简单工厂
工厂方法
抽象工厂
应用场景
- 当⼀个类不知道它所需要的类的时候。
- 当⼀个类希望通过其⼦类来指定创建对象的时候。
- 当类将创建对象的职责委托给多个帮助⼦类中的某⼀个,并且希望将哪⼀个帮助⼦类是代理者的信息局部化时。
代理模式
核心:在访问某个对象时引⼊⼀种代理对象,通过代理对象控制对原始对象的访问。
主要角色
- 抽象主题( Subject ): 定义了代理对象和真实对象的共同接⼝,使得代理对象能够替代真实对象
- 真实主题 Real Subject : 是实际执⾏业务逻辑的对象,是代理模式中的被代理对象
- 代理 Proxy : 包含⼀个指向真实主题的引⽤,提供与真实主题相同的接⼝,可以控制对真实主题的访问,并在 需要时负责创建或删除真实主题的实例

观察者模式
核心:定义了⼀种⼀对多的依赖关系,让多个观察者对象同时监听某⼀个主题对象。这个主题 对象在状态变化时,会通知所有的观察者对象,使他们能够⾃动更新⾃⼰。
优点:解除耦合,让耦合的双⽅都依赖于抽象,从⽽使得各⾃的变换都不会影响另⼀边的变换
装饰器模式
适配器模式
设计原则
-
单一权责
在设计类的时候要尽量缩⼩粒度,使功能明确、单⼀,不要做多余的事情(⾼内聚,低耦合)
-
开闭原则
软件实体(类、模块、函数等)应该对扩展开放,对修改关闭。这意味着可以通过扩展来添加新功能,⽽不必修改现有代码
-
里氏替代
⼦类型必须能够替换掉它们的基类型。在程序中,如果有⼀个基类和⼀个⼦类,那么可以⽤⼦类对象替换基类对 象,⽽程序的⾏为仍然是正确的
-
接口隔离
不应该强迫⼀个类实现它不需要的接⼝。⼀个类不应该对它⽤不到的⽅法负责
-
依赖倒置
⾼层模块不应该依赖于低层模块,⽽是应该依赖于抽象。抽象不应该依赖于具体实现,具体实现应该依赖于抽象
-
组合优于继承
继承耦合度⾼,组合耦合度低
继承基类是固定好的,但是组合通过组合类的指针,可以传⼊不同的类,避免⾼耦合
-
组合复用原则
优先使⽤组合 contains a(聚合 has a),⽽不是继承 is a 来达到⽬的
-
迪米特原则
⼀个对象应当对其他对象有尽可能少的了解,即不和陌⽣⼈说话

浙公网安备 33010602011771号