从零开始学设计模式(一):什么是设计模式

41 篇文章 1 订阅
23 篇文章 2 订阅

作者的其他平台:

| CSDN:https://blog.csdn.net/qq_41153943

| 掘金:https://juejin.cn/user/651387938290686

| 知乎:https://www.zhihu.com/people/1024-paper-96

| GitHub:https://github.com/JiangXia-1024?tab=repositories

本文大概5467字,读完共需10分钟

什么是设计模式

1995 年,GoF(Gang of Four,又叫四人帮)合作出版了《设计模式:可复用面向对象软件的基础》一书,共收录了 23 种设计模式,从此树立了软件设计模式领域的里程碑,称之为GoF设计模式或者设计模式GOF23。这23种设计模式并不是语法结构,而是对最基本的面向对象设计原则、面向对象的三大基本特征(封装性、继承性和多态性)以及类的与类之间的关联、组合关系进行的经验总结,从而来提高代码可复用性、可维护性、可读性、稳健性以及安全性。

设计模式的分类

这23种设计模式按照工作类型(干了什么)来划分可以分为创建型模式、结构型模式和行为型模式,每种类型有分别具体包括:

1、创建型模式:

单例模式(Singleton Pattern):是 Java 中最简单的设计模式之一。保证整个系统中一个类只有一个实例,并且提供一个访问该实例的全局访问点,实现这种功能的方式就叫单例模式。比如在一家人想要看电视,这时候家里只需要买一台电视机就可以了,没有必要每个人都买一台电视。如果一家看成一个系统,那么一台电视就是一个实例。这时候看电视可以有两种情况:一种是想看的时候才开,这就是懒汉式;一种是我一直开着想看的时候就看,这种就是饿汉式。

原型模式(Prototype Pattern):使用原型实例指定创建对象的种类,并且通过拷贝原型对象创建新的对象。原型模式实际上就是从一个对象再创建另外一个可定制的对象,而且不需要知道任何创建的细节。

工厂模式(Factory Pattern):提供一个用于创建对象的接口(工厂接口),让其实现类(工厂实现类)决定实例化哪一个类(产品类),并且由该实现类创建对应类的实例。应用最广的地方就是jdk中以及Spring和Struts框架中。而工厂模式又有三种简单工厂模式、工厂方法模式以及抽象工厂模式

抽象工厂模式(Abstract Factory Pattern):提供一个创建一系列相关或相互依赖的对象的接口,而无需指定它们具体的类。看起来和工厂模式很像,但有一些区别,那就是工厂模式是用来创建同一个产品的不同类型的,但是抽象工厂模式是用来创建不同类的产品。抽象工厂模式又称为Kit模式。

建造者模式(Builder Pattern):将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示,即一个房子可以分解成砖头、钢筋、石灰等组成,虽然房子是由这些组成的,但建筑的方式和方法以及这些组成的使用顺序都可以是不同的。

2、结构型模式:

适配器模式(Adapter Pattern):把一个类的接口变换成客户端所期待的另一种接口,从而使原本接口不匹配而无法在一起工作的两个类能够在一起工作。就好比你的苹果手机和安卓手机的数据线不一样,通过一个转换接口能够使得两个数据线在安卓/苹果手机上都能够使用。

桥接模式(Bridge Pattern):基于类的最小设计原则,使用封装、聚合及继承等行为,把抽象与行为实现分离开来,从而可以保持各部分的独立性以及应对他们的功能扩展。

装饰器模式(Decorator Pattern):是继承关系的一个替代方案,通过使用对象之间的关联关系来取代类之间的继承关系,从而能够动态的给一个对象添加一些额外的功能。

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

外观模式(Facade Pattern):隐藏系统的复杂性为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用

享元模式(Flyweight Pattern):运用共享技术来有効地支持大量细粒度对象的复用。它通过共享已经存在的又橡来大幅度减少需要创建的对象数量、避免大量相似类的开销,从而提高系统资源的利用率.

代理模式(Proxy Pattern):为其他对象提供代理以控制这个对象的访问。代理模式分为动态代理、静态代理、还有CGLIB动态代理,也是java中使用最为广泛的一种设计模式。

行为型模式:

模版方法模式(Template Pattern):父类就是模板,它包含很多不同的业务的重复代码,但是这些方法都是交由字类来实现。即父类只定义一个处理步骤,但是具体的实现交给对应子类来实现。

命令模式(Command Pattern):是将各种请求通过命令的方式封装成对象,请求和响应都以命令对象进行交互。请求先以命令的形式被封装在对象中,然后传给调用的对象。调用对象再寻找可以处理该命令的合适的执行对象,并把该命令传给相应的执行对象,执行对象再执行命令。这样方便将命令对象进行储存、传递、调用、增加与管理。

迭代器模式(Iterator Pattern):提供了一种方法顺序访问一个聚合对象中的各个元素,而又无需暴露该对象的内部实现,这样既可以做到不暴露集合的内部结构,又可让外部代码透明地访问集合内部的数据

观察者模式(Observer Pattern):定义一系列对象之间的一对多关系,当一个对象改变、更新状态时,依赖它的都会收到通知改变或者更新。

中介者模式(Mediator Pattern):中介者模式定义了一个中介对象来封装一系列对象之间的交互关系。中介者使各个对象之间不需要显式地相互引用,从而使耦合性降低,而且可以独立地改变它们之间的交互行为。比如租房中介是一种中介,如果我们想要租房可以通过中介和房东沟通,这时候其实并不需要知道对方是谁,也并不需要面对面,类似于电话、QQ、微信等等都是中介,能大大降低了沟通的复杂性。

备忘录模式(Memento Pattern):备忘录模式是指在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可以将该对象恢复到原先保存的状态。这里的备忘录其实和我们常见的用来提醒自己做某事的备忘录不太一样,这里的备忘录模式更类似于玩游戏的存档,或者是进行开发的代码托管工具,比如git。

解释器模式(Interpreter Pattern):是一种按照规定的语法进行解析的模式。通过给定一种语言,并且定义它的一种表示,再定义一个解释器,解释器通过使用表示来解释语言中的句子。

状态模式(State Pattern):允许一个对象在其内部状态改变时改变它的行为。状态模式将与特定状态相关的行为局部化,并且将不同状态的行为分割开来。比如我们打球的时候一开始状态很好,打球很猛,打了一会就比较累了,就跑的有点慢了,我们的身体状态能够改变我们的行为了。

策略模式(Strategy Pattern):对于一组算法,可以将每一种算法都封装到具有共同接口的独立的类中,从而使得它们可以相互替换。比如我们定义一个具有说的方法的接口,那么在调用的时候具体说什么则由具体的实现来实现,比如狗、猫、人对象调用的时候都是不同的实现。

职责链模式(Chain of Responsibility Pattern):为了避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。在这种模式中,通常每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推。

访问者模式(Visitor Pattern):封装一些作用于某种数据结构的各元素的操作,它可以在不改变数据结构的前提下定义作用于这些元素的新的操作。就好比一个记者(访问者),采访一个明星,可以通过对明星的采访和他的回答,写新闻稿来描述和报道这个事情(新的操作)。

设计模式的六大基本原则

设计模式中的6大基本原则(五原则一法则)是为了在应用开发中能够拥抱变化,也就意味着在后续升级、维护过程中不破坏系统稳定性并保持高可扩展性、高内聚、低耦合,让项目经历多个版本后依然保持清晰、灵活、稳定的系统结构。

总原则:开闭原则(Open Close Principle,OCP)

开闭原则就是说对扩展开放,对修改关闭。在程序需要进行拓展的时候,不能去修改原有的代码,而是要扩展原有代码,实现一个热插拔的效果。所以一句话概括就是:为了使程序的扩展性好,易于维护和升级。想要达到这样的效果,我们需要使用接口和抽象类等。

1、单一职责原则**(Single Responsibility Principle, SRP)**

不要存在多于一个导致类变更的原因,也就是说每个类应该实现单一的职责,如若不然,就应该把类拆分。

一个类只负责一个功能领域中的相应职责,或者可以定义为:就一个类而言,应该只有一个引起它变化的原因。

这就好比在一个工厂里,最好每个人都只负责一件事情,比如保洁负责保洁、保安负责保安,锅炉工负责烧锅炉等等。不可能一个人既要当保安,又要负责公司的保洁。同理在软件系统中,一个类(大到模块,小到方法)承担的职责越多,它被复用的可能性就越小,而且一个类承担的职责过多,就相当于将这些职责耦合在一起,当其中一个职责变化时,可能会影响其他职责的运作,因此要将这些职责进行分离,将不同的职责封装在不同的类中,即将不同的变化原因封装在不同的类中,如果多个职责总是同时发生改变则可将它们封装在同一类中。

单一职责原则是实现高内聚、低耦合的指导方针,它是最简单但又最难运用的原则,需要设计人员发现类的不同职责并将其分离,而发现类的多重职责需要设计人员具有较强的分析设计能力和相关实践经验。

**2、里氏替换原则(Liskov Substitution Principle,**LSP)

里氏代换原则中说,任何基类可以出现的地方,子类一定可以出现。里氏代换原则是继承复用的基石,只有当衍生类可以替换掉基类,软件单位的功能不受到影响时,基类才能真正被复用,而衍生类也能够在基类的基础上增加新的行为。里氏代换原则是对“开-闭”原则的补充。实现“开-闭”原则的关键步骤就是抽象化。而基类与子类的继承关系就是抽象化的具体实现,所以里氏代换原则是对实现抽象化的具体步骤的规范。

里氏替换原则中,子类对父类的方法尽量不要重写和重载。因为父类代表了定义好的结构,通过这个规范的接口与外界交互,子类不应该随便破坏它。

3、依赖倒转原则(Dependence Inversion Principle,DIP)

依赖倒转原则是开闭原则的基础,具体内容:面向接口编程,依赖于抽象而不依赖于具体。写代码时用到具体类时,不与具体类交互,而与具体类的上层接口交互。

采用依赖倒置原则可以减少类间的耦合性,提高系统的稳定性,降低并行开发引起的风险,提高代码的可读性和可维护性。

4、接口隔离原则(Interface Segregation Principle,ISP)

接口隔离原则的意思是:每个接口中不存在子类用不到却必须实现的方法,如果不然,就要将接口拆分。使用多个隔离的接口,比使用单个接口(多个接口方法集合到一个的接口)要好。

5、迪米特法则(Demeter Principle,DP)

迪米特法则又叫最少知道原则就是说:一个类对自己依赖的类知道的越少越好。也就是说无论被依赖的类多么复杂,都应该将逻辑封装在方法的内部,通过public方法提供给外部。这样当被依赖的类变化时,才能最小的影响该类。

最少知道原则的另一个表达方式是:只与直接的朋友通信。类之间只要有耦合关系,就叫朋友关系。耦合分为依赖、关联、聚合、组合等。我们称出现为成员变量、方法参数、方法返回值中的类为直接朋友。局部变量、临时变量则不是直接的朋友。我们要求陌生的类不要作为局部变量出现在类中。

6、合成复用原则(Composite Reuse Principle,DRP)

合成复用原则又叫组合/聚合复用原则。它要求在软件复用时,要尽量先使用组合或者聚合等关联关系来实现,其次才考虑使用继承关系来实现。

面向对象六大原则的特点可以基本总结如下:

开闭原则:软件中的对象(类,模块,函数等)应该对于扩展是开放的,但是对于修改是关闭的。

单一职责原则:让每个类只专心处理自己的方法。

里式替换原则:子类可以去扩展父类,但是不能改变父类原有的功能。

依赖倒置原则:应该通过调用接口或抽象类(比较高层),而不是调用实现类(细节)。

接口隔离原则:把接口分成满足依赖关系的最小接口,实现类中不能有不需要的方法。

迪米特原则:高内聚,低耦合。

合成复用原则:优先使用组合或者聚合,其次才考虑使用继承关系。

总结

本文主要对23种设计模式以及设计模式中的六大基本原则进行了简单的介绍,后续将对23种设计模式进行详细展开。

有任何问题和疑问欢迎交流、讨论!扫描下方二维码获取海量免费学习资源!

图片

相关推荐:

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值