设计模式

设计模式

常用设计模式

单例模式

核心:确保⼀个类只有⼀个实例,并提供⼀个全局访问点来访问该实例。

image-20241027090742069

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

image-20241027091051396

关键概念

  • ⼀个私有构造函数
  • ⼀个私有静态变量
  • ⼀个公有静态函数

单例模式的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 : 包含⼀个指向真实主题的引⽤,提供与真实主题相同的接⼝,可以控制对真实主题的访问,并在 需要时负责创建或删除真实主题的实例

image-20241027093134453

观察者模式

核心:定义了⼀种⼀对多的依赖关系,让多个观察者对象同时监听某⼀个主题对象。这个主题 对象在状态变化时,会通知所有的观察者对象,使他们能够⾃动更新⾃⼰。

优点:解除耦合,让耦合的双⽅都依赖于抽象,从⽽使得各⾃的变换都不会影响另⼀边的变换

装饰器模式

适配器模式

设计原则

  • 单一权责

    在设计类的时候要尽量缩⼩粒度,使功能明确、单⼀,不要做多余的事情(⾼内聚,低耦合)

  • 开闭原则

    软件实体(类、模块、函数等)应该对扩展开放,对修改关闭。这意味着可以通过扩展来添加新功能,⽽不必修改现有代码

  • 里氏替代

    ⼦类型必须能够替换掉它们的基类型。在程序中,如果有⼀个基类和⼀个⼦类,那么可以⽤⼦类对象替换基类对 象,⽽程序的⾏为仍然是正确的

  • 接口隔离

    不应该强迫⼀个类实现它不需要的接⼝。⼀个类不应该对它⽤不到的⽅法负责

  • 依赖倒置

    ⾼层模块不应该依赖于低层模块,⽽是应该依赖于抽象。抽象不应该依赖于具体实现,具体实现应该依赖于抽象

  • 组合优于继承

    继承耦合度⾼,组合耦合度低

    继承基类是固定好的,但是组合通过组合类的指针,可以传⼊不同的类,避免⾼耦合

  • 组合复用原则

    优先使⽤组合 contains a(聚合 has a),⽽不是继承 is a 来达到⽬的

  • 迪米特原则

    ⼀个对象应当对其他对象有尽可能少的了解,即不和陌⽣⼈说话

posted @ 2024-10-26 22:32  MuxLz  阅读(46)  评论(0)    收藏  举报