精华内容
下载资源
问答
  • 代码设计原则

    千次阅读 2017-12-18 15:32:56
    单一职责原则 Single Responsibility Principle 定义:一个类或者一个接口,最好只负责...解决方法:遵循单一职责原则。分别建立新类来对应相应职责;这样就能避免修改类时影响到其他职责; 当遇到职责扩

    单一职责原则 Single Responsibility Principle

    定义:一个类或者一个接口,最好只负责一项职责。

    问题由来:类T负责两个不同的职责P1和P2。由于职责P1需要发生改变而需要修改T类,就有可能导致原来运行正常的职责P2功能发生故障。

    解决方法:遵循单一职责原则。分别建立新的类来对应相应的职责;这样就能避免修改类时影响到其他的职责;

    当遇到职责扩散的时候,在逻辑足够简单的时候,才可以在代码级别上面违反单一职责原则,只有类中方法数量足够少,才可以在方法级别上违反单一职责原则;

    优点:类的复杂性将会降低,可读性将会大大提高,维护性也会提高。


    里氏替换原则 Liskov Substitution Principle

    在使用基类的地方可以任意使用其子类,能保证子类完美替换基类;这一种精神其实是对继承机制约束规范的体现。在父类和子类的具体实现中,严格控制继承层次中的关系特征,以保证用子类替换基类时,程序行为不发生问题,且能正常进行下去。

    对于继承来说,父类定义了一系列的规范和契约,虽然不强制所有的子类必须遵从,但是如果子类对这些非抽象方法任意修改,就会对整个继承体系造成破环。

    如果非要重写父类的方法,比较通用的方法是:原来的父类和子类都继承一个更加通俗的基类,原有的继承关系去掉,采用依赖、聚合、组合等关系代替;

    原则包含了一下四层含义: 
    * 子类可以实现父类的抽象方法,但不能覆盖父类的非抽象方法; 
    * 子类可以增加自己特有的方法; 
    * 当子类的方法重载父类的方法时,方法的形参要比父类方法的输入参数更佳宽松; 
    * 当子类的方法实现父类的抽象方法时,方法的返回值要比父类更加严格;


    依赖倒置原则 Dependence Inversion Principle

    定义:高层模块不应该依赖低层模块,二者都应该依赖其抽象;抽象不应该依赖细节;细节应该依赖抽象,其核心思想是依赖于抽象;

    问题由来:类A直接依赖类B,假如要将类A改为依赖类C,则必须通过修改类A的代码来完成;这种场景下,类A一般是高层模块,负责复杂的业务逻辑;类B和类C是低层模块,负责基本的原则操作;假如修改类A,会给程序带来不必要的风险。

    解决方案:将类A修改为依赖接口I,类B和类C各自实现接口I,类A通过接口I来间接与类B和类C发生联系,则会降低修改类A的几率;

    在实际中,我们一般需要做到以下三点: 
    * 低层模块尽量都要有抽象类或者接口,或者两者都有; 
    * 变量的声明类型尽量是抽象类或者接口; 
    * 使用继承时遵循里氏替换原则;


    接口隔离原则 Interface Segregation Principle

    定义:客户端不应该依赖它不需要的接口;一个类对另一个类的依赖应该建立在最小的接口上,否则将会造成接口污染;类A通过接口I依赖类B,类C通过接口I依赖类D,如果接口I对于类A和类B来说不是最小接口,则类B和类D必须去实现它们不需要的方法;

    原则的含义是:建立单一接口,不要建立庞大臃肿的接口,尽量细化接口,接口中的方法尽量少;就是说,我们要为每个类建立专用的接口,而不要试图去建立一个庞大的接口供所有依赖它的类去调用;

    注意,接口尽量小,但是要有限度,对接口进行细化可以提高程序设计灵活性,但是如果过小,则会导致接口数量尽量小,使设计复杂化。所以一定要适度,为依赖接口的类定制服务,只暴露给调用的类它需要的方法,它不需要的方法则隐藏起来;

    规则: 
    * 一个接口只服务于一个子模块或业务逻辑,服务定制; 
    * 通过业务逻辑压缩接口中的public方法,让接口看起来更加精悍; 
    * 已经被污染了的接口,尽量修改,如果变更风险太大,则用适配器模式进行转化; 
    * 根据具体的业务,深入了解逻辑,用心感知去控制设计思路;

    如何实施接口隔离,主要有两种方法: 
    1. 委托分离,通过增加一个新的接口类型来委托客户的请求,隔离客户和接口的直接依赖,注意这同时也会增加系统的开销; 
    2. 多重继承分离,通过接口的多重继承来实现客户的需求;


    迪米特法则

    定义:一个对象应该对其他对象保持最少的了解,其核心精神就是:不和陌生人说话,通俗之意就是一个对象对自己需要耦合关联调用的类应该知道的少;这会导致类之间的耦合度降低,每个类都尽量减少对其他类的依赖。


    合成复用原则

    原则是尽量使用合成/聚合的方式,而不是使用继承;

    开闭原则

    定义:一个软件实体如类、模版和函数应该对扩展,对修改关闭;

    解决方案:当软件需要变化时,尽量通过扩展软件实体的行为来实现变化,而不是修改已有的代码来实现变化;

    • 单一职责原则:实现类要职责单一;
    • 里氏替换原则:不要破坏继承体系;
    • 依赖倒置原则:面向接口编程;
    • 接口隔离原则:设计接口的时候要精简单一;
    • 迪米特法则:降低耦合;

    开闭原则:总纲,对扩展开放,对修改关闭;

    展开全文
  • 在任何编程语言中,函数的应用主要出于以下两种情况:1.代码块重复,这时候必须考虑用到函数,降低程序的冗余度2....高内聚、低耦合则是任何语言函数设计的总体原则。1.如何将任务分解成更有针对性...

    在任何编程语言中,函数的应用主要出于以下两种情况:

    1.代码块重复,这时候必须考虑用到函数,降低程序的冗余度

    2.代码块复杂,这时候可以考虑用到函数,增强程序的可读性

    当流程足够繁杂时,就要考虑函数,及如何将函数组合在一起。在Python中做函数设计,主要考虑到函数大小、聚合性、耦合性三个方面,这三者应该归结于规划与设计的范畴。高内聚、低耦合则是任何语言函数设计的总体原则。

    1.如何将任务分解成更有针对性的函数从而导致了聚合性

    2.如何设计函数间的通信则又涉及到耦合性

    3.如何设计函数的大小用以加强其聚合性及降低其耦合性

    【聚合】

    每个函数只做一件事

    完美的程序设计,每个函数应该而且只需做一件事。

    比如说:把大象放进冰箱分三步:把门打开、把大象放进去、把门关上。

    这样就应该写三个函数而不是一个函数拿所有的事全做了。这样结构清晰,层次分明,也好理解!

    【大小】

    保持简单、保持简短

    Python即是面向过程的语言,也是面向对象的语言,但更多的是充当脚本语言的角色。

    同样的功能,使用Python来实现其代码长度也许是C/C++/Java等语言的1/3. 几百行代码就能实现不小的功能!

    如果项目中设计的一个函数需要翻页才能看完的话,就要考虑将函数拆分了。

    在Python自带的200多个模块中,很少看到某个函数有两、三页的。

    Python代码以简单明了著称,一个过长或者有着深层嵌套的函数往往成为设计缺陷的征兆。

    【耦合】

    输入使用参数、输出使用return语句

    这样做可以让函数独立于它外部的东西。参数和return语句就是隔离外部依赖的最好的办法。

    慎用全局变量

    第一重考虑: 全局变量通常是一种蹩脚的函数间的进行通信的方式。

    它会引发依赖关系和计时的问题,从而会导致程序调试和修改的困难。

    第二重考虑: 从代码及性能优化来考虑,本地变量远比全局变量快。

    根据Python对变量的搜索的先后顺序: 本地函数变量==》上层函数变量==》全局变量==》内置变量

    从上面可以看出,本地变量优先被搜索,一旦找到,就此停下。下面专门对其做了测试,测试结果如下:

    import profile

    A = 5

    def param_test():

    B = 5

    res = 0

    for i in range(100000000):

    res = B + i

    return res

    if __name__=='__main__':

    profile.run('param_test()')

    >>> ===================================== RESTART =====================================

    >>>

    5 function calls in 37.012 seconds #全局变量测试结果:37 秒

    展开全文
  • 代码设计 六大原则

    2019-09-30 11:11:08
    代码设计 六大原则 单一职责原则 Single Responsibility Principle 定义:一个类或者一个接口,最好只负责一项职责。 问题由来:类T负责两个不同职责P1和P2。由于职责P1需要发生改变而需要修改T类,就有可能...

    代码设计 六大原则

    单一职责原则 Single Responsibility Principle

    定义:一个类或者一个接口,最好只负责一项职责。

    问题由来:类T负责两个不同的职责P1和P2。由于职责P1需要发生改变而需要修改T类,就有可能导致原来运行正常的职责P2功能发生故障。

    解决方法:遵循单一职责原则。分别建立新的类来对应相应的职责;这样就能避免修改类时影响到其他的职责;

    当遇到职责扩散的时候,在逻辑足够简单的时候,才可以在代码级别上面违反单一职责原则,只有类中方法数量足够少,才可以在方法级别上违反单一职责原则;

    优点:类的复杂性将会降低,可读性将会大大提高,维护性也会提高。


    里氏替换原则 Liskov Substitution Principle

    在使用基类的地方可以任意使用其子类,能保证子类完美替换基类;这一种精神其实是对继承机制约束规范的体现。在父类和子类的具体实现中,严格控制继承层次中的关系特征,以保证用子类替换基类时,程序行为不发生问题,且能正常进行下去。

    对于继承来说,父类定义了一系列的规范和契约,虽然不强制所有的子类必须遵从,但是如果子类对这些非抽象方法任意修改,就会对整个继承体系造成破环。

    如果非要重写父类的方法,比较通用的方法是:原来的父类和子类都继承一个更加通俗的基类,原有的继承关系去掉,采用依赖、聚合、组合等关系代替;

    原则包含了一下四层含义:
    * 子类可以实现父类的抽象方法,但不能覆盖父类的非抽象方法;
    * 子类可以增加自己特有的方法;
    * 当子类的方法重载父类的方法时,方法的形参要比父类方法的输入参数更佳宽松;
    * 当子类的方法实现父类的抽象方法时,方法的返回值要比父类更加严格;


    依赖倒置原则 Dependence Inversion Principle

    定义:高层模块不应该依赖低层模块,二者都应该依赖其抽象;抽象不应该依赖细节;细节应该依赖抽象,其核心思想是依赖于抽象;

    问题由来:类A直接依赖类B,假如要将类A改为依赖类C,则必须通过修改类A的代码来完成;这种场景下,类A一般是高层模块,负责复杂的业务逻辑;类B和类C是低层模块,负责基本的原则操作;假如修改类A,会给程序带来不必要的风险。

    解决方案:将类A修改为依赖接口I,类B和类C各自实现接口I,类A通过接口I来间接与类B和类C发生联系,则会降低修改类A的几率;

    在实际中,我们一般需要做到以下三点:
    * 低层模块尽量都要有抽象类或者接口,或者两者都有;
    * 变量的声明类型尽量是抽象类或者接口;
    * 使用继承时遵循里氏替换原则;


    接口隔离原则 Interface Segregation Principle

    定义:客户端不应该依赖它不需要的接口;一个类对另一个类的依赖应该建立在最小的接口上,否则将会造成接口污染;类A通过接口I依赖类B,类C通过接口I依赖类D,如果接口I对于类A和类B来说不是最小接口,则类B和类D必须去实现它们不需要的方法;

    原则的含义是:建立单一接口,不要建立庞大臃肿的接口,尽量细化接口,接口中的方法尽量少;就是说,我们要为每个类建立专用的接口,而不要试图去建立一个庞大的接口供所有依赖它的类去调用;

    注意,接口尽量小,但是要有限度,对接口进行细化可以提高程序设计灵活性,但是如果过小,则会导致接口数量尽量小,使设计复杂化。所以一定要适度,为依赖接口的类定制服务,只暴露给调用的类它需要的方法,它不需要的方法则隐藏起来;

    规则:
    * 一个接口只服务于一个子模块或业务逻辑,服务定制;
    * 通过业务逻辑压缩接口中的public方法,让接口看起来更加精悍;
    * 已经被污染了的接口,尽量修改,如果变更风险太大,则用适配器模式进行转化;
    * 根据具体的业务,深入了解逻辑,用心感知去控制设计思路;

    如何实施接口隔离,主要有两种方法:
    1. 委托分离,通过增加一个新的接口类型来委托客户的请求,隔离客户和接口的直接依赖,注意这同时也会增加系统的开销;
    2. 多重继承分离,通过接口的多重继承来实现客户的需求;


    迪米特法则

    定义:一个对象应该对其他对象保持最少的了解,其核心精神就是:不和陌生人说话,通俗之意就是一个对象对自己需要耦合关联调用的类应该知道的少;这会导致类之间的耦合度降低,每个类都尽量减少对其他类的依赖。


    合成复用原则

    原则是尽量使用合成/聚合的方式,而不是使用继承;

    开闭原则

    定义:一个软件实体如类、模版和函数应该对扩展,对修改关闭;

    解决方案:当软件需要变化时,尽量通过扩展软件实体的行为来实现变化,而不是修改已有的代码来实现变化;

    • 单一职责原则:实现类要职责单一;
    • 里氏替换原则:不要破坏继承体系;
    • 依赖倒置原则:面向接口编程;
    • 接口隔离原则:设计接口的时候要精简单一;
    • 迪米特法则:降低耦合;

    开闭原则:总纲,对扩展开放,对修改关闭;

    展开全文
  • 在任何编程语言中,函数的应用主要出于以下两种情况:1.代码块重复,这时候必须考虑用到函数,降低程序的冗余度2....高内聚、低耦合则是任何语言函数设计的总体原则。1.如何将任务分解成更有针对性...

    在任何编程语言中,函数的应用主要出于以下两种情况:

    1.代码块重复,这时候必须考虑用到函数,降低程序的冗余度

    2.代码块复杂,这时候可以考虑用到函数,增强程序的可读性

    当流程足够繁杂时,就要考虑函数,及如何将函数组合在一起。在Python中做函数设计,主要考虑到函数大小、聚合性、耦合性三个方面,这三者应该归结于规划与设计的范畴。高内聚、低耦合则是任何语言函数设计的总体原则。

    1.如何将任务分解成更有针对性的函数从而导致了聚合性

    2.如何设计函数间的通信则又涉及到耦合性

    3.如何设计函数的大小用以加强其聚合性及降低其耦合性

    【聚合】

    每个函数只做一件事

    完美的程序设计,每个函数应该而且只需做一件事。

    比如说:把大象放进冰箱分三步:把门打开、把大象放进去、把门关上。

    这样就应该写三个函数而不是一个函数拿所有的事全做了。这样结构清晰,层次分明,也好理解!

    【大小】

    保持简单、保持简短

    Python即是面向过程的语言,也是面向对象的语言,但更多的是充当脚本语言的角色。

    同样的功能,使用Python来实现其代码长度也许是C/C++/Java等语言的1/3. 几百行代码就能实现不小的功能!

    如果项目中设计的一个函数需要翻页才能看完的话,就要考虑将函数拆分了。

    在Python自带的200多个模块中,很少看到某个函数有两、三页的。

    Python代码以简单明了著称,一个过长或者有着深层嵌套的函数往往成为设计缺陷的征兆。

    【耦合】

    输入使用参数、输出使用return语句

    这样做可以让函数独立于它外部的东西。参数和return语句就是隔离外部依赖的最好的办法。

    慎用全局变量

    第一重考虑: 全局变量通常是一种蹩脚的函数间的进行通信的方式。

    它会引发依赖关系和计时的问题,从而会导致程序调试和修改的困难。

    第二重考虑: 从代码及性能优化来考虑,本地变量远比全局变量快。

    根据Python对变量的搜索的先后顺序: 本地函数变量==》上层函数变量==》全局变量==》内置变量

    从上面可以看出,本地变量优先被搜索,一旦找到,就此停下。下面专门对其做了测试,测试结果如下: import profile

    A = 5

    def param_test():

    B = 5

    res = 0

    for i in range(100000000):

    res = B + i

    return res

    if __name__=='__main__':

    profile.run('param_test()')

    >>> ===================================== RESTART =====================================

    >>>

    5 function calls in 37.012 seconds #全局变量测试结果:37 秒

    Ordered by: standard name

    ncalls tottime percall cumtime percall filename:lineno(function)

    1 19.586 19.586 19.586 19.586 :0(range)

    1 1.358 1.358 1.358 1.358 :0(setprofile)

    1 0.004 0.004 35.448 35.448 :1()

    1 15.857 15.857 35.443 35.443 Learn.py:5(param_test)

    1 0.206 0.206 37.012 37.012 profile:0(param_test())

    0 0.000 0.000 profile:0(profiler)

    >>> ===================================== RESTART =====================================

    >>>

    5 function calls in 11.504 seconds #局部变量测试结果: 11 秒

    Ordered by: standard name

    ncalls tottime percall cumtime percall filename:lineno(function)

    1 3.135 3.135 3.135 3.135 :0(range)

    1 0.006 0.006 0.006 0.006 :0(setprofile)

    1 0.000 0.000 11.497 11.497 :1()

    1 8.362 8.362 11.497 11.497 Learn.py:5(param_test)

    1 0.000 0.000 11.504 11.504 profile:0(param_test())

    0 0.000 0.000 profile:0(profiler)

    避免改变可变类型参数

    Python数据类型比如说列表、字典属于可变对象。在作为参数传递给函数时,有时会像全局变量一样被修改。

    这样做的坏处是:增强了函数之间的耦合性,从而导致函数过于特殊和不友好。维护起来也困难。

    这个时候就要考虑使用切片S[:]和copy模块中的copy()函数和deepcopy()函数来做个拷贝,避免修改可变对象

    具体参考这篇文章: Python中的深浅拷贝详解

    避免直接改变另一个模块中的变量

    比如说在b.py文件中导入a模块,a中有变量PI = 3.14, 但b.py想将其修改为:PI = 3.14159, 在这里你就搞不清楚变量PI原先的值到底是多少。碰到这种情况,可以考虑用易懂的函数名来实现: #模块a.py

    PI = 3.14

    def setPi(new):

    PI = new

    return PI

    这样既有自己想要的PI的值,又没有改变a模块中PI的值 import a

    PI = a.setPi(3.14159)

    print PI;a.PI

    展开全文
  • 概念利用测试概念进行代码设计七条基本原则[2]软件测试不用隔离测试,而是拥有您在它上面调用您想测试各种方法的单个调节器对象通常是有帮助。这个对象然后能把这些方法调用转发到适当地方。沿着相同线路...
  • ξ 4.1 什么是开闭原则☆ 开闭原则...这个原则是说在设计一个模块时候,应对使这个模块可以在不被修改前提下被扩展,换言之,应对可以不必修改源代码的情况下改变这个模块行为。☆ 满足开闭原则的软件系统...
  • 不使用开闭原则的解法: 在Car类中修改代码 代码实现: //设计类 public class Car { public void start() { System.out.println("启动汽车"); } public void run() { //在run方法中增加导航功能 System.out...
  • 某个类的方法通过局部变量、方法的参数或者对静态方法的调用来访问另一个类(被依赖类)中某些方法来完成一些职责 关联关系 一般关联关系 一个类对象作为另一个类成员变量来实现关联关系 聚合关系 强关联...
  • 不使用里氏替换原则的解法: 代码实现: //具体类 class ReadFile { public void read(String fileName){ System.out.println("读取Excel文件"+fileName); } } class ReadDoc extends ReadFile{ //子类覆写父类...
  • Javabean的设计原则:(1)共有类 即使用public class来定义(2)无参公有构造方法(3)属性私有属性使用private定义(4)Getter和Setter方法如下user.java就是一个符合要求javabean。public class ...
  • 软件设计是演进过程,而重构是设计演进基本方法。重构是指不改变软件行为前提下,修改程序内部结构。重构说简单,做不简单。首先,需要知道代码的好坏,即代码异味,设计原则等。其次,需要以自动测试作为保障。
  • 在任何编程语言中,函数的应用主要出于以下两种情况:1.代码块重复,这时候必须考虑用到函数,降低程序的冗余度2....高内聚、低耦合则是任何语言函数设计的总体原则。1.如何将任务分解成更有针对性...
  • 1)接口尽可能原子化,提高接口复用能力; 2)代码模块职责要尽可能明确,适用于接口、类、...5)设计接口和基层父类时,要充分考虑到可能存在需求变更,原则上只抽取不可变特性; 6)注意java类间解偶。总结起来
  • 优秀API接口设计原则方法

    千次阅读 2017-07-13 20:56:28
    一旦API发生变化,就可能对相关调用者带来巨大代价,用户需要排查所有调用的代码,需要调整所有与之相关部分,这些工作对他们来说都是额外。如果辛辛苦苦完成这些以后,还发现了相关bug,那对用户打击就...
  • 例题:学生管理类StudentManager包含如下功能,包括连接数据库方法getConnection()、操作数据库方法入search和delete、显示学生信息的方法display。 不使用单一职责原则的解法: public class Demo { public void ...
  • 高内聚、低耦合则是任何语言函数设计的总体原则。 1.如何将任务分解成更有针对性的函数从而导致了聚合性 2.如何设计函数间的通信则又涉及到耦合性 3.如何设计函数的大小用以加强其聚合性及降低其耦合性 【聚合】 每...
  • 文章目录Java 设计模式内容介绍先看几个经典面试题设计模式重要性设计模式七大原则设计模式目的设计模式七大原则单一职责原则基本介绍应用实例单一职责原则注意事项和细节接口隔离原则基本介绍应用实例应传统...
  • 在任何编程语言中,函数的应用主要出于以下两种情况:1.代码块重复,这时候必须考虑用到函数,降低程序的冗余度2....高内聚、低耦合则是任何语言函数设计的总体原则。1.如何将任务分解成更有针对性...
  • 意思就是我们改变一个软件时(比如扩展其他功能),应该通过扩展方式来达到软件改变,而不应该修改原有代码来实现变化。二、单一职责原则一个类只有一个引起这个类变化原因。即一个类只完成一个功能,如果做不到...
  • 在任何编程语言中,函数的应用主要出于以下两种情况:1.代码块重复,这时候必须考虑用到函数,降低程序的冗余度2....高内聚、低耦合则是任何语言函数设计的总体原则。1.如何将任务分解成更有针对性...
  • 或者有朋友尝试在业务编码中使用,却越用越复杂,本来一个类几个方法能搞定业务,套用模式后会多出好多接口和类,所以用着用着就放弃了。我说比较直接点,很多教材或博客中使用Animal、Fruit、Car这些例子来教...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 4,651
精华内容 1,860
关键字:

代码设计的原则方法