设计模式

87 阅读5分钟

1、设计模式的分类

image.png

2、工厂模式

工厂模式(Factory Pattern):工厂模式是一种创建型模式,它提供了一种创建对象的最佳方式。在工厂模式中,我们创建对象而不是直接实例化对象。这样可以使代码更加灵活,易于维护和扩展。工厂模式有三种类型:简单工厂模式工厂方法模式抽象工厂模式

1.说一说简单工厂模式

简单工厂模式指由一个工厂对象来创建实例,客户端不需要关注创建逻辑,只需提供传入工厂的参数。

UML类图如下:

image.png

适用于工厂类负责创建对象较少的情况,缺点是如果要增加新产品,就需要修改工厂类的判断逻辑,违背开闭原则,且产品多的话会使工厂类比较复杂。

Calendar 抽象类的 getInstance 方法,调用 createCalendar 方法根据不同的地区参数创建不同的日历对象。

Spring中的 BeanFactory 使用简单工厂模式,根据传入一个唯一的标识来获得 Bean 对象。

2.工厂方法模式了解吗?

和简单工厂模式中工厂负责生产所有产品相比,工厂方法模式将生成具体产品的任务分发给具体的产品工厂。

UML类图如下:

image.png

也就是定义一个抽象工厂,其定义了产品的生产接囗,但不负责具体的产品,将生产任务交给不同的派生类工厂。这样不用通过指定类型来创建对象了。

3.抽象工厂模式了解吗?

简单工厂模式和工厂方法模式不管工厂怎么拆分抽象,都只是针对一类产品,如果要生成另一种产品,就比较难办了!

抽象工厂模式通过在AbstarctFactory 中增加创建产品的接口,并在具体子工厂中实现新加产品的创建,当然前提是子工厂支持生产该产品。否则继承的这个接口可以什么也不干。

UML类图如下:

image.png

从上面类图结构中可以清楚的看到如何在工厂方法模式中通过增加新产品接口来实现产品的增加的。

3、单例模式

1.什么是单例模式?单例模式的特点是什么?

单例模式(Singleton Pattern)是一种创建型模式,一个单例类在任何情况下都只存在一个实例,构造方法必须是私有的、由自己创建一个静态变量存储实例,对外提供一个静态公有方法获取实例。

优点是内存中只有一个实例,减少了开销,尤其是频繁创建和销毁实例的情况下并且可以避免对资源的多重占用。缺点是没有抽象层,难以扩展,与单一职责原则冲突。

单例模式在需要控制资源的情况下非常有用,例如数据库连接池、线程池等。单例模式有两种实现方式:懒汉式饿汉式

2.单例模式的常见写法有哪些?

1、饿汉式,线程安全

饿汉式单例模式,顾名思义,类一加载就创建对象,这种方式比较常用,但容易产生垃圾对象,浪费内存空间。

  • 优点:线程安全,没有加锁,执行效率较高
  • 缺点:不是懒加载,类加载时就初始化,浪费内存空间

懒加载(lazy loading):使用的时候再创建对象

饿汉式单例是如何保证线程安全的呢?它是基于类加载机制避免了多线程的同步问题,但是如果类被不同的类加载器加载就会创建不同的实例。

2、懒汉式,线程不安全

这种方式在单线程下使用没有问题,对于多线程是无法保证单例的,这里列出来是为了和后面使用锁保证线程安全的单例做对比。

  • 优点:懒加载
  • 缺点:线程不安全

3、懒汉式,线程安全

懒汉式单例如何保证线程安全呢?通过synchronized 关键字加锁保证线程安全,synchronized 可以添加在方法上面,也可以添加在代码块上面,这里演示添加在方法上面,存在的问题是每一次调用getlnstance 获取实例时都需要加锁和释放锁,这样是非常影响性能的。

  • 优点:懒加载,线程安全
  • 缺点:效率较低

...待续

4、适配器模式

1.适配器模式了解吗?

在我们的应用程序中我们可能需要将两个不同接口的类来进行通信,在不修改这两个的前提下我们可能会需要某个中间件来完成这个衔接的过程。这个中间件就是适配器。所谓适配器模式就是将一个类的接口,转换成客户期望的另一个接口。它可以让原本两个不兼容的接囗能够无缝完成对接。

作为中间件的适配器将目标类和适配者解耦,增加了类的透明性和可复用性。

类适配器

原理:通过类继承实现适配,继承 Target 的接口,继承 Adaptee 的实现

image.png

对象适配器

原理:通过类对象组合实现适配

image.png

  • Target:定义 Client 真正需要使用的接口。
  • Adaptee:其中定义了一个已经存在的接口,也是我们需要进行适配的接口。
  • Adapter:对Adaptee和Target的接口进行适配,保证对target中接口的调用可以间接转换为对Adaptee中接口进行调用。

2.适配器模式的优缺点

优点:

  1. 提高了类的复用;
  2. 组合若干关联对象形成对外提供统一服务的接口;
  3. 扩展性、灵活性好。

缺点:

  1. 过多使用适配模式容易造成代码功能和逻辑意义的混淆。
  2. 部分语言对继承的限制,可能至多只能适配一个适配者类,而且目标类必须是抽象类。