Giter Site home page Giter Site logo

design-patterns's Introduction

设计模式示例代码

[TOC]

一、创建型设计模式

创建型模式(Creational Patterns):关注如何创建对象,以适应不同的场景和需求。

1.1 工厂模式

工厂模式(Factory Pattern)是一种常见的创建型设计模式,旨在通过提供一个统一的接口来创建对象,而不暴露对象的创建逻辑。它允许将对象的实例化过程从客户端代码中分离出来,从而使代码更加灵活、可扩展和易于维护。

工厂模式有几种不同的变体,包括简单工厂模式、工厂方法模式和抽象工厂模式。

1.1.1 简单工厂模式

简单工厂模式(Simple Factory Pattern)并不是一个标准的设计模式,但它通常作为工厂模式的起点进行讨论。在简单工厂模式中,有一个工厂类负责根据给定的参数来创建对象(换言之,一个工厂类负责多个产品类)。客户端只需要向工厂传递合适的参数,而无需关心具体的对象创建过程。但这种模式有一定的局限性,因为当需要添加新类型的产品时,必须修改工厂类的代码,违背了开闭原则(Open-Closed Principle)。

适用场景:

  • 产品类较少,且产品对象创建逻辑简单

1.1.2 工厂方法模式

工厂方法模式(Factory Method Pattern)通过将对象的创建委托给子类来解决简单工厂模式的限制性问题。每个产品类都有对应的工厂类,而这些工厂类继承自一个共同的抽象工厂类或接口。客户端代码通过调用工厂方法来创建对象,具体创建哪种对象由子类决定。这样,当需要添加新的产品类型时,只需要添加一个新的具体产品类和对应的工厂类,而无需修改现有的代码。

适用场景:

  • 产品类较多
  • 产品对象的创建逻辑相对复杂
  • 各产品的对象创建逻辑不同

1.1.3 抽象工厂模式

抽象工厂模式(Abstract Factory Pattern)提供了一种创建一系列相关或依赖对象的接口,而无需指定具体实现类。它通过引入抽象工厂和一组抽象产品类来实现。每个具体的工厂类都负责创建一族产品,并且这些产品之间有一定的相关性。客户端通过使用抽象工厂接口和抽象产品类,可以创建需要的产品族,而不用关心具体的实现细节。

适用场景:

  • 需要创建一系列相关或依赖的产品类

1.2 单例模式

单例模式(Singleton Pattern)是一种创建型设计模式,它确保一个类只有一个实例,并提供一个全局访问点来访问这个唯一实例。这意味着在整个程序运行期间,无论在何处访问该类,都只会得到同一个实例对象。单例模式在很多场景中都有用处,例如需要控制资源访问、配置管理、日志记录、线程池、数据库连接等。

单例模式有三种常见的实现方案:饿汉式(Eager Initialization)、懒汉式(Lazy Initialization)、双重检查锁定(Double-Checked Locking)

1.2.1 饿汉式-单例模式

在类加载时就创建实例,无论是否使用都会创建。这种方式简单直接,不存在多线程并发问题,适用于实例较小且在程序运行期间一直需要被使用的情况。

适用场景:

  • 实例较小
  • 实例使用频繁:因为不需要考虑并发问题,所以在获取实例的性能上占优势

1.2.2 懒汉式-单例模式

在需要使用的时候才去创建实例。懒汉式单例模式可以避免资源浪费,但需要注意多线程环境下的并发问题。

适用场景:

  • 实例较大,创建和初始化需要花费较多的资源和时间
  • 实例不一定会被使用

1.2.3 双重检查锁定-单例模式

在懒汉式的基础上做了进一步的优化:实例创建完成后无需加锁,提高访问性能

适用场景:

  • 实例较大,创建和初始化需要花费较多的资源和时间
  • 实例使用频繁:在多线程环境下频繁获取实例,需要通过双重检查锁定来提高性能

1.3 原型模式

原型模式(Prototype Pattern)是一种创建型设计模式,旨在通过克隆(复制)现有对象来创建新对象,以减少对象创建的开销,并且避免昂贵的资源初始化过程。它适用于那些对象创建过程较为复杂且需要重复创建相似对象的情况。

适用场景:

  • 对象创建过程较为复杂且需要重复创建相似对象

1.4 建造者模式

建造者模式(Builder Pattern)是一种创建型设计模式,通常用于创建具有多个组成部分的复杂对象。建造者模式的优势在于构建复杂对象时的灵活性和可扩展性。

适用场景:

  • 对象组成部分比较多,构建过程十分复杂

    Spring中的BeanDefinition就是一种复杂的类,为此Spring提供了BeanDefinitionBuilder

  • 构建过程存在可选部分:建造者模式可以很好地支持增量构建对象

二、结构型设计模式

结构型模式(Structural Patterns):关注如何组合类和对象以形成更大的结构,并提供新的功能。

2.1 适配器模式

适配器模式(Adapter Patterns)通常用解决接口的兼容问题。

适用场景:

  • 重用现有功能: 当你希望重用一个已有的类(通常无法直接修改这种类,例如第三方库中的类),但其接口不符合你的需求时,适配器模式可以将该类的功能整合到你的代码中,使之符合你的需求。
  • 统一接口规范: 当你想要确保多个类都遵循相同的接口规范,但其具体实现不同,适配器模式可以帮助你通过适配器统一它们的接口。

2.2 装饰器模式

装饰器模式(Decorator Pattern)通常用于增强类的功能。

适用场景:

  • 动态地为对象添加新的功能或职责,而不改变其接口。

    Spring框架中的AOP实际上就是使用了装饰器模式来实现

与适配器模式的对比:

适配器 装饰器
关注点 在接口不兼容的情况下,使不同的类能够一起工作 在不改变接口的情况下,增强类的功能

2.3 外观模式

外观模式(Facade Pattern)旨在提供一个简化的接口,用于访问底层系统的一组接口或一组相关的类。

外观模式的核心**是创建一个高级别的接口,这个接口封装了底层系统的许多复杂操作。通过这个接口,客户端可以更轻松地与系统进行交互,而不必直面系统底层的复杂性。

适用场景:

  • 简化复杂系统接口:当一个系统包含许多子系统或组件,并且客户端需要与这些复杂性交互时,外观模式可以提供一个简化的接口,减少客户端代码的复杂性。
  • 解耦客户端和子系统:外观模式可以帮助将客户端与子系统之间的耦合降低到最低限度,因为客户端只需要与外观类进行交互,而不需要直接与各个子系统进行通信。
  • 封装第三方库或接口:如果你在项目中使用了某个复杂的第三方库或接口,可以使用外观模式将其封装起来,以便客户端更容易使用,并且在未来需要切换库或接口时,只需在外观类中进行修改。
  • 子系统独立性:当不同的子系统之间需要保持独立性,但某些功能需要同时协同工作时,外观模式可以提供一个统一的接口来处理这些功能。
  • 系统维护和扩展:如果系统中的某些部分可能会发生变化,但你希望尽量减少对客户端的影响,可以使用外观模式来隔离这些变化,从而使维护和扩展更加容易。
  • 新旧系统整合:当你在现有系统中集成新系统或功能时,外观模式可以用于封装整合过程,以便平稳过渡并减少风险。

2.4 桥接模式

桥接模式(Bridge Pattern)旨在将抽象部分和实现部分分离,使它们可以独立地进行变化,而不会相互影响。这种模式通过将两种维度的变化分离,帮助我们更灵活地构建复杂的系统。

适用场景:

  • 多维度变化:当一个类有多个变化维度,且这些维度可以独立变化时,可以使用桥接模式来将这些维度分离。这有助于避免类爆炸问题,即由于不同组合产生的类的数量急剧增加而导致的代码复杂性。

2.5 组合模式

组合模式(Composite Pattern)旨在允许客户端以一致的方式处理单个对象和对象组合。它通过将对象组织成树状结构,使得单个对象和组合对象之间的区别被模糊化。

实际应用中,组合模式常见于图形界面、文件系统、组织架构等领域。例如,一个文件系统可以由文件和文件夹组成,其中文件夹可以包含文件和其他文件夹,这就是一个典型的组合模式。

三、行为型设计模式

行为型模式(Behavioral Patterns):关注对象之间的通信和责任分配,以更好地组织和管理代码。

3.1 观察者模式

观察者模式(Observer Pattern)旨在处理对象之间存在的一对多关系,使得当一个对象的状态变化时,其所有观察者能够自动收到通知并进行相应的操作。

适用场景:

  • 观察者模式适用于需要在对象间建立动态、松耦合的一对多关系,以便一个对象的状态变化能够自动通知并影响其他多个对象的情况,实现对象间的分离和协作。常见的适用场景包括事件处理、发布-订阅系统、图形界面的用户交互、实时监控系统以及模型-视图分离等。

Spring的事件机制就是基于观察者模式实现的

3.2 策略模式

策略模式(Strategy Pattern)允许你定义一系列算法或方法,并使它们能够在运行时互相替换,而不影响客户端的代码。这种模式可以帮助你在不同情境下选择不同的算法或行为,从而使你的程序更加灵活和可维护。

适用场景:

  • 多重算法选择: 当你有多种不同算法或行为可供选择,并且需要在运行时根据情况选择其中之一时,策略模式是一个很好的选择。这样可以避免在代码中使用大量的条件语句。

  • 动态切换行为: 当你需要在运行时根据不同情况切换对象的行为时,策略模式提供了一种灵活的方式,允许你在不影响客户端代码的情况下进行切换。

  • 避免代码重复: 如果你发现自己在不同的地方使用相似的代码来处理不同情况,可以将这些相似的部分提取为不同的策略类,以避免代码重复。

    个人理解:应该是比Method更高一层的抽象,换言之,当一个复杂的处理流程无法简单的抽象成一个方法,可以考虑抽象为一个策略。

  • 类的扩展性: 策略模式可以帮助你将算法或行为的变化局限在单独的策略类中,从而使类的扩展性更强,不必修改已有代码。

  • 保持代码整洁: 策略模式能够使代码更具可读性和可维护性,因为不同的策略被封装在不同的类中,使得每个类的职责更加清晰。

  • 单一职责原则: 策略模式有助于遵循单一职责原则,因为每个策略类只关注一种算法或行为,从而降低了类的复杂性。

3.3 命令模式

命令模式(Command Pattern)旨在将一个请求或操作封装成一个对象,从而使得可以参数化客户端对象,将操作排入队列、记录日志、撤销操作,或者在不同的上下文中进行调用。这种模式将调用者与接收者解耦,使得系统更加灵活和可扩展。

3.4 模板方法模式

模板方法模式(Template Method Pattern)主要用于定义一个算法的框架,同时允许子类在不改变算法结构的情况下重新定义算法的某些步骤。这种模式有助于促进代码的重用和灵活性。

模板方法模式的核心**是将一个算法分解为一系列步骤,其中某些步骤可以由子类实现。

Spring中AbstractApplicationContext类的refresh方法就应用了模板方法模式

3.5 责任链模式

责任链模式(Chain of Responsibility Pattern)用于处理一个请求可能会被多个对象处理的情况。在责任链模式中,将多个处理对象组成一个链,并在链上传递请求,直到有一个处理对象能够处理该请求为止。

这种模式的主要目的是将请求的发送者和接收者解耦,使得多个对象都有机会处理请求,而且能够在运行时动态地决定哪个对象将处理请求。

适用场景:

  • 责任链模式的一个典型应用场景是在日常工作流程中,例如审批流程。每个审批者都是一个处理者,他们按照一定的顺序处理请求(审批请求),并决定是否继续传递请求给下一个审批者。

design-patterns's People

Contributors

xiaozhengyu avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.