zoukankan      html  css  js  c++  java
  • 设计原则

    • 接口(or 抽象类)负责定义public属性和方法,并且声明与其他对象的依赖关系(模型构建)
    • 抽象类负责公共构造部分的实现(抽象是所有子类的共性封装)
    • 实现类实现业务逻辑,同时在适当的时候对父类进行细化。

    开闭原则(Open-Closed Principle)

    一个软件实体如类、模块和函数,应该对扩展开发,对修改关闭。

    • 抽象约束:①通过抽象类约束扩展,②外部调用尽量使用接口或抽象类,③抽象层尽量保持稳定,不允许轻易修改
    • 元数据控制模块行为:使用配置参数去控制模块的行为,案例-控制反转Inversion of Control
    • 约定优于配置:使用共有的章程约定替换繁琐的配置,可提高开发效率和可维护性,保存代码的简洁。
    • 封装变化:只对外暴露稳定的接口,使可能存在的修改不影响调用方使用

    依赖倒置原则(Dependence Inversion Principle) - 面向接口编程(Object-Oriented Design)

    面向接口编程,依赖于抽象而不依赖于具体。 - 抽象构建框架,实现扩展细节

    • 高层模块不应该依赖底层模块,二者都应该依赖其抽象。
    • 抽象不应该依赖细节,细节应该依赖抽象。

    接口/抽象类:本质是一种规范和约束,是对外暴露的一组通信规约,使其实现能被内部修改而不影响外界其他实体与其交互的方式。
    程序设计:就是对现实进行抽象,并将抽象与抽象相关联,从而形成一套合乎情理,描述了程序世界的规则。(系统模型构建)
    程序实现:根据需要对抽象进行具体的实现,在不同的场景,可以有不同的实现,但所有的实现都应该符合程序设计(符合模型规则)。
    即:当你构建一个世界的时候,你应该表达:这个世界的规则和联系应该是怎么样的,而不是具体细节:它,他,她,祂。

    // 依赖的三种写法
    // 1. 由实现类的构造函数中传递依赖对象:
    public Driver(ICar _car)
    {

          this.car = _car;

    }
    
// 2. setter方法声明依赖关系:
    
public void setCar(ICar car);

    // 3. 接口声明依赖关系:

    public void drive(ICar car);
    // 额外,依赖注入
    

    单一职责原则(Single Responsibility Principle)

    一个类应该有且仅有一个引起它变化的原因,否则类应该被拆分 - 降低变更引起的风险,修改只影响对应的功能,不会影响其他功能
    设计模式之禅-用户行为类和用户属性类


    接口隔离原则(Interface Segregation Principle)

    因为:类间的依赖关系应该建立在最小的接口上
    所以:接口需要尽量细化,而非建立一个统一的臃肿的接口
    目的:对外暴露功能时,不会提供额外多余的功能
    - public类型的接口方法,是对外界提供的契约,契约越少,越有利于日后的开发和扩展

    设计模式之禅中案例,为避免赋予普通用户额外的权限,对接口进行拆分:
    设计模式之禅-特殊情况下接口拆分


    迪米特法则(Law of Demeter)/最少知道原则(Least Knowledge Principle)

    ①. 只与朋友类(成员对象,方法入参,方法返回值)交流
    -- 类与类之间的关系是建立在类间的,而非方法间的(应避免在方法实现中新增类的依赖关系)。即:在程序模型建立时就将依赖关系确认,而非实现时再意外引入
    ②. 对于依赖的类知道的最少,尽量少的暴露public接口
    -- 当调用方需依次调用多个接口完成某个功能时,应该把该套逻辑抽取出来,调用方只调用一个接口即可完成整个功能(低耦合,高复用)
    ③. 如果两个软件实体无需直接通信,那么就不应该发生直接的相互调用,可以通过第三方转发(中介) - 由中介维护交互细节,案例:中介者模式、访问者模式

    总结:高内聚,低耦合,尽量减少类间依赖。
    对于①:调用方无需知晓被调用方将对哪个对象进行操作(只依赖必须依赖的类)
    对于②:实现逻辑应该维护在被调用方,而不是调用方每一步去操作,降低耦合度(被依赖类尽可能少暴露接口)
    对于③:当调用方和被调用方不需要直接通信时,可将通信部分单独封装成中介类,从而使调用方和被调用方的改动只影响其本身和中介类(案例:中介者模式和访问者模式)


    里氏替换原则(Liskov Substitution Principle)

    子类可以作为父类使用,且调用方无需分辨其是否是子类(在子类被当作其父类使用时,其应有和父类相同的行为逻辑)

    • 子类可以实现父类的抽象方法,但不能覆盖父类的非抽象方法
    • 子类中可以增加自己特有的方法
    • 子类重载父类方法时,要有不小于父类的(入参)前置条件
    • 子类实现父类方法时,要有不大于父类的(出参)后置条件(IDE会检查不通过)
    // (前置条件)例:
    Father{
      public void do(Map map);
    }
    Son{
      public void do{HashMap hmap};
    }
    
    // 对于f.do(new HashMap()):
    Father f = new Son(); // 将调用father.do(Map)方法
    Son f = new Son();    // 将调用son.do(HashMap)方法
    // 导致前后不一
    

    设计模式之禅中案例,特殊子类无法实现父类方法时,采用关联委托关系实现解耦。
    因此采用关联委托关系(组合),声音、形状等委托给AbstractGun处理,其他玩具枪相关的特性由AbstractToyGun进行拓展
    设计模式之禅 - 枪与玩具枪


    合成复用原则(Composite Reuse Principle)

    为避免继承泛滥,应尽量先使用组合或者聚合等关联关系(黑箱复用)来实现复用,其次才考虑使用继承关系(白箱复用)来实现。

    继承的缺点 - 强耦合的
    侵入性的:子类具有父类的所有属性和方法
    降低了代码的灵活性:子类必须拥有父类的方法

  • 相关阅读:
    RF中selenium2Library的关键字--BrowserManagement
    excle脚本驱动+动态执行case
    unittest+HTMLtestrunner+SMTP发送邮件
    01.微博三方登录原理讲解
    图片验证码接口
    编写注册接口
    jwt安装配置
    jwt原理
    vue组件
    使用axios实现登录功能
  • 原文地址:https://www.cnblogs.com/kiqi/p/13425103.html
Copyright © 2011-2022 走看看