设计模式

设计原则

image-20230306212145386

模式分类

  • 创建型: 在创建对象的同时隐藏创建逻辑,不使⽤ new 直接实例化对象,程序在判断需要创建哪些对象时更灵活。包括⼯⼚/抽象⼯⼚/单例/建造者/原型模式。

  • 结构型: 通过类和接⼝间的继承和引⽤实现创建复杂结构的对象。包括适配器/桥接模式/过滤器/组合/装饰器/外观/享元/代理模式。

  • ⾏为型: 通过类之间不同通信⽅式实现不同⾏为。包括责任链/命名/解释器/迭代器/中介者/备忘录/观察者/状态/策略/模板/访问者模式。

image-20230306212410826

创建型:

  • 单例模式

    • 注意双重检查锁里面的volatile(提供可⻅性、禁⽌指令重排序)
  • 各种工厂模式(简单工厂、工厂方法、抽象工厂)

    • 简单工厂模式:根据参数不同,创建不同的类(类属于同一大类即同一接口或者父类)

      • 例子:java中的DateFormat
    • 工厂方法模式:与简单工厂相比,具体商品交给子工厂去完成,将产品实例化操作延迟到工厂子类去做。好处在于需要新增商品就新增子工厂即可。

      • 例子:Collection中的Iterator迭代器对象的生产过程
    • 抽象工厂模式:对工厂方法模式再优化,不像工厂方法只能生产一大类的产品,可以生产其他大类的产品。在父亲工厂中新增产品体系即可。(缺点违反开闭原则)

      image-20230309152331523
  • 建造者模式:以详细的步骤创建复杂对象。将构造的方法不应该放在类的构造函数里面,应该抽取出来放在专门的建造者里面,(如果过于复杂可以添加主管类,并由主管类来管理调用哪些方法。)

  • 原型模式:解决复制对象的问题,对对象进行克隆。

    • 浅克隆用java自带的clonable接口的clone方法
    • 深克隆,在clone方法里面new一个新对象

结构型:

  • 适配器:类似于充电器,使两个不兼容的东西兼容到一起,提供接口转换,与装饰者不一样的是并不是对原有接口进行修改加强。
  • 桥接模式:将继承关系转换为关联关系,从而降低类与类的耦合,减少了代码的编码量
  • 装饰者:动态地给一个对象添加一些额外的功能。就增加功能来说,装饰模式比生成子类更为灵活。
  • 代理模式:代理模式的本质是⼀个中间件,主要目的是解耦合服务提供者和使用者。使用者通过代理间接的访问服务提供者,便于后者的封装和控制。主要有静态代理,JDK继承式的动态代理,CGLIB基于接口动态代理
  • 外观模式:对现有的系统添加一个新接口,来隐藏系统的复杂性即对负责方法进行封装。
  • 享元模式:典型的比如流行的池化技术,运用共享技术有效地支持大量细粒度的对象。享元模式把共享对象分为内部状态与外部状态。内部状态为主要共享内容,外部状态即各不相同的不共享属性。

行为型:

  • 责任链:形成一个类似于链表的事务处理链。请求者不知道由谁来处理。但是请求性能会低一点。
  • 观察者:定义对象间的一种一对多依赖关系,使得每当一个对象状态发生改变时,其相关依赖对象皆得到通知并被自动更新。
  • 策略模式:定义一组算法,将每个算法都封装起来,并且使它们之间可以互换。策略模式让算法独立于使用它的客户而变化,也称为政策模式(Policy);例子如ThreadPoolExecutor,需要传入具体的策略类。
  • 模板方法:定义一个操作中的算法的框架,而将一些步骤延迟到子类中。使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤

设计模式在实际中的运用

Java

  • 单例模式:使用单例模式来实现全局唯一的对象,例如日志记录器、数据库连接池等。
  • 工厂模式:像java.util.Calendar等中的getInstance()方法。
  • 观察者模式:进行对某些事件进行监听例如:java.util.EventListener等各种Listener。
  • 策略模式:java.util.Comparator能根据不同的要求来定制排序。
  • 模板方法模式:java.util.Collections中的sort()让子类可以重写方法的⼀部分,而不是整个重写。
  • 责任链模式:javax.servlet.Filter中的doFilter()方法,会有一个过滤器链依次处理。
  • 原型模式:java.lang.Objec中的clone()方法使得类的实例能够生成自身的拷贝。
  • 建造者模式:java.lang.StringBuilder定义了⼀个新的类来构建另⼀个类的实例,以简化复杂对象的创建。
  • 代理模式:java.lang.reflect.Proxy中的代理类。
  • 装饰者模式:java.io.BufferedInputStream(InputStream)进行包装动态的给⼀个对象附加额外的功能。
  • 适配器模式:java.io.InputStreamReader(InputStream)转换流用来把⼀个接口转化成另⼀个接口。
  • 桥接模式:JDBC连接驱动。

Spring

  • 工厂设计模式:Spring 使用工厂模式通过BeanFactory 、ApplicationContext 创建 bean 对象。
  • 代理设计模式:Spring AOP 功能的实现。
  • 单例设计模式:Spring 中的 Bean 默认都是单例的。
  • 模板方法模式:Spring 中 jdbcTemplate 、hibernateTemplate 等以
    Template 结尾的对数据库操作的类,它们就使用到了模板模式。
  • 观察者模式:Spring 事件驱动模型就是观察者模式很经典的⼀个应用。
  • 适配器模式:Spring MVC 中DispatcherServlet也是用到了适配器模式适配Controller 。