设计模式——设计原则

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

  1. 如何理解单一职责原则?

    一个类只负责完成一个职责或者功能,不要设计大而全的类,要设计力度小,功能单一的类单一职责原则是为了实现代码高,内聚低和提高代码的复用性,可读性,可维护性。

  2. 如何判断类的职责是否足够单一?

    从场景应用不同阶段的需求背景,不同的业务层面,对同一个类的职责是否单一可能会有不同的判定结果。实际上,一些立面的判断指标更具有指导意义,比如出现下面情况,这些有可能说明设计类不满足单一职责原则:
    <1>类中的代码行数、函数或者属性过多。
    <2>依赖的其他类过多,或者依赖类的其他类过多。
    <3>私有方法过多。
    <4>比较难给那起一个合适的名字。
    <5>类中大量的方法都是集中操作类中的某几个属性。

  3. 类的职责,是否设计的越单一越好?

    单一职责原则通过避免设计大而全的类,避免将不相关的功能耦合在一起来提高类的内聚性。
    同时类职责单一类依赖的和被依赖的其他类也会变少,减少代码的耦合性,以此来实现代码的高内聚低和,但是拆分过细,实际上会适得其反,影响可维护性。

二、开闭原则(Open Closed Principle,OCP)

  1. 对扩展开放,对修改关闭的理解。

    添加一个新的功能,应该是通过在已有的代码基础上扩展代码(新增模块类,方法,属性等)。而非修改已有代码(修改模块、类、方法、属性等)方式来完成。
    开闭原则并不是说完全杜绝修改,而是以最小的修改代码的代价来完成新功能的开发。一样的代码改动在初代码力度下可能被定为修改,在细代码力度下可能又被认定为扩展。

  2. 如何做到对扩展开放,对修改关闭?

    时刻具备扩展意识,抽象意识,封装意识,在写代码的时候要多花点时间思考一下这段代码未来可能有哪些需求变更。如何设计代码结构事先留好扩展点。以便在未来需求变更的时候再不改代码整体结构,做到对小代码改动的情况下将新的代码灵活的插入到扩展点上。
    很多设计原则,设计思想,设计模式都是以高高代码的扩展性为最终目的。
    常见的提高代码扩展性方法有多态依赖注入,基于接口而非实现编程以及大部分的设计模式。

三、里氏替换原则(Liskv Substitution Principle,LSP)

  1. 如何理解里氏替换原则?

    对对象能够替换程序中父类对象出现的任何地方,并且保证原来程序的逻辑行为不变及正确性不被破坏。
    里式替换原则,是用来指导继承关系中子类该如何设计的一个原则。最核心的理解:“Design By Contact”,按照协议来设计。
    父类定义了函数的约定(或者叫做协议),即子类可以改变函数的内部实现逻辑,但不能改变函数原有的“约定”(行为约定),这里的行为约定包括:函数声明要实现的功能;对输入输出异常的约定,;甚至包括注释中所罗列的任何特殊说明。

  2. 多态和里氏替换的区别。

    多态和里式替换有点类似,但关注的角度不一样,多态是面向对象编程中一大特性,语法,代码实现思路。里式替换是一种设计原则,用来指导继承关系中子类该如何设计的,子类设计要保证在替换父类的时候不改变原有程序的逻辑以及不破坏原有程序的正确性。

  3. 哪些代码违背了LSP?

    ①子类违背父类声明要实现的功能。如:父类中提供订单排序函数按金额排序,而子类重写按日期排序。
    ②子类违背父类对输入输出异常的约定。
    ③子类违背父类注释中所罗列的任何特殊说明。

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

  1. 如何理解接口隔离原则?

    客户端不应该被强迫依赖他不需要的接口。
    ①如果把接口理解为一组API接口集合,可以是某个微服务的接口,也可以是某个内裤的接口等。如果部分接口只本部分调用者使用,我们就需要将这部分接口离出来,单独给这部分调用者使用,而不强迫其他调用者,也依赖这部分不会被调用到的接口。
    ②如果把接口理解为单个API接口或函数,部分调用者只需其部分功能,那就需要把函数拆分成力度更细的多个函数,让调用者只依赖他需要的那细粒度函数。
    ③把“接口”理解为OOP中的接口,接口的设计要尽量单一,不要让接口的实现类和调用者依赖不需要的接口函数。

  2. 接口隔离原则(ISP)和单一职责原则(SRP)的区别。

    单一职责原则针对的是模块、类、接口的设计。接口隔离原则相对于单一职责原则,一方面更侧重于接口的设计;另一方面,他的思考角度不同,接口隔离级别提供了一种判断接口的职责是否单一的标准:通过调用者如何使用接口来间接的判定。如果调用者只使用部分接口或接口的部分功能,那就不够单一。

五、依赖反转(倒置)原则(Dependency Inversion Principle,DIP)

  1. 控制反转(Inversion Of Control,IOC)

    控制反转是一个比较笼统的设计思想,并不是一种具体的实现方法。一般用来指导框架层面的设计,这里所说的“控制”指的是对程序的执行流程的控制,“反转”指的是在没有使用框架之前,程序员自己控制整个程序的执行。在使用框架之后,整个程序的执行流程通过框架来控制,流程的控制权从程序员“反转”给了框架。

  2. 依赖注入(Dependency Injection,DI)

    依赖注入是一种具体的编程技巧,不通过new的方式在类内部创建依赖类的对象,而是将依赖的类对象在外部创建好之后,通过构造函数、函数参数等方式传递(或注入)给类使用。

  3. 依赖注入框架

    如果依赖注入框架提供的扩展点,简单配置一下所有需要创建的类的对象、类与类之间的依赖关系,就可以实现由框架来自动创建对象、管理对象的生命周期、依赖注入等原本需要程序员来做的事情。

  4. 依赖反转原则(DIP)

    依赖反转原则也叫依赖倒置原则,这条原则跟控制反转有点类似,主要用来指导框架层面的设计。高层模块不依赖低层模块,他们共用依赖同一个对象。抽象不要依赖具体实现细节,具体实现细节依赖抽象。调用者属于高层,被调用者属于低层。

六、KISS原则、YAGNI原则

  1. KISS原则(keep it simple and stupid)

    尽量保持简单
    KISS原则是保持代码可读性和可维护性的重要手段。
    KISS原则中的“简单”并不是以代码的行数来考量的,行数越少并不代表代码越简单,我们还要考虑逻辑复杂度、实现难度、代码的可读性等。若本身就复杂的问题,用复杂的方法解决,并不违背kiss原则。

  2. 写kiss原则的指导:

    ①不要使用别人看不懂的技术实现。
    ②不要重复造轮子,善于使用已有的工具类库。
    ③不要过度优化。

  3. YAGNI原则(You Ain’t gonna need it)

    你不会需要它
    核心思想:不要做过度设计。不要编写当前用不到的代码。

    KISS原则讲的是“如何做”的问题(尽量保持简单)
    YAGNI原则讲的是“要不要做”的问题(当前不需要就不要做)

七、DRY原则

  1. DRY

    不要重复自己,即不要写重复代码。
    三种代码重复的情况:实现逻辑重复、功能语义重复、代码执行重复。
    实现逻辑重复,但功能语义不重复的代码,并不违背DRY原则。
    实现逻辑不重复,但功能语义重复的代码,也算是违反DRY原则。
    代码执行重复也算是违反DRY原则。

  2. 代码复用表示一种行为,在开发新的功能时,尽量使用已经存在的代码。
    代码复用性表示一段代码可被复用的特性和能力,在开发时尽量让代码可复用。
    不重复并不代表可复用,不存在任何重复代码不代表有可复用的代码。

  3. 提高代码复用性的方法

    减少代码耦合
    满足单一职责原则。模块化。业务与非业务逻辑分离。用代码下沉。封装、继承、抽象、多态。应用模板的等设计模式。
    在设计每个模块类函数的时候,要向设计一个外部API一样去思考他的复用性。可以不写复用代码,但一定不能写重复代码。

八、迪米特法则(Law Of Demeter,LOD)

  1. 如何理解高内聚、松耦合?

    高内聚、松耦合是一个非常重要的设计思想,能够有效的提高代码的可读性和可维护性。缩小功能改动导致的代码改动范围。

    “高内聚”用来指导类本身的设计,“松耦合”来指导类与类之间依赖关系的设计。

    “高内聚”指相近的功能应该放到同一类中,不相近的功能不要放到同一类中,相近的功能往往会被同时修改,放到同一个类中,修改会比较集中,代码容易维护。

    “松耦合”只在代码中类与类之间的依赖关系简单,清晰,及时,两个类有依赖关系,一个类的代码改动也不会或很少导致依赖类的代码改动。

    高内聚有助于低耦合。

  2. 如何理解迪米特法则。

    不该有直接依赖关系的类之间不要有依赖。有依赖关系的类之间,尽量依赖必要接口。
    迪米特法则是希望减少类之间的耦合,让类越独立越好,每个类都应该少了解系统的其他部分。一旦发生变化,需要了解这一变化的类就会比较少。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值