zoukankan      html  css  js  c++  java
  • 设计之路

    设计理念

    高内聚,低耦合

      模块:模块是按业务系统划分,可以颗粒化,方法,类都可以称之为模块。

      内聚:泛指模块内的关系

      耦合:泛指模块之间的关系  

    高内聚:模块内尽量以围绕着完成一个具体功能为目的,不涵盖与之没有较大关系的功能方法

    低耦合:模块之间的关系不紧密,模块A改变的同时不会影响到关联模块B,反之,如果有个10个模块,修改了1个模块,另外9个模块也要跟着改,这就属于高耦合

    OO三大特性

    封装,继承,多态

    封装:把客观事物封装成一个对象,对象可以保留隐私信息,并且可以暴露某些信息【公有方法,属性】给可信赖用户

    继承:对象之间可以互相继承,被继承者称之为父类,继承者称为子类,子类会继承父类的公有方法【含保护级,*无需编写代码就可以扩展获得某些功能】

    多态:一个类实例的相同方法在不同情境下会有不同的结果,多用于继承+虚方法

      如:假设有个抽象类bird,有个虚方法fly,具体实现类hawk,sparrow分别继承于bird,重写fly方法,它们二者的fly方法是不一样的

    其他:重写,重载

    重写:父类有个虚方法,子类继承重写

    重载:函数名称一样,但传入参数不一样【也可以返回参数不一样】

      如:构造函数重载

    UML类关系

    继承,依赖,关联,聚合,组合

    继承是类与类【接口】之间的常见关系,子类继承父类所有功能,并可以扩展新功能

    依赖是类A使用了类B,这种关系是临时、弱的,用完就舍弃,类A使用了类B之后,类B的生命周期就已经结束

      通常是类A里面的某个方法【也可以是构造函数】用到类B的某个属性或者方法

    关联是强依赖,这种关系是持久的,只要类A在,类B就一直存在

      通常是类A里面有类B的实例【类A里面有个属性是类B】

    聚合是关联的一种,体验在真实场景下,表达的是一种has-a的关系,A和B各自有独立的生命周期,如公司与员工,计算机与CPU

    组合也是关联的一种,表达的是一种contains-a的关系,有A才有B,没A就没B,如人与手

    设计原则

    SRP:单一职责原则

      对一个类而言,引起其变化的原因应该只有一个,换种说法就是这个类只负责干一件事【内聚】

    DIP:依赖倒置原则

      抽象不应该依赖细节,细节应该依赖抽象,有点绕口,本质就是面向接口编程,而不是面向实现编程

      如:以电脑主板为例,主板会预留一些插槽【接口】,显卡,内存条按照插槽规则具体设计【细节】,这样如果一根内存条坏了,只需换一根内存条,而不需要把主板也换了

    OCP:开闭原则

      对扩展开发,对修改关闭,即代码每次发生变化时,要通过添加新的代码来增强现有类型的行为,而不是修改原有的代码。

      如:我们的电脑主板,可以插显卡,内存条,CPU等等,主板就是对扩展【插内存条,插显卡】开放,对修改关闭,这种实现也可理解为面向改变的提出来当公共接口,外部扩展都与这个公共接口通信

    LSP:里氏替换原则

      子类能够完全替换父类,父类所有动作,子类都能完成

      如:企鹅继承鸟,鸟能飞,但企鹅不能飞,这就违反里氏替换原则

    Lod:迪米特原则【最少知识原则】

      换个说法就是不跟陌生人说话,就是2个类之间不直接通信,通过第三方转发

      如:我们电脑坏了,我们不会找小王,而是直接找IT部【第三方】,由IT部转发命令给小王修
    外观模式、中介者模式使用到

    ISP:接口隔离原则

      单个接口不要承担过多的业务,如业务过多,可分离出多个接口来实现,其实就是对单个接口来说,尽量做到单一职责

    设计模式

    须知

    软件产品的本质目标就是要可维护、可扩展、可复用和灵活性好,而设计模式就是为了达到这种设计理念的解决方案,我们可以把设计模式比喻成药【疫苗】,产品当作小动物,只有当动物生病时才吃药【不滥用设计模式】,提前注射疫苗是为了防止以后出问题,想一口气把产品做完美,那是不可能的,市场和客户的需求是不可把控,后期产品的迭代与重构往往更能体现设计模式的好处

    种类

    设计模式按分类可以分为三种,创建型,结构型,行为型

    创建型:创建对象的模式,将客户从所需实例化的对象中解耦,抽象对象实例化的过程

      1:隐藏对象的创建组织过程

      2:封装系统使用的具体类

    • 单件:一个类只有一个实例,提供一个全局访问点
    • 工厂方法:创建单个对象,由子类决定具体要创建的产品
    • 抽象工厂:创建产品家族
    • 建造者:隔离一个产品的具体构造过程
    • 原型:通过克隆或者拷贝实例化对象

    结构型:对象和类之间的结构构建关系,把类或对象组合更大的结构中,主要用来处理类或对象的组合,包括类结构型和对象结构型,类结构型就是通过继承实现,对象结构则是通过对象依赖或者关联实现

    • 适配器:封装对象,并提供不同的接口【适配不兼容的接口】
    • 桥接:将产品实现和抽象分离出来
    • 组合:把树结构对象转换成一对一关系【客户用一致的方式处理组合对象和单个对象】
    • 装饰:为对象动态添加职责
    • 外观:简化一群子系统,统一接口访问
    • 享元:某个实例可以共享多次使用
    • 代理:包装对象,以控制对另一个对象的访问

    行为型:在不同对象之间划分责任和算法,类和对象如何交互和分配职责。行为模式不仅仅关于类和对象,还关于它们之间的互相作用,简单理解就是对象A关联对象B,对象A执行某个方法A1的同时会影响到B,B可能也会执行某个方法B1

    • 职责链:某个请求需要经过多人处理
    • 命令:封装请求为对象
    • 解释器:系统文法的解释
    • 迭代:在对象的集合中游走,不暴露内部实现
    • 中介者:通过第三方解耦类对象之间的直接交互
    • 备忘录:备份和恢复对象的内部状态
    • 观察者:对象状态改变时动态通知其所有观察者
    • 状态:对象行为改变,其内部状态跟着改变
    • 策略:封装可以互换的算法行为
    • 模板方法:子类决定算法实现的步骤
    • 访问者:在不改变对象的同时增加新的能力

    常用模式

    创建型

    1.抽象工厂

    定义:一个工厂产生一组产品,创建一组产品对象

    使用频率:高

    注意:工厂和产品的关系是一对多,但产品组的数量一定要恒定,如果后期增加一个产品,那么每个工厂都要修改一遍【违背OCP】

    ,扩展产品组容易,扩展产品组内的产品复杂

    UML类图:

    2.建造者

    定义:把一个产品的创建细节抽离出来,分步实现

    使用频率:中低

    场景:肯德基霸王套餐【包含鸡腿,饮料,爆米花】,汽车【包含车身,论坛,方向盘等等】

    UML类图:

    3.工厂方法

    定义:一个工厂只能产生一个产品,同理增加一个产品的同时需要增加一个具体工厂

    使用频率:高

    注意:工厂和产品的关系是一对一,注意简单工厂严格说 不算设计模式,是一种编程习惯。

    UML类图:

    4.原型

    定义:拷贝对象,通常是扩展一个克隆方法

    使用频率:中

    UML类图:

    5.单件

    定义:一个类只有一个实例,提供一个全局访问点,如抽象工厂的工厂、对象池【构造器不能公开】

    使用频率:中高

    UML类图:

     

    结构型

    6.适配器

    定义:转换接口,通过适配器,访问原本访问不了的接口

    使用频率:中高

    注意:替换之前旧的接口【过期之类】,一般用于开发后期

    场景:TypeC充电器,.net中的DataAdapter

    UML类图:

    7.桥接

    定义:分离接口与实现,通常为二维变化

    使用频率:中

    UML类图:

    8.组合

    定义:统一接口,通常是把一对多的关系转为一对一的关系,统一接口,呈现的树结构,涵盖叶子节点,用来表达整体与部分的关系

    使用频率:中高

    场景:winform中的Textbox,Label这种控件类

    注意:组合模式是以单一责任设计原则换取透明性【通过让组件的接口含有管理子节点和叶节点的操作,客户可以将组合叶节点一视同仁,这对客户是透明的】

    UML类图:

    9.装饰

    定义:稳定接口,对现有对象增加扩展功能

    使用频率:中

    UML类图:

    10.外观

    定义:简化接口,一类子系统封装出一个公共接口出来,外层只与统一通过公共接口打交道,由公共接口决定调取哪个相应子功能

    使用频率:高

    场景:银行接待,你去银行只要找接待人,他帮你处理贷款,借款等事宜【一般是开发前期】,最少知识原则,只和你的密友谈话

    UML类图:

    11.享元

    定义:保留接口,把一类经常使用的产品对象缓存到一个共享区域,下次调取,就不需要再实例化,直接从缓存区域直接获取就行

    使用频率:低

    UML类图:

    12.代理

    定义:假借接口,通过第三方代理访问接口

    使用频率:中高

    场景:如国内上youtube需要借用VPN,懒加载

    UML类图:

     

    行为型

    13.职责链

    定义:封装对象责任,支持责任的变化,构建动态职责连,支持事务型操作,某个行为需要多个对象依次执行,对象直接关系是链式

    使用频率:中低

    场景:面试(hr-结束-经理),审批

    UML类图:

    14.命令

    定义:解耦请求者与实现者,命令抽象出来,涵盖发送者,命令,接受者,通常命令会与接受者关联起来,发送者可以灵活变化

    使用频率:中高

    场景:人-遥控器-电视机

    UML类图:

    15.解释器

    定义:注重封装特定领域变化,文法翻译

    使用频率:低

    场景:字典翻译

    UML类图:

    16.迭代

    定义:注重封装对象集合,不暴露其内部表示,程序可以对对象作遍历操作

    使用频率:高

    注意:当读取对象的时候不能对对象集合作add,remove影响到集合数的操作

    UML类图:

    17.中介

    定义:解耦对象之间的依赖关系,统一通过第三方建立交互关系

    使用频率:中低

    场景:聊天室

    UML类图:

    18.备忘录

    定义:注重对象状态变化,支持状态的保持和恢复,记录某个时间点的对象状态,如果有异常,可以执行回滚操作返回到正常状态

    使用频率:低

    场景:数据库事务日志

    UML类图:

    19.观察者

    定义:注重对象通知变化,通知依赖他的对象更新,涵盖观察者和被观察者,观察者和被观察者关系为多对一,被观察者统一会向观察者发送一个消息,观察者会根据收到的消息作出相应动作【这是一种推的实现】

    使用频率:高

    场景:订阅,关注微信公众号,股票-股民,红绿灯-司机

    UML类图:

    20.状态

    定义:封装对象与状态的关系,对象的状态会根据对象某个属性变化而变化

    使用频率:中

    场景:话费(正常-欠费)

    UML类图:

    21.策略

    定义:注重封装算法,随时替换算法

    使用频率:中高

    场景:排序【快排,2分排序】,税收【上海,南昌】

    UML类图:

    22.模板方法

    定义:封装操作骨架,父类定义好执行步骤,具体实现步骤交给具体子类

    使用频率:中

    场景:数据库【mysql,oracle,mssql】操作 链接-操作-关闭

    注意:钩子是在模板步骤中预先定义一个空方法,由子类继承决定钩子是否使用【步骤是可选的,类似if do】,工厂方法是模板方法的一种特殊版本

    UML类图:

    23.访问者

    定义:注重对象操作变化,运行时为类添加新的操作

    使用频率:低

    场景:如新来一个邻居,我们去拜访,邻居会有开门,接待,倒水这些相应动作【这些动作一定要恒定】,换个邻居一样是这种操作

    注意:多对多【固定数目】的关系,所以要求数据结构相对稳定,增加访问者容易,但数据结构增加一种麻烦就会很麻烦【需改动原有访问者,违反开闭原则】

    UML类图:

    总结

    模式是在某情境下,针对某问题的某种解决方案
    情境:应用某个模式的情况,这应该是会不断出现的情况
    问题:是你在某情境下达到的目标,但也可以是某情境下的约束
    解决方案:就是你追求的,一个通用的设计,用来解决约束、达到目标

    设计模式是解决一个经常重复发生的设计问题

    尽可能用最简单的方式解决问题【不要写个HelloWorld也要扯上模式】,模式只是一种工具,只有在需要时才用,模式是设计问题的一种解决方案

    遵循设计原则,建立最简单的代码完成工作,在这个过程中,看到需要设计模式的地方,才使用模式

    当代码有很多if else switch这种条件性的语句时下就可以考虑优化重构代码了

    其他

    开发注意

      找出会变化的方面,把它们从不变的部分分离出来

      变量不可以有具体类的引用

      不要类派生自具体类【会依赖具体类】

      不要覆盖类中已实现的方法【说明方法不适合继承,没达到共性】

    继承是编译时运行,组合【对象关联】则是运行时运行,所以继承趋于稳定,组合则趋于灵活

    设计模式固然好,但我们得清楚,设计模式会增加代码复杂度,二维还好,维度越多,耦合越高,可读性越差

    MVC是一种复合设计模式【涵盖多个】

    V 控件组合模式
    M 观察者,模型改变,控制器,视图跟着改变
    C 视图和模型策略 换C就是更换策略

  • 相关阅读:
    5-1 CSS命名规范
    npm
    Maven的安装与配置
    Emmet
    计算机常识——IP/TCP协议
    判别分析——距离判别
    R语言创建空向量、矩阵
    Rstudio——基本功能及操作
    R语言——source函数
    R语言关于warning问题——关于options函数
  • 原文地址:https://www.cnblogs.com/dalas/p/9516758.html
Copyright © 2011-2022 走看看