【檀越剑指大厂–设计模式】设计模式

一.设计原则

1.六大设计原则

  • 单一职责原则

  • 里氏替换原则

  • 依赖倒置原则

  • 接口隔离原则

  • 迪米特法则

  • 开闭原则

开闭原则
当应用的需求改变时,在不修改软件实体的源代码或者二进制代码的前提下,可以扩展模块的功能,使其满足新的需求。

里氏代换原则
子类可以扩展父类的功能,但不能改变父类原有的功能。也就是说:子类继承父类时,除添加新的方法完成新增功能外,尽量不要重写父类的方法。

依赖倒转原则
实现开闭原则的重要途径之一,它降低了客户与实现模块之间的耦合。

接口隔离原则
为了约束接口、降低类对接口的依赖性。

迪米特法则(最少知道原则)
为什么叫最少知道原则,就是说:一个实体应当尽量少的与其他实体之间发生相互作用,使得系统功能模块相对独立。

单一职责原则
控制类的粒度大小、将对象解耦、提高其内聚性。

2.单一职责好处/h4>
  • 类的复杂性降低,实现什么职责都有清晰明确的定义
  • 可读性提高,复杂性降低,那当然可读性提高了;
  • 可维护性提高,可读性提高,那当然更容易维护了!
  • 变更引起的风险降低,变更是必不可少的,如果接口的单一职责做得好,一个接口修改只对相应的实现类有影响,对其他的接口无影响,这对系统的扩展性、维护性都有非常大的帮助。

3.里氏替换/h4>

只只要父类能出现的地方子类就可以出现,而且替换为子类也不会产生主任何错误或异常,使用者可能根本就不需要知道是父类还是子类。但是,反过来就不行了,有子类出现的地方,父类未必就能适应.

  • 子类必须完全实现父类的方法
  • 子类可以有自己的个性
  • 覆盖或实现父类的方法时输入参数可以被放大 (重载和重写)
  • 覆写或实现父类的万方法时输出结果可以被缩小

4.里氏替换优劣/h4>

优点

  • 代码共享,减少创建类的工作量,每个子类都拥有父类的方法和属性;
  • 提高代码的重用性;
  • 子类可以形似父类,但又异于父类,“龙生龙,凤生凤,老鼠生来会打洞”是说子拥有父的“种”,“世界上没有两片完全相同的叶子”是指明子与父的不同;
  • 提高代码的可扩展性,实现父类的方法就可以“为所欲为”了,君不见很多开源框架的扩展接口都是通过继承父类来完成的;
  • 提高产品或项目的开放性。

缺点

  • 继承是侵入性的。只要继承,就必须拥有父类的所有属性和方法;

  • 降低代码的灵活性。子类必须拥有父类的属性和方法,让子类自由的世界中多了些约束;

  • 增强了耦合性。当父类的常量、变量和方法被修改时,必需要老
    虑子类的修改,而且在缺乏规范的环境下,这种修改可能带来非常糟糕的结果–大片的的代码需要重构。

5.依赖倒置

  • 高层模块不应该依赖低层模块,两者都应该依赖其抽象;

  • 抽象不应该依赖细节;

  • 细节应该依赖抽象。

IDriver司机开车(不区分车类型),ICar车跑(区分车类型),2个接口

6.依赖倒置的优点

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

7.依赖倒置的传递

  • 构造函数传递依赖对象

  • Setter方法传递依赖对象

  • 接口声明依赖对象

8.接口隔离

建立单一接口,不要建立臃肿庞大的接口。再通俗一点讲:接口尽量细化,同时接口中的方法尽量少。与单一职责原则不是相同的吗,接口隔离原则与单一职责的审视角度是不相同的,单一职责要求的是类和接口职责单一,注重的是职责,这是业务逻辑上的划分,而接口隔离原则要求接口的方法尽量少。例如一个接口的职责可能包含10个方法,这10个方法都放在一个接口中,并且提供给多个模块访问,各个模块按照规定的权限来访问,在系统外通过文档约束“不使用的方法不要访问”,按照单一职责原则是允许的,按照接口隔离原则是不允许的,因为它要求“尽量使用多个专门的接口”。专门的接口指什么是指提供给每个模块的都应该是单一接口,提供给几个模块就应该有几个接口,而不是建立一个庞大的臃肿的接口,容纳所有的客户端访问。

  • 接口要尽量小
  • 接口要高内聚
  • 定制服务
  • 接口设计有限度的

9.迪米特法则

一个对象应该对其他对象有最少得了解,如果两个类不必彼此直接通信,那么这两个类就不应当发生直接的相互作用;如果其中一个类需要调用另一个类的某一个方法的话,可以通过第三者转发这个调用。

该原则其根本思想,是强调了类之间的松耦合;类之间的耦合越弱,越利于复用,一个处在弱耦合的类被修改,不会对有关系的类造成波及。在类的结构设计上,每一个类都应当尽量降低成员的访问权限。

10.开闭原则

软件实体应该可以扩展,但不可修改。该原则是面向对象设计的核心所在,遵循这个原则可以带来面向对象技术所声称的可维护、可扩展、可复用、灵活性好。

设计人员必须对于他设计的模块应该对哪种变化封闭做出选择,必须先猜测出最有可能发生的变化种类,然后构造抽象来隔离那些变化。最初编写程序时假设变化不会发生,当变化发生时,就创建抽象来隔离以后发生的同类变化,拒绝不成熟的抽象。

二.具体模式

1.单例模式

确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。

主要优点

  • 单例模式提供了对唯一实例的受控访问。因为单例类封装了它的唯一实例,所以它可以严格控制客户怎样以及何时访问它。
  • 由于在系统内存中只存在一个对象,因此可以节约系统资源,对于一些需要频繁创建和销毁的对象单例模式无疑可以提高系统的性能。
  • 允许可变数目的实例。基于单例模式我们可以进行扩展,使用与单例控制相似的方法来获得指定个数的对象实例,既节省系统资源,又解决了单例单例对象共享过多有损性能的问题。

主要缺点

  • 由于单例模式中没有抽象层,因此单例类的扩展有很大的困难。
  • 单例类的职责过重,在一定程度上违背了“单一职责原则”。因为单例类既充当了工厂角色,提供了工厂方法,同时又充当了产品角色,包含一些业务方法,将产品的创建和产品的本身的功能融合到一起。
  • 现在很多面向对象语言(如Java、C#)的运行环境都提供了自动垃圾回收的技术,因此,如果实例化的共享对象长时间不被利用,系统会认为它是垃圾,会自动销毁并回收资源,下次利用时又将重新实例化,这将导致共享的单例对象状态的丢失。

适用场景

  • 系统只需要一个实例对象,如系统要求提供一个唯一的序列号生成器或资源管理器,或者需要考虑资源消耗太大而只允许创建一个对象。
  • 客户调用类的单个实例只允许使用一个公共访问点,除了该公共访问点,不能通过其他途径访问该实例。

2.单例模式的实现

3.工厂模式

  • 简单工厂模式
  • 工厂方法模式
  • 抽象工厂模式

这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式、在工厂模式中,我们在创建对对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。

抽象程度

简单工厂模式 < 工厂方法模式 < 抽象工厂模式。

角色分类

1、简单工厂模式:抽象产品、具体产品、工厂类。

2、工厂方法模式:抽象产品、具体产品、抽象工厂、具体工厂。

3、抽象工厂模式:抽象产品族、抽象产品、具体产品、抽象工厂、具体工厂。

简单工厂模式

  • 工厂类封装了创建具体产品对象的函数
  • 扩展性非常差,新增产品的时候,需要去修改工厂类。
  • 组成
    • 工厂类(ShoesFactory):工厂模式的核心类,会定义一个用于创建指定的具体实例对象的接口。
    • 抽象产品类(Shoes):是具体产品类的继承的父类或实现的接口。
    • 具体产品类(NiKeShoesAdidasShoesLiNingShoes):工厂类所创建的对象就是此具有产品实例。

工厂方法模式

定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。

抽象工厂模式

提供一个创建一系列相关或者相互依赖的对象的接口,无须指定他们具体的类。

来源:檀越剑指大厂

声明:本站部分文章及图片转载于互联网,内容版权归原作者所有,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2022年11月9日
下一篇 2022年11月9日

相关推荐