设计模式的理解与举例

设计模式详解与应用实例
设计模式是软件开发中解决问题的通用解决方案,分为创建型、结构型和行为型模式。它们提供代码重用、理解性和可靠性。文章介绍了单例模式、工厂模式(包括简单工厂、工厂方法和抽象工厂)、策略模式、代理模式、中介者模式、装饰者模式和观察者模式等,并通过实际示例阐述了每种模式的应用。设计模式有助于减少代码中的if条件语句,实现代码的开放-封闭原则,提高代码复用和可扩展性。

设计模式介绍

设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案。这些解决方案是众多软件开发人员经过相当长的一段时间的试验和错误总结出来的

  • 设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结。
为什么要有设计模式?好处是什么?
  • 为了重用代码、让代码更容易被他人理解、保证代码可靠性(设计模式提供了一个标准的术语系统,且具体到特定的情景)。
  • 合理地运用设计模式可以完美地解决很多问题,每种模式在现实中都有相应的原理来与之对应,每种模式都描述了一个在我们周围不断重复发生的问题,以及该问题的核心解决方案
设计模式分类

根据设计模式的参考书 Design Patterns - Elements of Reusable Object-Oriented Software(中文译名:设计模式 - 可复用的面向对象软件元素) 中所提到的,总共有 23 种设计模式。

  • 设计模式可以分为三大类:
    • 创建型模式(Creational Patterns)
    • 结构型模式(Structural Patterns)
    • 行为型模式(Behavioral Patterns)
    • 另一类设计模式:J2EE 设计模式
创建型模式

这些设计模式提供了一种在创建对象的同时隐藏创建逻辑的方式,而不是使用 new 运算符直接实例化对象。这使得程序在判断针对某个给定实例需要创建哪些对象时更加灵活。

  • 工厂模式(Factory Pattern)
  • 抽象工厂模式(Abstract Factory Pattern)
  • 单例模式(Singleton Pattern)
  • 建造者模式(Builder Pattern)
  • 原型模式(Prototype Pattern)
结构型模式

这些设计模式关注类和对象的组合。继承的概念被用来组合接口和定义组合对象获得新功能的方式。

  • 适配器模式(Adapter Pattern)
  • 桥接模式(Bridge Pattern)
  • 过滤器模式(Filter、Criteria Pattern)
  • 组合模式(Composite Pattern)
  • 装饰器模式(Decorator Pattern)
  • 外观模式(Facade Pattern)
  • 享元模式(Flyweight Pattern)
  • 代理模式(Proxy Pattern)
行为型模式

这些设计模式特别关注对象之间的通信。

  • 责任链模式(Chain of Responsibility Pattern)
  • 命令模式(Command Pattern)
  • 解释器模式(Interpreter Pattern)
  • 迭代器模式(Iterator Pattern)
  • 中介者模式(Mediator Pattern)
  • 备忘录模式(Memento Pattern)
  • 观察者模式(Observer Pattern)
  • 状态模式(State Pattern)
  • 空对象模式(Null Object Pattern)
  • 策略模式(Strategy Pattern)
  • 模板模式(Template Pattern)
  • 访问者模式(Visitor Pattern)
J2EE 模式

这些设计模式特别关注表示层。这些模式是由 Sun Java Center 鉴定的。

  • MVC 模式(MVC Pattern)
  • 业务代表模式(Business Delegate Pattern)
  • 组合实体模式(Composite Entity Pattern)
  • 数据访问对象模式(Data Access Object Pattern)
  • 前端控制器模式(Front Controller Pattern)
  • 拦截过滤器模式(Intercepting Filter Pattern)
  • 服务定位器模式(Service Locator Pattern)
  • 传输对象模式(Transfer Object Pattern)
设计模式之间的关系

在这里插入图片描述

具体设计模式举例

单例模式

保证一个类仅有一个实例,并提供一个访问它的全局访问点。
实现的方法为先判断实例存在与否,如果存在则直接返回,如果不存在就创建了再返回,这就确保了一个类只有一个实例对象。

如下图的车,只有一辆,一旦借出去则不能再借给别人:
在这里插入图片描述
在这里插入图片描述

  • 全局变量是单例模式吗?
    • 一般情况我们不认为全局变量是一个单例模式,原因是:全局命名污染且不易维护,容易被重写覆盖。
  • js中举例
    • 在javascript中,实现一个单例模式可以用一个变量标志当前的类已经创建过对象,如果下次获取当前类的实例时,直接返回之前创建的对象即可。
    • 在前端中,很多情况都是用到单例模式,例如页面存在一个模态框的时候,只有用户点击的时候才会创建,而不是加载完成之后再创建弹窗和隐藏,并且保证弹窗全局只有一个
    • 现在很多第三方库都是单例模式,多次引用只会使用同一个对象,如jquery、lodash、moment…
工厂模式

在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口指向新创建的对象

  • 工厂模式通常会分成3个角色:
    • 工厂角色 — 负责实现创建所有实例的内部逻辑。
    • 抽象产品角色 — 是所创建的所有对象的父类,负责描述所有实例所共有的公共接口。
    • 具体产品角色 — 是创建目标,所有创建的对象都充当这个角色的某个具体类的实例。
      在这里插入图片描述
      就像工厂一样重复的产生类似的产品,工厂模式只需要我们传入正确的参数,就能生产类似的产品
  • 工厂模式根据抽象程度的不同可以分为:
    • 简单工厂模式(Simple Factory)
    • 工厂方法模式(Factory Method)
    • 抽象工厂模式(Abstract Factory)
简单工厂模式(Simple Factory)

简单工厂模式也叫静态工厂模式,用一个工厂对象创建同一类对象类的实例。

  • 假设我们要开发一个公司岗位及其工作内容的录入信息,不同岗位的工作内容不一致,当我们调用工厂函数时,只需要传递name、age、career就可以获取到包含用户工作内容的实例对象
工厂方法模式(Factory Method)

跟简单工厂模式差不多,但是把具体的产品放到了工厂函数的prototype中。

  • 相当于工厂总部不生产产品了,交给下辖分工厂进行生产
  • 但是进入工厂之前,需要有个判断来验证你要生产的东西是否是属于我们工厂所生产范围,如果是,就丢给下辖工厂来进行生产。
  • 工厂方法关键核心代码是工厂里面的判断this是否属于工厂,也就是做了分支判断,这个工厂只做我能做的产品。
抽象工厂模式(Abstract Factory)

简单工厂和工厂方法模式的工作是生产产品,那么抽象工厂模式的工作就是生产工厂的。

  • 由于JavaScript中并没有抽象类的概念,只能模拟,可以分成四部分:
    • 用于创建抽象类的函数
    • 抽象类
    • 具体类
    • 实例化具体类
策略模式

策略模式,就是定义一系列的算法,把他们一个个封装起来,目的就是将算法的使用与算法的实现分离开来,并且使他们可以相互替换。

  • 至少分成两部分:
    • 策略类(可变),策略类封装了具体的算法,并负责具体的计算过程。
    • 环境类(不变),接受客户的请求,随后将请求委托给某一个策略类。
  • 使用策略模式的优点有如下:
    • 策略模式利用组合,委托等技术和思想,有效的避免很多if条件语句
    • 策略模式提供了开放 — 封闭原则,使代码更容易理解和扩展。
    • 策略模式中的代码可以复用
代理模式

代理模式:为对象提供一个代用品或占位符,以便控制对它的访问。

  • 代理模式的关键是,当客户不方便直接访问一个对象或者不满足需要时,提供一个替身对象来控制这个对象的访问,客户实际上访问的是替身对象。
    在这里插入图片描述
  • 在生活中,代理模式的场景是十分常见的,例如我们现在如果有租房、买房的需求,更多的是去找链家等房屋中介机构,而不是直接寻找想卖房或出租房的人谈。此时,链家起到的作用就是代理的作用。
  • 例如实现图片懒加载的功能,先通过一张loading图占位,然后通过异步的方式加载图片,等图片加载好了再把完成的图片加载到img标签里面。
实现

在ES6中,存在proxy构建函数能够让我们轻松使用代理模式:const proxy = new Proxy(target, handler);
按照功能来划分,javascript代理模式常用的有:

  • 缓存代理
    • 缓存代理可以为一些开销大的运算结果提供暂时的存储,在下次运算时,如果传递进来的参数跟之前一致,则可以直接返回前面存储的运算结果。
  • 虚拟代理
    • 虚拟代理把一些开销很大的对象,延迟到真正需要它的时候才去创建,常见的就是图片预加载功能。
中介者模式

中介者模式的定义:通过一个中介者对象,其他所有的相关对象都通过该中介者对象来通信,而不是相互引用,当其中的一个对象发生改变时,只需要通知中介者对象即可

  • 通过中介者模式可以解除对象与对象之间的紧耦合关系
装饰者模式

装饰者模式的定义:在不改变对象自身的基础上,在程序运行期间给对象动态地添加方法。

  • 通常运用在原有方法维持不变,在原有方法上再挂载其他方法来满足现有需求。
观察者模式

观察者模式定义了对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知,并自动更新。

  • 观察者模式属于行为型模式,行为型模式关注的是对象之间的通讯,观察者模式就是观察者和被观察者之间的通讯。
    在这里插入图片描述
发布订阅模式

发布-订阅是一种消息范式,消息的发送者(称为发布者)不会将消息直接发送给特定的接收者(称为订阅者)。而是将发布的消息分为不同的类别,无需了解哪些订阅者(如果有的话)可能存在。

  • 订阅者可以表达对一个或多个类别的兴趣,只接收感兴趣的消息,无需了解哪些发布者存在。
发布订阅和观察者模式联系与区别

两种设计模式思路是一样的,举个生活例子:

  • 观察者模式:某公司给自己员工发月饼发粽子,是由公司的行政部门发送的,这件事不适合交给第三方,原因是“公司”和“员工”是一个整体。
  • 发布-订阅模式:某公司要给其他人发各种快递,因为“公司”和“其他人”是独立的,其唯一的桥梁是“快递”,所以这件事适合交给第三方快递公司解决。
  • 上述过程中,如果公司自己去管理快递的配送,那公司就会变成一个快递公司,业务繁杂难以管理,影响公司自身的主营业务,因此使用何种模式需要考虑什么情况两者是需要耦合的。
区别

在这里插入图片描述

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

努力不熬夜的小喵

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值