各种设计模式的优缺点

简单工厂模式

简单工厂模式就是让一个工厂类承担构建所有对象的职责。调用者需要什么产品,让工厂生产出来即可。

优点:将构建过程封装的好处不仅可以降低耦合,如果某个产品构造方法相当复杂,使用工厂模式可以大大减少代码重复。

缺点:一是如果需要生产的产品过多,此模式会导致工厂类过于庞大,承担过多的职责,变成超级类;

​ 二是当生成新产品时,必须在工厂类中添加新的分支。这违背了开闭原则

工厂方法模式

工厂方法模式就是将简单工厂的各个职责拆分成专业职责的工厂类

优点:工厂方法模式就是为了解决简单共厂模式的弊端诞生的。当生产的产品种类越来越多时,工厂类不会变成超级类(各个工厂的运行过程都可单独修改);当需要生产新的产品时,无需更改既有的工厂,只需要添加新的工厂即可。保持了面向对象的可扩展性,符合开闭原则。

缺点:相比起简单工厂来说,工厂方法用户的操作类便多了,增加了用户端的代码量,但相比起其改进程度来说,这点问题还是能接受的

抽象工厂模式

抽象工厂模式时工厂方法模式的进一步改进,提取出其工厂接口

优点:由于客户只调用抽象工厂中的方法(每个具体工厂都实现其方法,但在客户端的调用代码是一样的),这就使得替换工厂变得非常容易。也很好的继承了工厂方法模式的优点,很好的发挥了开闭原则、依赖倒置原则。

缺点:抽象工厂模式太重了,如果抽象接口需要添加新功能,则会影响到所有的具体工厂类。所有工厂模式适合同类工厂这样的横向扩展需求,不适合增添新功能这样的纵向扩展。

单例模式

单例模式是在创建类时使该类能自行创建它的实例(在类中提供初始化功能)。

单例模式有两种,分为懒汉模式和饿汉模式,懒汉模式是在类中提供一个初始化的函数(类如果没被初始化将其初始化,如果类被初始化了就结束调用),在需要的地方调用这个初始化函数;饿汉模式是在创建类的变量时就声明,然后给出一个声明函数返回该变量。其具体过程及各种优缺点参照我博客()。

建造者模式

建造者模式又叫生成器模式,将一个复杂对象的构建与他的表示分离,使得同样的构建过程可以创建不同的表示

具体实现

指挥者(Director)直接和客户(Client)进行需求沟通;

沟通后指挥者将客户创建产品的需求划分为各个部件的建造请求(Builder);

将各个部件的建造请求委派到具体的建造者(ConcreteBuilder);

各个具体建造者负责进行产品部件的构建;

最终构建成具体产品(Product)。

优点

1.使用建造者模式可以使客户端不必知道产品内部组成的细节。

2.具体的建造者类之间是相互独立的,这有利于系统的扩展。

3.具体的建造者相互独立,因此可以对建造的过程逐步细化,而不会对其他模块产生任何影响。

缺点

1.建造者模式所创建的产品一般具有较多的共同点,其组成部分相似;如果产品之间的差异性很大,则不适合使用建造者模式,因此其使用范围受到一定的限制。

2.如果产品的内部变化复杂,可能会导致需要定义很多具体建造者类来实现这种变化,导致系统变得很庞大。

原型模式

原型模式,用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象。其实就是从一个对象再创建另外一个可定制的对象,而且不需要知道任何创建细节。

优点:

使用原型模式创建对象比直接new一个对象在性能上要好的多,因为Object类的clone方法是一个本地方法, 它直接操作内存中的二进制流,特别是复制大对象时,性能的差别非常明显。

使用原型模式的另一个好处是简化对象的创建,使得创建对象就像我们在编辑文档时的复制粘贴一样简单。

适配器模式

将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不相容而不能工作的那些类可以一起工作。

优点:

复用了现存的类,解决了现存类和复用环境要求不一致的问题。

一个对象适配器可以把多个不同的适配者类适配到同一个目标,也就是说,同一个适配器可以把适配者类和它的子类都适配到目标接口。

缺点:

对于对象适配器来说,更换适配器的实现过程比较复杂。

桥接模式

将抽象部分与它的现实部分分离,使它们都可以独立地变化(实现系统可能有多角度分类,每一种分类都有可能变化,那么就把这种多角度分离出来让它们独立变化,减少它们之间的耦合)

桥接模式的使用场景:
1、当一个对象有多个变化因素的时候,通过抽象这些变化因素,将依赖具体实现,修改为依赖抽象。
2、当某个变化因素在多个对象中共享时。我们可以抽象出这个变化因素,然后实现这些不同的变化因素。
3、当我们期望一个对象的多个变化因素可以动态的变化,而且不影响客户的程序的使用时。

组合模式

将对象组合成树形结构以表示‘部分-整体’的层次结构。组合模式对单个用户对象和组合对象具有使用一致性。

缺点:客户端需要花更多时间理清类之间的层次关系

优点:无需关系处理的单个对象,还是组合的对象容器,实现容器之间的解耦合。当有新部件时容易添加进来。

何时用组合模式:

需求中体现部分与整体层次的结构时,以及你希望用户可以忽略组合对象与单个对象的不同,统一的使用组合结构中的所有对象时。

中介者模式

用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显示地相互引用,从而使其松耦合,而且可以独立地改变它们之间的交互。

优点:

将多对多的通信转化成多对一的通信,降低了系统的复杂性;Mediator还活得系统解耦的特性;将控制集中

缺点:

由于控制的集中化,于是把交互复杂性变为了中介者的复杂性,这就使得中介者会变得比任何一个ConcreteColleague都复杂

备忘录模式

在不破坏封装的前提下捕获一个对象的内部状态,并在该对象之外保持这个状态。这样一会就可以将该对象恢复到原先保存的状态。

使用备忘录模式的好处:
1)有时一些发起人对象的内部信息必须保存在发起人对象以外的地方,但是必须要由发起人对象自己读取,这时使用备忘录模式可以把复杂的发起人内部信息对其他的对象屏蔽起来,从而可以恰当地保持封装的边界。
2)本模式简化了发起人类。发起人不再需要管理和保存其内部状态的一个个版本,客户端可以自行管理他们所需要的这些状态的版本。
3)当发起人角色的状态改变的时候,有可能这个状态无效,这时候就可以使用暂时存储起来的备忘录将状态复原。

使用备忘录模式的缺点:
1)如果发起人角色的状态需要完整地存储到备忘录对象中,那么在资源消耗上面备忘录对象会很昂贵。
2)当负责人角色将一个备忘录存储起来的时候,负责人可能并不知道这个状态会占用多大的存储空间,从而无法提醒用户一个操作是否很昂贵。

状态模式

当一个对象的内在状态改变时允许其改变其行为,这个对象看起来像是改变了其类。

优点:

将特定的状态相关的行为都放入一个对象中,由于所有与状态相关的代码都存在某个ConcreteState中,所以通过定义新的子类很容易增加新的状态和转换

策略模式

它定义了算法家族,分别封装起来,让他们之间可以相互替换,次模式让算法的变化不会影响到使用算法的客户

优点:

策略模式非常完美的符合了“开闭原则”,用户可以在不修改原有系统的基础上选择算法或行为,也可以灵活地增加新的算法或行为。

缺点:

虽然策略模式定义了算法,但是它并不提供算法的选择,即什么算法对于什么问题最合适这是策略模式所不关心的,所以对于策略的选择还是要客户端来做。客户必须要清楚的知道每个算法之间的区别和在什么时候什么地方使用什么策略是最合适的,这样就增加客户端的负担。

模板方法

定义一个算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。

优点:

通过把不变行为搬移到超类,去除子类中的重复代码来体现它的优势,提供了一个很好的代码复用的平台

访问者模式

作用于某对象结构中的各元素的操作,它使我们可以在不改变各元素的类的前提下定义作用于这些元素的新操作。

优点:

把数据结构和作用于结构上的操作脱耦合,使得操作集合可以相对自由的演化

缺点:

使得增加新的数据结构比较困难

(适用于数据结构相对稳定的系统)

猜你喜欢

转载自blog.csdn.net/weixin_43244265/article/details/108569105