Javascript——设计模式(一)

news2024/11/16 8:54:48

Javascript常见设计模式-CSDN博客

设计模式专栏内容总结-CSDN博客

C#编程思想——设计模式-CSDN博客

设计模式概述及其作用

设计模式(Design Pattern)是一套被反复使用、多数人知晓的、经过分类编目的代码设计经验的总结。使用设计模式的主要目的是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。设计模式使代码编制真正工程化,是软件工程的基石。

23种设计模式分类

23种设计模式分为以下三大类:

  1. 创建型模式:包括单例模式、抽象工厂模式、建造者模式、工厂模式、原型模式等。
  2. 结构型模式:包括适配器模式、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模式等。
  3. 行为型模式:包括模版方法模式、命令模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式、状态模式、策略模式、职责链模式、访问者模式等。

单例模式及其使用场景

单例模式(Singleton Pattern)是创建型模式的一种,它确保一个类只有一个实例,并提供一个全局访问点。

使用场景

  1. Windows的任务管理器,只能打开一个任务管理器。
  2. Windows系统的回收站。
  3. 网站的计数器,通过单例模式可以很好地实现。
  4. 应用程序的日志应用,一般都使用单例模式实现,因为系统一般共用一个日志。
  5. 数据库连接池的设计一般也是采用单例模式,因为数据库连接是一种数据库资源,使用单例模式可以大大降低打开或关闭数据库连接所引起的效率损耗。

实现方式

  1. 懒汉式(线程不安全):支持延迟加载,但在多线程环境下不能保证单例的唯一性。
  2. 懒汉式(线程安全):通过在方法前加同步锁synchronized关键字的方式,保证在多线程环境下单例的唯一性,但会降低性能。
  3. 饿汉式:类加载时就初始化实例,避免了多线程同步问题,但可能会浪费一些空间。
  4. 双重检查锁定:在懒汉式基础上增加了双重检查,既保证了懒加载,又解决了多线程问题。
  5. 静态内部类:利用类加载机制保证单例的唯一性,既实现懒加载,又保证了线程安全。

保证线程安全

  1. 使用synchronized关键字。
  2. 使用双重检查锁定。
  3. 使用静态内部类。

工厂模式和抽象工厂模式的区别

  1. 目的不同:工厂模式旨在通过让子类决定应该实例化哪一个类来创建对象,主要用于创建单一类型的对象。而抽象工厂模式提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。
  2. 复杂性不同:工厂模式相对简单,每个具体工厂类只负责创建一种具体产品。抽象工厂模式更复杂,一个工厂类可以创建多种产品对象。
  3. 应用场景不同:工厂模式适用于产品种类相对较少且不会频繁增加的情况。抽象工厂模式适用于有多个产品系列,且产品系列中的产品需要一起使用的场景。

简单工厂模式的工作原理

简单工厂模式(Simple Factory Pattern),又叫做静态工厂方法(Static Factory Method)模式,但它不属于23种GOF设计模式之一。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。其实质是由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类(这些产品类继承自一个父类或接口)的实例。

建造者模式及其使用场景

建造者模式(Builder Pattern)是一种创建型设计模式,它允许你通过分步骤的方式构建一个复杂对象。建造者模式将一个复杂对象的构建过程与其表示分离,使得同样的构建过程可以创建不同的表示。

使用场景

  1. 需要生成的对象具有复杂的内部结构。
  2. 需要生成的对象内部属性本身相互依赖。
  3. 在对象构建过程中需要使用到构建对象之外的其他服务。

原型模式及其使用场景

原型模式(Prototype Pattern)是一种创建型设计模式,它允许通过复制(或克隆)一个已经存在的对象来创建一个新的对象,而无需重新实例化它。

使用场景

  1. 当一个系统应该独立于它的产品创建、构成和表示时。
  2. 当创建对象的成本很高时(如创建的时间开销很大,或者需要的资源很多)。
  3. 当一个系统需要复制很多对象,而又不能使用语言中的复制构造函数时。

适配器模式及其使用场景

适配器模式(Adapter Pattern)是一种结构型设计模式,它允许接口不兼容的类一起工作,通过将一个类的接口转换成客户希望的另外一个接口,使原本由于接口不兼容而不能一起工作的那些类可以一起工作。

使用场景

  1. 你想要使用一个已经存在的类,但是它的接口与你的需求不匹配。
  2. 你想创建一个可以复用的类,该类可以与其他不相关的类或不可预见的类(即那些接口可能不兼容的类)一起工作。
  3. 你想使用一个已经存在的子类,但是你不能通过继承来复用它的代码,或者你想在运行时动态地指定要使用的类。

桥接模式及其使用场景

桥接模式(Bridge Pattern)是一种结构型设计模式,它将抽象部分与实现部分分离,使它们都可以独立地变化。

使用场景

  1. 当一个类存在两个或多个独立变化的维度,而这些维度都需要进行扩展时。
  2. 当你希望避免因一个维度的变化而影响到其他维度时。
  3. 当你希望实现非常灵活的抽象和实现之间的解耦时。

组合模式及其使用场景

组合模式(Composite Pattern)是一种结构型设计模式,它将对象组合成树形结构以表示“部分-整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。

使用场景

  1. 你希望用户以统一的方式处理个别对象和组合对象时。
  2. 你想表示对象的部分-整体层次结构时。
  3. 你希望用户忽略组合对象与单个对象的差异时。

装饰器模式及其使用场景

装饰器模式(Decorator Pattern)是一种结构型设计模式,它允许你向一个现有的对象添加新的功能,同时又不改变其结构。

使用场景

  1. 当你想要在不修改现有类的前提下,给类动态地增加职责时。
  2. 当你想要复用现有类时,并且这些类的接口是稳定的(即它们的方法不会改变)。
  3. 当你想要将职责分配给多个对象,而不是只有一个对象时(这可以消除“过多的使用继承”所带来的问题)。

装饰器、适配器、代理、桥接四种设计模式的区别

  1. 装饰器模式:动态地给一个对象添加一些额外的职责。就增加功能来说,装饰器模式比生成子类更为灵活。
  2. 适配器模式:将一个类的接口转换成客户希望的另外一个接口,使原本由于接口不兼容而不能一起工作的那些类可以一起工作。
  3. 代理模式:为其他对象提供一种代理以控制对这个对象的访问。
  4. 桥接模式:将抽象部分与实现部分分离,使它们都可以独立地变化。

外观模式及其使用场景

外观模式(Facade Pattern)是一种结构型设计模式,它提供了一个统一的接口,用来访问子系统中的一群接口。外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。

使用场景

  1. 当你想要为一个复杂子系统提供一个简单接口时。
  2. 当你想要让客户从子系统的具体实现中解耦时。
  3. 当你想要在一个层次结构的子系统中提供一个一致的接口时。

享元模式及其使用场景

享元模式(Flyweight Pattern)是一种结构型设计模式,它使用共享对象,用以尽可能减少内存。它主要用于减少对象数量,以减少内存和提高性能。

使用场景

  1. 当系统中存在大量的相似对象,这些对象耗费大量内存资源时。
  2. 当你需要将对象的状态外部化,以便减少对象本身所占用的内存时。
  3. 当你希望使用共享对象来减少对象数量,从而提高性能时。

代理模式及其使用场景

代理模式(Proxy Pattern)是一种结构型设计模式,它为其他对象提供一种代理以控制对这个对象的访问。

使用场景

  1. 当你想要为另一个对象提供一个代理以控制对这个对象的访问时。
  2. 当你想要在不修改现有类的前提下,为类添加额外的功能时(例如,日志记录、安全检查等)。
  3. 当你想要延迟对象的创建时(例如,懒加载)。

观察者模式及其使用场景

观察者模式(Observer Pattern)是一种行为型设计模式,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。

使用场景

  1. 当一个对象改变状态后,需要自动通知并更新其他对象时。
  2. 当一个对象需要与其他对象保持松散的耦合关系时(即对象之间不需要直接引用对方)。
  3. 当一个对象的状态变化需要通知多个对象时。

以上是对设计模式的详细解答,包括其定义、作用、分类以及各种具体模式的工作原理和使用场景。希望这些信息能帮助你更好地理解和准备前端面试。

什么是迭代器模式?一般用在什么场景?

迭代器模式是一种行为型设计模式,它用于提供一种顺序访问聚合对象中各个元素的方法,而又不暴露该对象的内部表示。通过使用迭代器模式,可以遍历一个聚合对象,而无需关心该对象的内部结构和实现细节。

使用场景

  • 当你需要访问一个聚合对象中的元素,但不想暴露其内部结构时,可以使用迭代器模式。例如,遍历一个列表、集合或数组等数据结构时,可以使用迭代器模式来隐藏底层数据结构的实现细节,提供统一的遍历接口。

什么是模板方法模式?一般用在什么场景?

模板方法模式定义了一个算法的骨架,并允许子类为一个或多个步骤提供实现。它使得子类在不改变算法结构的前提下,可以重新定义算法的某些步骤。

使用场景

  • 父类视角:一次性实现一个算法不变的部分,并将可变部分留给子类实现。
  • 子类视角:各个子类中公共部分被提取出来,集中到一个公共的父类中,避免代码重复。

例如,在软件开发中,经常需要执行一系列步骤来完成某个任务,这些步骤中有些是不变的,有些是可变的。此时,可以使用模板方法模式来定义一个算法的骨架,将不变的部分放在父类中实现,将可变的部分留给子类实现。

什么是命令模式?一般用在什么场景?

命令模式将一个请求封装为一个对象,使发出请求的责任和执行请求的责任分割开。两者通过命令对象进行沟通,这样方便将命令对象进行储存、传递、调用、增加与管理。

使用场景

  • 需要将请求排队、记录请求日志、支持可撤销操作等。
  • 在系统需要将请求发送者和请求接收者解耦时,可以使用命令模式。例如,在GUI编程中,可以使用命令模式来将用户的操作封装为命令对象,然后将其传递给相应的处理函数或对象进行处理。

什么是状态模式?一般用在什么场景?

状态模式允许对象在内部状态改变时改变它的行为,对象看起来像是改变了它的类。

使用场景

  • 一个对象的行为取决于它的状态,并且它必须在运行时根据状态改变它的行为。
  • 代码中包含大量与对象状态有关的条件语句,例如,一个操作中含有庞大的多分支语句,且这些分支依赖于该对象的状态。

例如,在开发一个游戏时,游戏角色的状态可能会随着游戏的进行而改变(如空闲、行走、战斗等),每种状态下角色的行为也会有所不同。此时,可以使用状态模式来将角色的不同状态及其对应的行为封装到不同的状态类中,从而实现状态的切换和行为的改变。

什么是策略模式?一般用在什么场景?

策略模式定义了一系列算法,并将每一个算法封装起来,使它们可以互换。策略模式使得算法可以独立于使用它的客户端而变化。

使用场景

  • 当实现某一个功能存在多个算法或者策略时,可以根据环境或者条件的不同选择不同的算法或者策略来实现某个功能。
  • 一个系统需要动态地在几种算法中选择一种时,可以将每个算法封装到策略类中。

例如,在开发一个电商网站时,可能会有多种不同的支付策略(如支付宝支付、微信支付、银行卡支付等)。此时,可以使用策略模式来将这些不同的支付策略封装到不同的策略类中,然后根据用户的支付选择来动态地选择相应的支付策略。

什么是责任链模式?一般用在什么场景?

责任链模式使多个对象都有机会处理请求,从而避免了请求的发送者和接受者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有对象处理它为止。

使用场景

  • 需要将请求和处理分开,使得请求的处理过程更加灵活和可扩展。
  • 当有多个对象可以处理同一个请求,但具体由哪个对象处理是运行时决定的。

例如,在开发一个Web应用时,可能会有多个过滤器(如身份验证过滤器、日志记录过滤器等)来对用户的请求进行处理。此时,可以使用责任链模式来将这些过滤器连成一条链,并根据需要动态地添加或删除过滤器。

什么是中介者模式?一般用在什么场景?

中介者模式包装了一系列对象相互作用的方式,使得这些对象不必相互明显作用。从而使他们可以松散耦合。当某些对象之间的作用发生改变时,不会立即影响其他的一些对象之间的作用。

使用场景

  • 当对象之间的交互操作很多且每个对象的行为操作都彼此依赖时,为防止在修改一个对象的行为时同时涉及修改很多其他对象的行为,可采用中介者模式来解决紧耦合问题。

例如,在开发一个聊天室应用时,可能会有多个用户同时在线并相互发送消息。此时,可以使用中介者模式来将用户之间的消息传递过程封装到一个中介者对象中,从而实现用户之间的松散耦合和消息的高效传递。

什么是访问者模式?一般用在什么场景?

访问者模式是一种将数据操作与数据结构分离的设计模式。它允许你定义一个新的操作,而不修改现有的类层次结构。

使用场景

  • 当一个复杂的对象结构包含多个类的对象,并且希望在不修改这些类的情况下增加新的操作。

例如,在开发一个图形编辑器时,可能会有多种不同的图形对象(如圆形、矩形、三角形等)。此时,可以使用访问者模式来定义一个新的操作(如计算图形的面积或周长),而无需修改现有的图形类。

什么是备忘录模式?一般用在什么场景?

备忘录模式在不破坏封装性的前提下,捕获并恢复对象的内部状态。

使用场景

  • 需要保存和恢复对象的状态的场景。例如,在开发一个文本编辑器时,可以使用备忘录模式来保存和恢复文档的编辑状态。

以下是对前端面试题中各个概念及问题的详细回答:

单一职责原则

  • 定义:单一职责原则(Single Responsibility Principle,SRP)规定一个类应该只有一个发生变化的原因。它要求一个类或者模块应该有且只有一个改变的原因,即一个类只做一件事情,并将这件事情做好。
  • 应用场景:在大型复杂系统中,应用单一职责原则能提高代码质量和可维护性。通过将类的职责分解为多个独立的类,可以降低类的复杂度,提高代码的可读性和可维护性。

开闭原则

  • 定义:开闭原则(Open Closed Principle,OCP)是面向对象程序设计中的一个基本原则。它的核心思想是,一个软件实体(如类、模块或函数)应该对扩展开放,对修改封闭。
  • 应用场景:开闭原则主要应用于软件架构设计中,帮助设计出更加灵活和可扩展的系统结构。通过模块化设计,将不同的功能模块化,每个模块内部的变化不会影响到其他模块,从而实现系统的可扩展性。

里氏替换原则

  • 定义:里氏替换原则(Liskov Substitution Principle,LSP)强调在软件设计中,基类对象可以被其子类对象替换,而不会影响程序的正确性。
  • 应用场景:里氏替换原则在继承体系设计中尤为重要。它确保子类能够替换父类而不会影响系统的正确性,从而帮助构建一个更稳定、可扩展的系统。

接口隔离原则

  • 定义:接口隔离原则要求客户端不应该依赖它不需要的接口,即类间的依赖关系应该建立在最小的接口上。
  • 应用场景:接口隔离原则主要用于将臃肿的接口拆分为独立的几个接口,使得客户端只需要依赖它们需要的接口。这有助于降低代码的耦合度,提高系统的灵活性和可维护性。

依赖倒置原则

  • 定义:依赖倒置原则(Dependency Inversion Principle,DIP)指导我们如何构建松耦合、易于扩展和维护的系统。它要求高层模块不应该依赖于低层模块,两者都应该依赖于抽象。
  • 应用场景:依赖倒置原则在面向对象设计中非常重要。它通过将依赖关系建立在抽象之上,减少了模块间的直接依赖,提高了系统的灵活性和可扩展性。

迪米特法则

  • 定义:迪米特法则(Law of Demeter)又称最少知识原则(Principle of Least Knowledge),它强调对象之间的松耦合和封装性。一个对象应该尽可能少地了解其他对象的细节,只与其直接的朋友进行通信。
  • 应用场景:迪米特法则在面向对象设计中用于降低系统的复杂度和依赖关系。通过减少对象之间的交互和依赖,提高了系统的可维护性和可扩展性。

设计模式

  • 定义:设计模式是在软件工程中反复出现的问题的最佳解决方案。它不是一种具体的“技术”,而是一种“思想”,是从众多成功案例中总结出的经验。

  • 常见的设计模式

    • 单例模式:确保一个类只有一个实例,并提供全局访问点。
    • 工厂模式:定义一个用于创建对象的接口,由子类决定实例化哪个类。
    • 适配器模式:将一个类的接口转换成客户希望的另一个接口。
    • 策略模式:定义一系列算法,将每个算法都封装起来,并使它们可以互换。
    • 代理模式:为其他对象提供一种代理以控制对这个对象的访问。
    • 观察者模式:定义对象之间的一对多依赖关系,使得一个对象的状态改变会通知其依赖者。
  • 使用原因:使用设计模式可以提高代码的可重用性、可读性和可维护性。它帮助我们构建出更加灵活、可扩展和易于维护的系统。

综上所述,这些原则和设计模式在前端开发中同样具有重要意义。它们不仅有助于提高代码质量,还能降低系统的复杂度和维护成本。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2241393.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

IoT [remote electricity meter]

IoT [remote electricity meter] 物联网,远程抄表,电表数据,举个例子

sql数据库-排序查询-DQL

目录 语法 排序方式 举例 将表按年龄从小到大排序 将表按年龄从大到小排序 ​编辑 多重排序 将表按年龄升序,年龄相同按入职时间降序 语法 select * from 表名 order by 字段名1 排序方式1,字段2 排序方式2; 排序方式 升序:ASC&…

在spring boot工程中使用Filter时,@WebFilter 注解不生效的问题分析和解决方案

1. 问题描述 首先编写一个Filter类并通过Component放入spring容器中,通过实现jakarta.servlet中提供的Filter接口完成过滤器的创建,代码如下。 import jakarta.servlet.*; import jakarta.servlet.annotation.WebFilter; import org.springframework.st…

学习threejs,使用TWEEN插件实现动画

👨‍⚕️ 主页: gis分享者 👨‍⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍⚕️ 收录于专栏:threejs gis工程师 文章目录 一、🍀前言1.1 ☘️THREE.PLYLoader PLY模型加…

TypeScript在现代前端开发中的应用

💓 博客主页:瑕疵的CSDN主页 📝 Gitee主页:瑕疵的gitee主页 ⏩ 文章专栏:《热点资讯》 TypeScript在现代前端开发中的应用 TypeScript在现代前端开发中的应用 TypeScript在现代前端开发中的应用 引言 TypeScript 概述…

CTF-Crypto-简单加密

打开首页看题目 描述看起来是一段乱码,拉入随波逐流,未解决 e6Z9i~]8R~U~QHE{RnY{QXg~QnQ{^XVlRXlp^XI5Q6Q6SKY8jUAA 观察字符串,末尾是AA,其中可能含有base64加密 找寻Ascll码表,发现A的Ascll是65,的Ascl…

MacOS下,如何在Safari浏览器中打开或关闭页面中的图片文字翻译功能

MacOS下,如何在Safari浏览器中打开或关闭页面中的图片文字翻译功能 在Mac上的Safari浏览器中,可以通过实况文本功能来实现图片中的文本翻译。关闭步骤具体步骤如下: 在浏览器地址栏,鼠标右击翻译按钮,然后点击“首选…

操作系统——虚拟存储器(含思维导图)

本教材为中国铁道出版社——操作系统(第四版)刘振鹏、张明、王煜著。本篇文章为第六章复习。 目录 思维导图: ​编辑一、虚拟存储器 1.理论基础 2.定义 二、分页虚拟存储管理 1.基本原理 2.缺页中断 3.页面置换 (1&…

基于8.0 Update 3b 的ESXi-Arm Fling

很久没有更新过 ESXi-Arm 的版本了,博通旗下的 VMware 居然把它更新到了 8.0U3b。 下载地址:https://community.broadcom.com/flings 我准备使用离线更新,就没有下载 ISO,直接下载ESXi-Arm-Offline-Depot-2_00-dl.zip scp 上传…

python解析网页上的json数据落地到EXCEL

安装必要的库 import requests import pandas as pd import os import sys import io import urllib3 import json测试数据 网页上的数据结构如下 {"success": true,"code": "CIFM_0000","encode": null,"message": &quo…

C#桌面应用制作计算器

C#桌面应用制作简易计算器,可实现数字之间的加减乘除、AC按键清屏、Del按键清除末尾数字、/-按键取数字相反数、%按键使数字缩小100倍、按键显示运算结果等...... 页面实现效果 功能实现 布局 计算器主体使用Panel容器,然后将button控件排列放置Pane…

谷歌推出设备内置人工智能,实时向手机用户发出诈骗电话警报

Google 宣布推出适用于 Android 的新安全功能,可实时防御诈骗和有害应用。 这些功能由先进的设备内置 AI 提供支持,可在不损害隐私的情况下增强用户安全性。 这些新的安全功能首先在 Pixel 上推出,并将很快在更多 Android 设备上推出。 诈…

HarmonyOS ArkTs 解决流式传输编码问题

工作日志 日期:2024-11-15 标题:HarmonyOS ArkTs 解决流式传输编码问题 问题描述 问题:在处理流式数据的 HTTP 请求时,服务器返回的数据存在编码问题,导致数据无法正确地解码为字符串。部分数据在解码后出现了乱码…

MySQL数据库最大连接数查询及修改

MySQL数据库最大连接数查询及修改 1. 客户端连接数超出异常案例 Navicat连接异常信息如下: 2. 查看MySQL最大客户端连接数 通过mysql client命令登录MySQL数据库(登录用户不受限制,既可以是 root管理员用户,也可以是常规用户&a…

使用Wireshark获取USB HID(Human Interface Device)报告描述符

使用Wireshark选择需要获取的USB进行抓取数据,找到设备(host)接收信息的数据 第二栏出现hid报告,右击选择复制流 将复制的内容粘贴到USB标准请求及描述符在线分析工具 - USB中文网 进行解析 以图中获取手写板的数据为例&#xff…

TofuAI处理BT1120时序视频要求

时序要求 BT.1120视频用于1920x108030Hz数字视频输入。具体时序必须严格按照说明。BT.1120输入电平为1.8V。 BT1120数字视频采用YCbCr彩色格式输出,串行数据位宽为16bit,亮度在 高8bit,色度在低8bit,亮度和色度在同一个时钟周期输…

聊天服务器(8)用户登录业务

目录 登录状态业务层代码数据模型层代码记录用户的连接信息以及线程安全问题客户端异常退出业务 登录状态 登录且状态变为online 业务层代码 #include "chatservice.hpp" #include "public.hpp" #include <string> #include <muduo/base/Loggi…

通用定时器---输出比较功能

目录 一、概念 二、输出比较的8种模式 三、输出比较输出PWM波形的基本结构 配置步骤 四、示例代码 一、概念 OC&#xff08;OutPut Compare&#xff09;输出比较。输出比较可以通过比较CNT与CCR寄存器的关系&#xff0c;来对输出电平进行置1/置0/翻转的操作&#xff0c;可…

Wireshark中的length栏位

注&#xff1a;Ethernet II的最小data length为46&#xff0c;如果小于&#xff0c;会补全到46. 1.指定网卡抓取的&#xff0c;链路为ethernet。 IPv4 Ethernet II 长度为 14 bytes - L1ipv4 header中的length包括header和payload的总长度 - L2wireshark中length表示抓取的pac…

spring boot整合https协议

整体目录 1. 生成SSL证书 首先&#xff0c;使用keytool生成一个自签名证书。打开命令行工具并运行以下命令&#xff1a; keytool -genkeypair -alias myserver -keyalg RSA -keysize 2048 -keystore keystore.jks -validity 365 这将创建一个名为keystore.jks的文件&#xf…