一、理解什么是设计模式
设计模式是对软件设计开发过程中反复出现的某类问题的通用解决方案。
设计模式是一个在软件设计领域中被广泛应用的概念,它指的是一套被公认为有效的解决特定问题的设计思路和方法。
设计模式更多的是指导思想和方法论,而不是现成的代码,当然每种设计模式都有每种语言中的具体实现方式。
学习设计模式更多的是理解各种模式的内在思想和解决的问题,毕竟这是前人无数经验总结成的最佳实践,而代码实现则是对加深理解的辅助。
设计模式的目的是帮助开发人员在面对复杂的软件设计问题时,可以更加高效、优雅地解决问题,并提高软件的可重用性、可维护性、可扩展性和可靠性。
设计模式通常包括一系列定义良好的类和对象,以及它们之间的关系和交互方式,是一种被反复使用、实践并广泛认可的模式或范例。
二、常见的设计模式有以下几种
序号 | 分类 | 名称 | 理解 |
1 | 创建型模式 | 单例模式 | 单例模式是一种创建型设计模式,它保证了一个类只有一个实例,并提供了一个全局的访问点。单例模式常常用于管理全局唯一的资源,如全局配置、日志记录、数据库连接等。 单例模式是一种具体的实现,而不是一种抽象的概念模式。在实现单例模式时,需要考虑线程安全、并发控制、延迟实例化等问题。 在单例模式的实现中,常用的方法有:
|
2 | 工程模式 | 工程模式是一种软件设计模式,它旨在提供一种可重用的解决方案,以解决在软件开发中常见的设计问题。工程模式强调了软件设计的结构透明性和模块化,使得软件系统更易于维护和扩展。工程模式通常包括以下几个部分:
通过使用工程模式,可以将具体的实现细节与客户端代码分离开来,从而实现松耦合的设计。这样一来,当需求发生变化时,只需修改具体类的实现即可,而不会影响到客户端代码。工程模式在大型软件系统中应用广泛,例如,Java语言中的工厂模式、单例模式、抽象工厂模式等都是工程模式的典型应用。 | |
3 | 抽象工厂模式 | 抽象工厂模式是一种创建型设计模式。它允许客户端通过接口创建一组相关或相互依赖的对象,而不需要指定它们的具体类。抽象工厂模式与工厂方法模式的区别在于,它可以创建多个产品族,而不仅仅是一个产品等级结构。在抽象工厂模式中,客户端不需要创建对象,而是通过工厂接口来获取所需的对象实例。这样可以提高系统的灵活性和可扩展性,因为客户端只需要知道工厂接口,而无需关心具体的产品实现细节。 | |
4 | 建造者模式 | 建造者模式是一种创建型设计模式,它允许你创建复杂对象的过程与其表示相分离。这样,同样的构建过程可以创建不同的表示形式。建造者模式使得你可以在不同的步骤中创建对象,这些对象在创建时可能需要不同的步骤,并且可能需要以不同的顺序执行这些步骤。 在建造者模式中,有一个“Director”负责控制对象的构建过程,而有一个“Builder”负责实际构建对象。通过这种方式,Director 和 Builder 可以相互独立,从而使得构建过程更加灵活和可扩展。 建造者模式通常被用于创建对象的构建过程比较复杂,或者需要多个步骤才能完成的情况。它可以让你更好地组织代码,并且提高代码的复用性和可维护性。 | |
5 | 原型模式 | 原型模式是一种创建型设计模式,它允许通过复制现有对象来创建新对象,而不是通过实例化新对象并初始化它们的值。即原型模式是一种通过克隆来创建对象的模式。 在原型模式中,一个原型对象被克隆来创建新的对象。这个原型对象是一个已经初始化的对象,它包含了我们需要的所有属性和方法。新对象可以通过复制这个原型对象来创建,并且可以修改其属性值和方法实现以满足特定的需求。 原型模式被广泛应用于创建大量相似对象的场景,以避免重复的初始化过程,并提高对象创建的效率。 | |
6 | 结构型模式 | 适配器模式 | 适配器模式是一种结构型设计模式,它允许将不兼容的接口转换为客户端所期望的接口。它解决了不同类之间接口不兼容的问题,使得这些类可以协同工作。 适配器模式有三个角色:
适配器模式主要通过适配器类来实现对现有接口的转换,使得客户端代码可以透明地使用新的接口。适配器模式的优点是可以提高代码重用性和灵活性,同时降低了系统的耦合度。但是,适配器模式也会增加系统的复杂度,因为需要增加适配器类来进行接口转换。 |
7 | 桥接模式 | 桥接模式是一种结构型设计模式,用于将抽象与实现分离,使它们可以独立地变化。桥接模式的核心思想是把实现和抽象分离开来,让它们可以独立变化,从而达到更好的灵活性。 在桥接模式中,抽象部分定义了一个接口,它包含了对某种功能的抽象方法,而实现部分则是提供了这个功能的具体实现。两者之间通过一个桥接接口进行通信。 桥接模式的优点在于它能够轻松地扩展和修改系统的功能,同时减少了不必要的类之间的依赖关系,从而提高了系统的灵活性和可维护性。 桥接模式的缺点在于它会增加系统的复杂性和代码量,需要设计者有较强的抽象能力和对系统的整体架构有清晰的把握。 | |
8 | 组合模式 | 组合模式是一种结构型设计模式,它将对象组合成树状结构,以表示“部分-整体”的层次结构。组合模式让客户端可以统一对待单个对象和组合对象,从而简化了客户端的代码,同时也使得整个系统更加灵活和可扩展。 在组合模式中,树状结构中的每个节点都可以是单个对象或者是一个组合对象。每个组合对象都可以包含其它组合对象和单个对象,从而形成了一个树形结构。所有的节点都实现了相同的接口,这样客户端可以使用相同的方式来访问树中的所有节点。 组合模式的优点在于它可以简化客户端的代码,因为客户端不需要关注是单个对象还是组合对象,而只需要使用相同的方式来操作它们。另外,组合模式也支持嵌套的结构,因此可以表示非常复杂的层次结构。 组合模式的缺点在于它可能会加重系统的复杂性,因为需要为每个节点都实现相同的接口。此外,组合模式也可能会带来一些性能上的问题,因为在处理大型树形结构时,可能需要遍历整个树形结构,从而影响系统的性能。 | |
9 | 装饰模式 | 装饰模式是一种结构型设计模式,它允许在运行时动态地将责任附加到对象上,同时不改变其行为和接口。 装饰模式通过将一个对象嵌套在另一个对象中来实现这一点,将对象进行逐层的封装。这样可以在不影响原有代码的情况下,动态地为对象添加新的行为;同时也可以动态地移除已有的行为。这样做的好处是,可以避免使用继承来扩展对象的行为,降低了代码的复杂性,同时提供了更大的灵活性和可维护性。 装饰模式的核心思想是将对象的行为分离成单独的类,然后将这些类动态地组合在一起。这使得我们可以更加灵活地管理对象的不同行为,并且可以根据需要添加、删除或替换这些行为。 | |
10 | 外观模式 | 外观模式是一种结构型设计模式,它提供了一个高层次的接口,以简化一组复杂的子系统的使用。它允许客户端通过简化的接口来与复杂的系统进行通信,而不需要了解系统的详细实现。 外观模式包含一个外观类,该类包含对子系统中各个类的引用。客户端通过外观类与子系统进行通信,而不需要直接调用子系统中的类。外观类将客户端的请求转发给子系统中的适当类,并将结果返回给客户端。 外观模式的优点包括: 1. 简化了客户端与子系统之间的交互,使得代码更加简洁易懂。 2. 降低了客户端与子系统之间的耦合度,提高了系统的可维护性和可扩展性。 3. 提供了一个安全的、受控的访问方式,以防止客户端直接访问子系统中的类。 4. 提高了系统的性能,因为外观类可以缓存请求结果,减少了对子系统的访问次数。 外观模式常用于大型系统中,可以帮助客户端更好地组织代码,并提高代码重用性和可维护性。 | |
11 | 享元模式 | 享元模式是一种结构型设计模式。它的主要目的是减少程序所需的内存和计算资源,通过共享对象的方法来有效地支持大量的小型对象。这个模式将对象分为两个部分:内部状态和外部状态。内部状态是可以共享的,而外部状态则是每个对象都不同的。 在享元模式中,共享对象通常是不可变的,一旦创建,就不能修改它们的内部状态,因为修改它们的状态可能会影响其他使用该对象的客户端。 享元模式常用于需要大量相似对象的场景,例如文本编辑器中的字体和颜色,图像编辑器中的像素颜色等。 这个模式的优点是可以减少内存使用,提高程序性能,缺点是代码变得更加复杂,需要仔细维护共享对象的状态。 | |
12 | 代理模式 | 代理模式是一种常见的设计模式,它允许通过代理对象来控制对某个对象的访问。代理对象与被代理对象实现相同的接口,因此客户端无法区分其是否在与被代理对象直接交互。 代理模式的使用场景主要有以下几种: 1. 远程代理:通过代理对象访问远程服务器上的对象,可以在客户端和服务器之间建立网络连接。 2. 虚拟代理:代理对象在访问被代理对象之前执行一些操作,例如创建被代理对象需要的资源,只有在必要时才会实例化被代理对象。 3. 安全代理:代理对象对访问进行控制,例如验证客户端是否有访问权限。 4. 智能代理:代理对象可以在被代理对象上添加一些额外的操作,例如缓存结果、记录日志等。 优点: 1. 代理对象可以隐藏被代理对象的具体实现,保护其知识产权和商业秘密。 2. 代理对象可以在访问被代理对象前进行验证和授权,提高系统的安全性。 3. 代理对象可以在访问被代理对象时进行一些额外的操作,例如缓存结果、记录日志等。 缺点: 1. 代理模式会增加系统的复杂度,需要额外的代码来实现代理对象和被代理对象之间的交互。 2. 代理对象的性能可能会受到影响,特别是在执行一些额外操作时。 | |
13 | 行为型模式 | 责任链模式 | 责任链模式是一种行为设计模式,在该模式中,多个对象组成一个链,并依次尝试处理请求,直到其中一个对象能够处理该请求为止。每个对象都有机会处理请求或者将其传递给链中的下一个对象,这样的设计能够避免请求发送者和接收者之间的直接耦合。责任链模式的主要目的是将请求从一个对象传递到另一个对象,直到找到能够处理该请求的对象为止,这样能够提高代码的灵活性并降低系统的复杂度。其中的链可以由任何对象组成,例如对象、方法、组件等。 |
14 | 命令模式 | 命令模式(Command Pattern)是一种行为型模式,它将请求封装成对象,从而允许使用不同的请求、队列或者日志来参数化其他对象。该模式允许将请求发出者和请求接收者解耦。 在命令模式中,请求作为命令封装在对象中,并像其他对象一样进行处理。命令对象可以使用不同的请求和参数化它们,以便将需要执行的命令发送给不同的对象。命令模式的核心在于命令对象的抽象性,以及将请求的发送者和接收者分离的能力。 命令模式的参与者包括: - Command:命令接口,定义执行操作的统一接口。 命令模式常见的应用场景包括:多级撤销操作、队列请求等。 | |
15 | 解释器模式 | 解释器模式(Interpreter Pattern)是一种行为型设计模式,它定义了一种语言的文法,并且定义了一个解释器,用于解释该语言中的语句。这种模式将某个特定的领域问题分解为一组语法规则,然后用这些规则来解释执行问题。 解释器模式中的核心是解释器,它负责解释语言中的句子,并执行相应的操作。解释器通常由一个抽象语法树来表示语言的结构,每个节点表示一个语言元素,并且包含了具体的执行动作。 解释器模式适用于需要频繁进行某些特定操作的场景,比如一些领域特定语言或者一些规则引擎等。它可以将复杂的语言结构简化为一些简单的语法规则,并且可以方便地添加新的规则和操作。但是,由于解释器需要解释每个语言元素,因此解释器模式可能会影响性能和效率。 | |
16 | 迭代器模式 | 迭代器模式是一种行为型设计模式,它允许访问一个聚合对象的各个元素,而又不暴露该对象的内部结构。换句话说,迭代器模式提供了一种方法来访问容器对象中的所有元素,而无需暴露其实现细节。迭代器模式分离了对象的遍历行为,使得代码更加灵活,可维护性也更好。 在迭代器模式中,我们通常会定义一个迭代器接口,该接口包含了访问聚合对象中各个元素的方法。聚合对象则负责实现该接口,并提供访问自身元素的方法。客户端代码会使用迭代器接口来遍历聚合对象中的元素,而不关心具体实现细节。 迭代器模式能够很好地应对容器对象结构的变化,因为只需修改聚合对象的实现即可,而不会影响到客户端代码。此外,迭代器模式能够使代码更加简洁,因为遍历容器对象的代码不再分散在客户端代码中。 | |
17 | 中介者模式 | 中介者模式(Mediator Pattern)是一种行为型设计模式,它允许多个对象之间通过一个中介对象来协调和通信,从而降低对象之间的耦合度。中介者模式的核心思想是将对象之间的通信和协作抽象出来,通过中介者来处理这些通信和协作,使得对象之间只需要与中介者交互,而不需要直接交互。这样可以减少对象之间的依赖关系,从而实现更松耦合的设计。 中介者模式通常包括一个中介者(Mediator)和多个同事对象(Colleague)。同事对象之间需要通信时,不是直接相互引用,而是通过中介者来实现消息的转发和协调。中介者负责协调和管理同事对象之间的关系和行为,从而实现解耦的效果。中介者模式常用于复杂的应用场景中,如图形界面设计、服务器端程序设计等。 中介者模式的优点包括: 1. 降低了对象之间的耦合性,使得对象之间的交互更加灵活和可扩展; 中介者模式的缺点包括: 1. 中介者对象可能会变得过于复杂和庞大,难以维护; | |
18 | 备忘录模式 | 备忘录模式(Memento Pattern)是一种行为设计模式,它允许你在不暴露对象实现细节的情况下保存和恢复其内部状态。该模式涉及三种角色:发起人、备忘录和管理者。 发起人是需要被保存状态的对象。备忘录是一个简单的对象,它存储了发起人的某个状态。管理者负责存储备忘录,并在需要时将其返回给发起人。 使用备忘录模式,你可以随时保存发起人的状态,并在需要时将其还原。这可以让你在不破坏对象封装性的情况下进行恢复。 此外,该模式还支持撤销操作。当你执行一系列操作后,可以将当前状态存储为备忘录。如果之后你想撤销操作,可以恢复到之前的备忘录,达到撤销操作的目的。 备忘录模式在实际开发中常用于实现撤销和恢复功能、快照和版本控制等场景。 | |
19 | 观察者模式 | 观察者模式是一种行为型设计模式,它允许一个对象(被观察者)在其状态发生变化时自动通知一组依赖它的对象(观察者)。 在观察者模式中,被观察者对象(也称为主题或发布者)维护一组观察者对象,并在其状态发生变化时通知观察者。观察者对象实现了一个接口,该接口允许被观察者对象注册、注销和通知观察者。 观察者模式可以用于许多场景,如事件处理、用户界面、消息传递等。它提供了一种松散耦合的方式来实现对象之间的通信,使得被观察者和观察者可以独立地进行修改和扩展,而不会影响到其他对象。 | |
20 | 状态模式 | 状态模式(State Pattern)是一种行为型设计模式,它允许一个对象在其内部状态改变时改变它的行为。该模式将状态封装成不同的类,并将对象在不同状态下的行为委托给表示相应状态的对象来处理。这样可以减少条件语句的嵌套,使代码更加简洁与可维护。 状态模式主要包含以下角色: - Context(上下文):定义客户端所感兴趣的接口,并维护一个当前状态的实例,即维护一个State类型的对象。 应用场景: - 对象的行为随着状态的改变而改变; | |
21 | 策略模式 | 策略模式是一种行为设计模式,其目的是允许在运行时根据不同的情况选择不同的算法或行为。该模式将算法封装在单独的策略类中,并使它们互相替换。 使用策略模式的优势包括: 1. 提高代码的可维护性,易于添加或修改策略。 2. 提高代码的可测试性,可以针对不同策略编写独立的测试用例。 3. 降低代码的复杂度,将不同策略的实现分离,使得代码更清晰、更易于理解。 例如,一个电商网站可能需要根据不同的促销活动来计算折扣价格。使用策略模式可以创建不同的策略类来计算不同类型的折扣,例如按照百分比折扣、按照固定折扣、按照满减活动等。然后在运行时根据不同的促销活动选择不同的策略类来计算折扣价格。 | |
22 | 模板方法模式 | 模板方法模式是一种设计模式,它提供了一种在父类中定义操作中的算法骨架,而将一些步骤延迟到子类中实现的方式。因此,模板方法使得子类可以在不改变算法结构的情况下重新定义某些步骤。 这个模式的主要思想是将一些通用的步骤或算法实现在父类中,并定义一些占位符操作(称为“钩子”),这些占位符操作在子类中实现。然后在父类中使用这些操作来完成算法骨架,并在子类中实现占位符操作,以完成算法的具体实现。 模板方法模式有以下优点: 1. 通过将通用的算法实现放在父类中,可以避免代码重复。 2. 使用模板方法可以保持算法的稳定性,因为算法骨架不会改变。 3. 可以通过在子类中实现占位符操作来定制算法,从而实现代码重用和扩展。 模板方法模式的缺点是,父类和子类之间的关系可能变得复杂,因为子类必须遵守父类定义的算法骨架。如果算法骨架改变,可能需要更改所有子类的实现。 | |
23 | 访问者模式 | 访问者模式是一种行为型设计模式,它允许在不改变对象结构的情况下定义对该结构中对象的新操作。该模式将算法与其操作的对象分离开来,从而使其更易于添加、更容易维护。 在访问者模式中,有两个重要的角色:访问者和被访问者。被访问者是一个对象结构,例如一个树形结构或一个列表。访问者可以在不改变对象结构的情况下,对这些对象进行操作。 访问者模式的主要优点包括: 1. 使得添加新的操作变得更加简单,只需要增加新的访问者。 2. 将算法与其操作的对象分离开来,使得每个类的功能单一,更易维护。 3. 可以在不改变对象结构的情况下增加新的操作。 访问者模式的主要缺点包括: 1. 需要对对象结构进行重构,使其能够接受访问者访问。 2. 在对象结构稳定并且不经常改变时,访问者模式可能会增加复杂度,因为需要额外的接口和类来实现。 3. 访问者模式可能会影响程序的性能,因为它需要额外的类和接口来实现。 |
此外还有并发模式、架构模式等等。这些设计模式都是经过实践考验的经验总结,可以帮助开发人员快速解决一些常见的问题,在提高代码质量、可读性等方面起到积极的作用。
三、前端需要掌握的设计模式
1、MVC:模型(Model)、视图(View)和控制器(Controller)的设计模式,用于组织代码结构,将业务逻辑、数据处理和视图展示分离开来。
2、观察者模式:通过定义一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会收到通知并自动更新。
3、策略模式:定义一系列的算法,将它们封装成一个个独立的策略类,可以动态地选择使用哪个算法。
4、工厂模式:将创建对象的过程封装到工厂类中,通过传入不同的参数返回不同的对象。
5、单例模式:保证一个类只有一个实例,并提供一个全局访问点,避免重复创建和浪费资源。
6、适配器模式:将一个类的接口转换成客户希望的另一个接口,使得原本不兼容的类可以一起工作。
7、装饰器模式:动态地给一个对象添加一些额外的职责,而不需要修改其原始的类。
8、模板方法模式:将一些固定的算法流程封装到一个模板方法中,具体算法实现由子类完成,可以方便地扩展不同的算法。
9、命令模式(Command Pattern):将请求封装成一个对象,从而使得可以用不同的请求对客户进行参数化。
10、职责链模式(Chain of Responsibility Pattern):将请求的发送者和接收者解耦,使多个对象都有机会处理请求。
11、外观模式(Facade Pattern):为复杂的子系统提供一个简单的接口。
以上是前端开发中常用的一些设计模式,掌握它们可以提高代码的可复用性、可维护性和扩展性,但并不是必须要掌握的,可以根据实际需求和项目情况自行选择。
四、vue项目用到哪些设计模式
Vue.js 是一个 JavaScript 框架,以下是一些常见的设计模式在 Vue.js 项目中的应用情况:
1、MVVM 模式:Vue.js 是基于 MVVM(Model-View-ViewModel)模式设计的,它将模型、视图和视图模型分离,并通过数据绑定和事件机制实现它们之间的通信。它是MVC的变体,适用于前端开发。Vue.js就是基于MVVM模式的。MVVM将View和Model通过ViewModel(ViewModel就是一种介于View和Model之间的组件)来进行联系和通信,进而实现数据的双向绑定。
2、组件模式:Vue.js 的核心思想就是组件化,在 Vue.js 项目中,我们可以将应用程序划分为多个组件,然后通过组件间的通信构建复杂的用户界面。
3、观察者模式:Vue.js 实现了响应式编程的机制,通过观察者模式(Watcher)来监听数据变化,并自动更新视图。
4、单例模式:在 Vue.js 中,使用单例模式来管理应用程序级别的状态/管理全局的状态,例如 Vuex 中的 store 对象。
5、工厂模式:
Vue.js 的插件和指令可以采用工厂模式来创建实例,确保在不同的组件中使用相同的配置。
Vue中的组件可以看作是一种工厂模式的实现。开发者只需要定义好组件的模板和逻辑,就可以通过组件工厂创建多个相同的组件并复用。
6、策略模式:Vue中的指令和过滤器就是策略模式的实现。开发者可以自定义指令和过滤器,然后根据需要进行选择和使用。
7、责任链模式:Vue中的事件机制就是责任链模式的实现。事件由组件树自下而上传递,直到被处理或到达根节点。
总之,Vue.js 项目中可以采用多种设计模式,根据具体的需求和场景选择合适的模式来提高代码的可维护性和扩展性。
五、vue项目开发可以使用到哪些设计模式,AI回答仅供参考
1、组件模式:Vue的核心思想就是组件化,将页面分割成独立、可复用的组件。因此,在Vue项目开发中,组件模式是不可避免的。
2、单向数据流模式:Vue中,父组件通过props属性向子组件传递数据,子组件通过$emit方法向父组件发送消息,实现了单向数据的流动。
3、事件订阅/发布模式:在Vue中,可以通过事件订阅/发布模式实现组件之间的异步通信。事件订阅者通过on方法订阅事件,事件发布者通过emit方法发布事件,从而实现组件之间的解耦。
4、生命周期模式:Vue组件生命周期包括created、mounted、updated、destroyed等,可以帮助开发者更好地掌控组件状态,实现组件的灵活控制。
5、路由模式:在Vue中,可以通过Vue-router实现路由模式,将应用分成多个页面,实现SPA(Single Page Application)单页应用程序,提高应用程序的用户体验。
6、状态管理模式:Vue应用程序的状态管理可以使用Vuex,实现多组件共享数据的功能。Vuex使用单向数据流模式,通过store来管理应用程序的状态,可以极大地简化应用程序的复杂度。
7、手势识别模式:在移动端开发中,可以使用手势识别模式,识别用户的手势操作,实现应用程序的交互效果。可以使用第三方库如Hammer.js等实现手势识别模式。
8、依赖注入模式:Vue.js中的依赖注入主要是通过provide/inject API来实现的,可以在祖先组件中注入依赖项,并在子组件中访问这些依赖项,提高代码的重用性和可测试性。
9、观察者模式:Vue.js利用观察者模式实现了响应式数据,即当数据发生变化时,会自动更新依赖于该数据的视图。
10、命令模式:通过使用Vue.js的自定义指令和事件监听机制,可以实现命令模式,将业务逻辑和组件行为分离,提高代码的可维护性。
总的来说,Vue.js强调组件化,通过一系列的设计模式来提高代码的可维护性、可重用性和可扩展性。
六、相关内容
6.1、工厂函数设计模式
工厂模式是一种设计模式,说白了就是一种简单的函数,这个函数可以创建对象,为它添加属性和方法,然后返回这个对象。
工厂函数设计模式是一种创建型设计模式,它通过使用工厂函数来创建不同类型的对象。
在这种模式中,我们定义一个单独的函数(称为工厂函数),它负责根据不同的条件和参数创建具有不同属性和行为的对象。工厂函数不仅可以创建新的对象,还可以重用已有的对象。
工厂函数设计模式有以下几个特点:
1. 简化对象的创建过程,使代码更容易维护和扩展。
2. 提高了代码的可读性和可重用性,使得创建对象的逻辑与其他代码分离。
3. 通过工厂函数来创建对象,可以在不改变现有代码的情况下轻松地扩展对象的类型和属性。
4. 工厂函数可以根据不同的参数和条件来创建不同类型的对象,提高了代码的灵活性和可定制性。
工厂函数设计模式在许多常见的编程语言中得到了广泛应用。例如,在JavaScript中,我们经常使用工厂函数来创建对象。
6.2、依赖注入设计模式
依赖注入(Dependency Injection,DI)是一种设计模式,用于将依赖关系从代码中分离出来,使得代码更加灵活、可测试和可维护。它通过外部化对象的创建和管理,从而使得依赖关系不再硬编码在代码中,而是在运行时通过注入来实现。
依赖注入的核心思想是将对象的创建和管理职责交给另外的对象(通常是一个容器或框架),从而让应用程序本身只需要关注核心业务逻辑的实现,而不必关注对象的创建和管理。
在依赖注入的实现中,通常会有三个角色:依赖注入容器、服务提供者和服务消费者。其中,容器负责管理对象的创建和生命周期,服务提供者负责实现具体的服务,而服务消费者则是使用这些服务的对象。
依赖注入还可以分为构造函数注入、属性注入和方法注入。在构造函数注入中,对象会在构造函数中声明依赖关系;在属性注入中,对象的依赖关系会通过属性进行注入;在方法注入中,则是在方法中声明依赖关系。
依赖注入在实际应用中可以帮助我们将应用程序解耦,提高代码的可维护性和可测试性,同时也可以帮助我们更好地管理和组织依赖关系。
【设计模式——依赖注入】_设计模式 依赖注入_Aseed40424991的博客-CSDN博客
七、设计模式demo
7.1、js实现单例模式
在JavaScript中,实现单例模式可以通过对象字面量或者闭包来实现。以下是两种常见的实现方式:
7.1.1、对象字面量实现单例模式
let singleton = {
name: 'Singleton Example',
getInstance: function () {
return singleton;
}
};
// 使用示例
let obj1 = singleton.getInstance();
let obj2 = singleton.getInstance();
console.log(obj1 === obj2); // true
7.1.2、闭包实现单例模式
let Singleton = (function () {
let instance;
function createInstance() {
let object = new Object({name: 'Singleton Example'});
return object;
}
return {
getInstance: function () {
if (!instance) {
instance = createInstance();
}
return instance;
}
};
})();
// 使用示例
let obj1 = Singleton.getInstance();
let obj2 = Singleton.getInstance();
console.log(obj1 === obj2); // true
在上面的示例中,闭包实现单例模式利用了闭包的特性来保持单例的状态和数据,只需要在第一次创建实例时才会执行createInstance
函数,之后每次调用getInstance
函数都直接返回创建的单例实例。
7.2、vue项目中实现单例模式
以下是一个简单的Vue项目中使用单例模式的代码示例:
// singleton.js
let instance;
class Singleton {
constructor() {
this.name = 'Singleton Example';
}
static getInstance() {
if (!instance) {
instance = new Singleton();
}
return instance;
}
}
export default Singleton;
// main.js
import Vue from 'vue'
import Singleton from './singleton';
Vue.config.productionTip = false;
// 在Vue实例中使用单例模式,确保只有一个实例
Vue.prototype.$singleton = Singleton.getInstance();
new Vue({
render: h => h(App),
}).$mount('#app');
在main.js
中,我们将Singleton
类作为一个单例实例挂载到Vue实例的原型中,这样在整个Vue项目中就只有一个Singleton
实例了,可以在不同时刻、不同组件中共享使用。在组件中使用时,只需要通过this.$singleton
来访问即可。
// MyComponent.vue
<template>
<div>{{ name }}</div>
</template>
<script>
export default {
created() {
console.log(this.$singleton.name); // Singleton Example
},
computed: {
name() {
return this.$singleton.name;
}
}
};
</script>
以上示例中,我们在MyComponent.vue
组件中访问$singleton
实例中的name
属性,并在组件创建时打印出了实例中的属性值。
vuex其实也是单例模式的实例,如果我们换一种表达,像这样定义一个单例模式也是实现组件传参的一种方法。
八、欢迎交流指正,关注我,一起学习。
九、参考链接
前端需要了解的9种设计模式 - 知乎