python函数设计原则

一、函数设计

1、函数间的隔离

函数间的隔离与函数任务的分解有关。

单一职责原则(Single Responsiblity Principle,SRP):

定义:有且仅有一个原因引起类的变更。

要求:一个接口或类只有一个职责。


2、函数间的耦合

函数间的耦合性高低取决于函数间相互的通信程度。

里氏替换原则(Liskov Substitution Principle,LSP):

定义:所有引用基类的地方必须能透明地使用其子类的对象。

要求:

①、子类必须完全实现父类的方法:

  • 在类中调用其他类时务必要使用父类或接口;
  • 如果子类不能完整地实现父类的方法,或者父类的某些方法在子类中已经发生“畸变”,则建议断开父子继承关系,采用依赖、聚集、组合等关系代替继承。

②、覆盖或实现父类的方法时输入参数可以被放大:

  • 如果父类的输入参数类型大于子类的输入参数类型,会出现父类存在的地方,子类未必会存在,因为一旦把子类作为参数传入,调用者很可能进入子类的方法范畴;
  • 子类中方法的前置条件必须与超类中被覆写的方法的前置条件相同或者更宽松。 

③、覆写或实现父类的方法时输出结果可以被缩小:父类的一个方法的返回值是一个类型T,子类的相同方法(重载或覆写)的返回值为S,那么里氏替换原则就要求S必须小于等于T,也就是说,要么S和T是同一个类型,要么S是T的子类。

依赖倒置原则(Dependence Inversion Principle,DIP):

定义:高级模块不应该依赖于低级模块。两者都应该依赖于抽象。抽象不应该依赖于细节。细节应该依赖于抽象。

依赖倒置原则的本质就是通过抽象(接口或抽象类)使各个类或模块的实现彼此独立,不互相影响,实现模块间的松耦合。对象的依赖关系有三种方式来传递:

①、构造函数注入 --- 在类中通过构造函数声明依赖对象。

②、Setter依赖注入 --- 在抽象中设置Setter方法声明依赖关系。

③、接口注入 --- 在接口的方法中声明依赖对象。

要求:

  1. 每个类尽量都有接口或抽象类,或者抽象类和接口两者都具备; --- 这是依赖倒置的基本要求
  2. 变量的表面类型尽量是接口或者是抽象类;
  3. 任何类都不应该从具体类派生;
  4. 尽量不要覆写基类的方法; --- 如果基类是一个抽象类,而且这个方法已经实现了,子类尽量不要覆写。类间依赖的是抽象,覆写了抽象方法,对依赖的稳定性会产生一定的影响。
  5. 结合里氏替换原则使用。 --- 接口负责定义public属性和方法,并且声明与其他对象的依赖关系,抽象类负责公共构造部分的实现,实现类准确的实现业务逻辑,同时在适当的时候对父类进行细化。 

接口隔离原则(Interface isolation principle,ISP):

接口分为两种:

  1. 实例接口(Object Interface),在Java中声明一个类,然后用new关键字产生一个实例,它是对一个类型的食物的描述,这是一种接口。
  2. 类接口(Class Interface),Java中经常使用的interface关键字定义的接口;

定义:

  1. Clients should not be forced to depend upon interfaces that they don‘t use。(客户端不应该依赖它不需要的接口。)
  2. The dependency of one class to another one should depend on the smallest possible interface。(类间的依赖关系应该建立在最小的接口上。)

要求:

  1. 接口要尽量小; --- 不出现臃肿的接口(Fat Interface),但是“小”是有限度的,首先就是不能违反单一职责原则。
  2. 接口要高内聚; --- 高内聚就是提高接口、类、模块的处理能力,减少对外的交互。在接口中尽量少公布public方法,接口是对外的承诺,承诺越少对系统的开发越有利,变更的风险也就越少,同时也越有利于降低成本。
  3. 定制服务; --- 一个系统或系统内的模块之间必然会有耦合,有耦合就要有相互访问的接口(并不一定就是Java中定义的Interface,也可能是一个类或单纯的数据交换),我们设计时就需要为各个访问者(即客户端)定制服务。定制服务就是单独为一个个体提供优良的服务。我们在做系统设计时也需要考虑对系统之间或模块之间的接口采用定制服务。采用定制服务就必然有一个要求:只提供访问者需要的方法。
  4. 接口设计是有限度的。 --- 接口的设计粒度越小,系统越灵活。但是,灵活的同时也带来了结构的复杂化,开发难度增加,可维护性低,所以接口设计一定要注意适度。

  接口隔离原则是对接口的定义,同时也是对类的定义,接口和类尽量使用原子接口或原子类来组装。

原子划分判断:

  1. 一个接口只服务于一个模块或业务逻辑;
  2. 通过业务逻辑压缩接口中的public方法,接口时常去回顾,尽量让接口达到“满身筋骨肉”,而不是“肥嘟嘟”的一大堆方法;
  3. 已经被污染了的接口,尽量去修改,若变更的风险较大,则采用适配器模式进行转化处理;
  4. 了解环境,拒绝盲从。每个项目或产品都有特定的环境因素,环境不同,接口拆分的标准就不同。

迪米特法则(Law of Demeter ,LoD)/最少知识原则(Least Knowledge Principle,LKP):

定义:一个对象应该对其他对象有最少的了解。即,一个类应该对自己需要耦合或调用的类的内部知道得最少。

要求:

①、只和朋友交流

  • 朋友类的定义:出现在成员变量、方法的输入输出参数中的类称为成员朋友类,而出现在方法体内部的类不属于朋友类。
  • 一个类只和朋友交流,不与陌生类交流,不要出现getA().getB().getC().getD()这种情况(在一种极端的情况下允许出现这种访问,即每一个点后面返回类型都相同),类与类之间的关系是建立在类间的,而不是方法间,因此一个方法尽量不引入一个类中不存在的对象,当然,JDK API提供的类除外。

②、朋友间也是有距离的 --- 一个类公开的public属性或方法越多,修改时涉及的面积越大,变更引起的风险扩散也就越大。

  • 在设计时需要反复衡量:是否还可以再减少public方法和属性,是否可以修改为private、package-private(包类型,在类、方法、变量前不加访问权限,则默认为包类型)、protected 等访问权限,是否可以加上final关键字等。 
  • 尽量不要对外公布太多的public方法和非静态的public变量,尽量内敛,多使用private、package-private、protected等访问权限。

③、自己的就是自己的 --- 如果一个方法放在本类中,即不增加类间的关系,也对本类不产生负面影响,就放置在本类中。

④、谨慎使用Serializable

  迪米特法则的核心观念就是类间解耦,弱耦合,只有弱耦合了以后,类的复用率才可以提高。其要求的结果就是产生了大量的中转或跳转类,导致系统的复杂性提高,同时也为维护带来了难度。

  迪米特法则要求类间解耦,但解耦是有限度的(除非是计算机的最小单元——二进制的0和1。那才是完全解耦),在实际的项目中,原则只是供参考,如果违背了这个原则,项目也未必会失败,这就需要大家在采用原则时反复度量,不遵循是不对的,严格执行就是“过犹不及”。

 

3.开放封闭原则(Open and closed principle,OCP)

定义:一个软件实体如类、模块和函数应该对扩展开放,对修改关闭。即,一个软件实体应该通过扩展来实现变化,而不是通过修改已有的代码来完成变化。

软实体包括以下几个部分:

  1. 项目或软件产品中按照一定的逻辑规则划分的模块;
  2. 抽象和类;
  3. 方法。

变化归纳以下三种类型:

  1. 逻辑变化;
  2. 子模块变化;
  3. 可见视图变化。

要求:

①、抽象约束 --- 通过接口或抽象类可以约束一组可能变化的行为,并且能够实现对扩展开放:

  • 通过接口或抽象类约束扩展,对扩展进行边界限定,不允许出现在接口或抽象类中不存在的public方法;
  • 参数类型,引用对象尽量使用接口或者抽象类,而不是实现类;
  • 抽象层尽量保持稳定,一旦确定即不允许修改。

②、元数据(metadata)控制模块行为

编程时使用元数据来控制程序的行为,减少重复开发。用来描述环境和数据的数据,通俗地说就是配置参数,参数可以从文件中获得,也可以从数据中库中获得。

③、制定项目章程

在一个团队中,建立项目章程是非常重要的,因为章程中指定了所有人员都必须遵守的约定,对项目来说,约定优于配置。相信大家都做过项目,会发现一个项目会产生非常多的配置文件。以SSH项目开发为例,一个项目中Bean配置文件就非常多,管理非常麻烦。如果需要扩展,就需要增加子类,并修改SpringContext文件。然而,如果你在项目中指定这样一个章程:所有的Bean都自动注入,使用Annotation进行装配,进行扩展时,甚至只用写一个类,然后由持久层生成对象,其他的都不需要修改,这就需要项目内约束,每个项目成员都必须遵守,该方法需要一个团队有较高的自觉性,需要一个较长时间的磨合,一旦项目成员都熟悉这样的规则,比通过接口或抽象类进行的约束效率更高,而且扩展性一点也没有减少。

④、封装变化

  • 将相同的变化封装到一个接口或抽象类中;
  • 将不同的变化封装到不同的接口或抽象类中,不应该有两个不同的变化出现在同一个接口或抽象类中。

二、Python函数的设计规范

1、耦合性:

  • 尽可能通过参数接受输入,以及通过return产生输出以保证函数的独立性;
  • 尽量减少使用全局变量进行函数间通信;
  • 不要在函数中直接修改可变类型的参数;
  • 避免直接改变定义在另外一个模块中的变量;

2、聚合性:

  • 每个函数都应该有一个单一的、目的统一的目标;
  • 每个函数的功能都应该相对简单;

3、函数大小:

函数体量大 函数体量小
耦合性高 耦合性低
聚合性低 聚合性高

游戏循环(主循环)主要工作:

  • 处理事件
  • 更新游戏状态
  • 绘制游戏状态到屏幕上

python函数设计原则_第1张图片

 

 

http://www.gxlcms.com/python-352521.html

https://www.cnblogs.com/bypp/p/8987186.html

https://blog.csdn.net/Field_Yang/article/details/80587895

https://www.jb51.net/article/127484.htm

你可能感兴趣的:(python函数设计原则)