设计模式内容分享(二十四):什么是设计模式

本文介绍了设计模式的概念、三大类别(创建型、结构型、行为型)、面向对象原则的应用,以及设计模式在软件开发中的重要性,包括提高代码复用性、可维护性和可扩展性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

设计模式简介

为什么分为三大类

全局观

创建型模式

结构型模式

行为型模式

设计模式的重要性

设计模式的目的  

设计模式7大原则 

结语


ea2580cff1ac4b1f991d667b014e3331.png

设计模式简介

设计模式是程序员在面对同类软件工程设计问题所总结出来的有用的经验, 模式不是代码,而是某类问题的通用解决方案,设计模式(Design pattern) 代表了最佳的实践。这些解决方案是众多软件开发人员经过相当长的一段时 间的试验和错误总结出来的。

设计模式的本质提高 软件的维护性,通用性和扩展性,并降低软件的复杂度。

设计模式(Design Pattern)是前辈们对代码开发经验的总结,是解决特定问题的一系列套路。它不是语法规定,而是一套用来提高代码可复用性、可维护性、可读性、健壮性以及安全性的解决方案。

正确使用设计模式具有以下优点:

  • 可以提高程序员的思维能力、编程能力和设计能力
  • 使程序设计更加标准化、代码编制更加工程化,使软件开发效率大大提高,从而缩短软件的开发周期。
  • 使软件的代码可重用性高、可读性强、可靠性高、灵活性好、可维护性强。

最重要的是抽象能力,设计模式是对面对对象设计原则的实际运用

面向对象特点

  • 封装:隐藏内部实现

  • 继承:复用现有的代码

  • 多态:改写对象的行为

面向对象设计原则

  1. 依赖倒置原则:针对接口编程,依赖于抽象而不依赖于具体,抽象(稳定)不应依赖于实现细节(变化),实现细节应该依赖于抽象,因为稳定态如果依赖于变化态则会变成不稳定态。

  2. 开放封闭原则:对扩展开放,对修改关闭,业务需求是不断变化的,当程序需要扩展的时候,不要去修改原来的代码,而要灵活使用抽象和继承,增加程序的扩展性,使其易于维护和升级,类、模块、函数等都是可以扩展的,但是不可修改。

  3. 单一职责原则:一个类只做一件事,一个类应该仅有一个引起它变化的原因,并且变化的方向隐含着类的责任。

  4. 里氏替换原则:子类必须能够替换父类,任何引用基类的地方必须能透明地使用其子类的对象,开放关闭原则的具体实现手段之一。

  5. 接口隔离原则:接口最小化且完备,尽量少public来减少对外交互,只把外部需要的方法暴露出来。

  6. 最少知道原则:一个实体应该尽可能少地与其他实体发生相互作用。

  7. 将变化的点进行封装,做好分界,保持一侧变化,一侧稳定,调用侧永远稳定,被调用测内部可以变化。

  8. 优先使用组合而非继承,继承为白箱操作,而组合为黑箱,继承某种程度上破坏了封装性,而且父类与子类之间耦合度比较高。

  9. 针对接口编程,而非针对实现编程,强调接口标准化

总结:没有一步到位的设计模式,刚开始编程时不要把太多精力放到设计模式上,需求总是变化的,刚开始着重于实现,一般敏捷开发后为了应对变化重构再决定采取合适的设计模式。

为什么分为三大类

全局观

        大家都知道设计模式可以根据目的分为三大类,分别是创建型模式、结构型模式、行为型模式

        那么为什么这么分呢?下面说一下笔者的理解

        创建型模式:主要用于处理对象的创建,实例化对象。但是,这可能会限制在系统内创建对象的类型或数目

        结构型模式:处理类或对象间的组合。它将以不同的方式影响着程序,允许在补充写代码或自定义代码的情况下创建系统,而且具有重复使用性和应用性能

        行为型模式:描述类或对象怎样进行交互和职责分配。影响系统的状态、行为流,简化、优化并且提高应用程序的可维护性

4b8eef7869d64389a7431cd7c9c682ea.png

创建型模式

1、简单工厂

        当我们的程序在实例化对象时,如果输入条件不一样,产生的对象也不一样,那么我们可以考虑使用简单工厂对不同的实例进行统一封装

2、工厂方法

        它是针对简单工厂的改进版,添加了对ProductManager的抽象

3、抽象工厂

        这个是最复杂的工厂模式,它用来生成一个产品线上的所有产品,我们假设一个产品线上包括多个产品,不同的产品线上的产品个数是一样的,这样我们需要一个针对产品线的抽象,并且很显然不同产品线上的产品是不可能混到一起的

4、单例模式

        这是比较好理解的一个模式,从字面上说,就是程序在运行的过程中,希望在任意时刻,都只保留某个对象的唯一实例

5、建造者模式

        对于一些复杂对象来说,它可以分成多个不同的部分,在实例化时,不同部分之间实例化的顺序,有时会有严格的限制,这时我们就可以使用建造者模式了

6、原型模式

        我们在程序运行过程中,当需要有新的实例对象时,有时并不希望是从头创建一个对象,而是希望新的实例的状态和某个已存在的实例保持一致,这就是原型模式发挥作用的地方

结构型模式

1、适配器模式

        当我们已经开发出一个模块,有一套清晰的接口,并且模块正在被某个功能使用(意味着模块接口改变的可能性不高),这是如果有另外一个功能也需要使用这个模块的功能,但是对应的是一套完全不同的接口,这时适配器就可以发挥作用了

2、装饰模式

       假如我们已经开发了一套功能,然后根据需求,需要增加一些子功能,而且这些子功能是比较分散比较时可以增删的,这时如果直接修改接口,那么会造成接口功能复杂并且不稳定,针对这种情况,我们可以使用装饰模式

3、桥接模式

        面向对象提倡的几个最佳实践包括:1)封装变化;2)面向接口编程;3)组合优于继承;4)类的职责尽量单一。桥接器完美的体现了这些,通过创建型模式,我们可以很好地达到面向接口编程的目标,也就是说我们在程序中各变量的声明类型是接口类型或者抽象类,而具体的实现类型则由不同的设计模式使用不同方式指定

3、享元模式

        当我们系统中需要使用大量的小对象,但我们又不希望将所有的小对象都创建出来时,可以考虑使用享元模式,它会抽取小对象中的公共部分,将其封装为基类,然后针对不同条件创建小对象,同时在对象池中维护这些小对象,客户在需要使用小对象时,首先在对象池中查找,如果存在,直接返回。对于小对象中“个性”的部分,由调用小对象的客户端进行维护

4、组合模式

        当我们的对象结构中存在“父子”关系时,可以考虑使用组合模式

5、代理模式

        在编写程序时,有时我们希望使用某个对象或者模块的功能,但是因为种种原因,我们不能直接访问,这时就可以考虑使用代理模式

6、装饰模式

        如果我们的程序需要深入调用某个模块的内部,但我们又不想和模块过紧耦合,这时可以考虑使用装饰模式,来对外部封装内部子系统的实现。简单的装饰可能和代理在某种程度上很相似。

行为型模式

1、职责链模式

        如果完成一项业务,需要很多步相关操作,但是如果将这些操作完全封装到一个类或者方法里面,又违背了单一职责的原则。这时我们可以考虑使用职责链模式

2、命令模式

        命令模式将发出命令和执行命令很好的区分开来,当我们执行某项业务时,客户端只需要构造一个请求,而不必关心业务实现的具体细节,即构造请求和业务实现是独立的

3、解释器模式

        如果我们的系统中有些特定的问题反复出现,我们想要对这些问题进行抽象,那应该如何做?试想一下,当我们写完代码后,是如何进行编译的?无论对C#还是Java,它们的编译器都会读取我们所写的每一行代码,并作出相应的解释。我们可以部分认为,编译器中存储了任何组合的语句,类似于C中的typedef。解释器做的就是类似的事情,它将具有通用性的问题进行抽取,对其解决方案进行综合处理

4、迭代器模式

        访问者模式,针对的是存储在一起的不同类型的对象集合,如何进行遍历处理,那么针对存储在一起的相同类型的对象集合,我们应该如何进行遍历呢?迭代器模式可以帮我们做到

5、中介者模式

        如果我们的系统中有多个对象,彼此之间都有联系,那这是一个对象之间耦合很高的系统,我们应该如何优化呢?我们可以建立一个知道所有对象的“对象”,在它内部维护其他对象之间的关联,这就是中介者模式

6、备忘录模式

        当我们的系统中存在这样一种对象,它的属性很多,在某些情况下,它的一部分属性是需要进行备份和恢复的,那应该如何做?谈到备份和恢复,我们立刻想到可以使用原型模式,但那是针对所有属性的,备忘录模式可以很好地解决这里的问题

7、观察者模式

         当我们的系统中,存在一个业务A,有其他多个业务都需要关注业务A,当它的状态发生变化时,其他业务都需要做出相应操作,这时我们可以使用观察者模式

8、状态模式

        当我们的系统中的对象,需要根据传入的不同参数,进行不同的处理,而且传入参数的种类特别多,这时在方法内部会产生大量的if语句,来确定方法的执行分支。那么如何消除这些if语句呢?状态模式可以帮我们做到

9、策略模式

        当我们的系统中,针对某项业务有多个算法时,如何对这些算法进行管理,我们可以考虑使用策略模式,它主要是针对一组可以提取相同接口的算法进行管理

10、模板方法模式

        继承是面向对象的一大核心,而模板方法就是对继承的完美体现。对于某项业务来说,我们可以根据通用的流程,设计其方法骨架,针对不清晰或者不明确的地方,以抽象方法的方式来处理,然后根据不同的子业务,创建不同的子类,在子类中,实现那些抽象方法

11、访问者模式

        当我们有一个对象集合,集合中的元素类型是不一样的,但类型是相对固定的,例如只有3种不同的类型,但是可能有30个元素。如果我们希望对集合中的所有元素进行某种操作,从接口的角度来看,由于类型不一致,我们很难通过一个统一的接口来遍历集合元素并对其进行操作。这时我们可以考虑使用访问者模式,它将获取某个元素和对元素进行操作进行了分离

设计模式的重要性

软件工程中,设计模式(design pattern)是对软件设计中普遍存在(反复出现) 的各种问题,所提出的解决方案。这个术语是由埃里希·伽玛(Erich Gamma)等人 在1990年代从建筑设计领域引入到计算机科学的

设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结,代表了最佳的实践, 通常被有经验的面向对象的软件开发人员所采用。

设计模式的本质是面向对象设计原则的实际运用,是对类的封装性、继承性和多态性以及类的关联关系和组合关系的充分理解。

设计模式是主要针对面向对象语言提出的一种设计思想,主要是提高代码可复用性,抵御变化,尽量将变化所带来的影响降到最低。

设计模式的目的  

编写软件过程中,程序员面临着来自耦合性,内聚性以及可维护性,可扩展性,重用性,灵活性等多方面的挑战,设计模式是为了让程序(软件),具有更好代码。

设计模式是为了让软件(程序),具有更好代码重用性、可读性、可扩展性、可靠性,使程序高内聚、低耦合。

1.代码重用性

2.可读性

3.扩展性

4.可靠性(新增功能对原来功能不影响)

5.高内聚 低耦合    

设计模式7大原则  

1d4389e021dd4a36a4a891f98fae8a5d.png

结语

        在学习一个东西之前,有一个全局观是很重要的,有助于你后面的学习。上文只是对设计模式有一个小小的介绍,具体详细的大家可以去看设计模式详解专栏

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

之乎者也·

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

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

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

打赏作者

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

抵扣说明:

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

余额充值