ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【架构师之路】三、设计模式

2021-09-19 22:01:29  阅读:138  来源: 互联网

标签:框架 原则 子类 设计 模块 基类 架构师 设计模式


面向对象编程与面向对象分析

面向对象编程不是使用面向对象的编程语言进行编程,而是利用多态特性进行编程。

面向对象分析是将客观世界,即编程的业务领域进行对象分析。

  • 充血模型与贫血模型

  • 领域驱动设计DDD

面向对象设计的目的和原则

软件设计的最终目的,是使软件达到「强内聚、松耦合」,从而使软件:

  • 易扩展-易于增加新的功能

  • 更强壮-不容易被粗心的程序员破坏

  • 可移植-能够在多样的环境下运行

  • 更简单-容易理解、容易维护

面向对象设计的原则

  • 为了达到上述设计目标,有人总结了多种指导原则

  • 「原则」是独立于编程语言的,甚至也可以用于非面向对象的编程语言中。

设计模式

设计模式是用于解决某一种问题的通用的解决方案。设计模式也是语言中立的。设计模式贯彻了设计原则。

  • 创建模式

  • 行为模式

  • 结构模式

框架(frameworks)

框架是用来实现某一类应用的结构性的程序,是对某一类架构方案可复用的设计与实现

  • 如同框架结构的大厦的框架

  • 简化应用开发者的工作

  • 实现了多种设计模式,使应用开发者不需要花太大的力气,就能设计出结构良好的程序来

不同领域的框架

  • 微软公司为 Windows 编程开发了 MFC 框架。

  • Java 为它的 GUI 开发了 AWT 框架

  • 还有许多开源的框架:MyBatis、Spring 等

  • Web 服务器也是框架:Tomcat

框架 VS 工具

框架调用应用程序代码 应用程序代码调用工具

架构师框架保证架构的落地 架构师用工具提高开发效率

软件设计的「臭味」

不好的软件,会发出如下臭味

  • 僵硬-不易改变

  • 【僵化性】如果单一的改动会导致依赖关系的模块中的连锁改动,那么设计就是僵化的,必须要改动的模块越多,设计就越僵化。

  • 脆弱-只想改A,结果 B 被意外破坏

  • 【脆弱性】如果出现新问题的地方与改动的地方没有概念上的关联。要修正这些问题又会引出更多的问题,从而使开发团队就像一只不停追逐自己尾巴的狗一样。

  • 不可移植-不能适应环境的变化

  • 【牢固性】设计中包含了对其他系统有用的部分,而把这些部分从系统中分离出来所需要的努力和风险是巨大的。

  • 导致误用的陷阱-做错误的事比做正确的事更容易,引诱程序员破坏原有的设计

  • 【粘滞性】可以保持系统设计的方法比破坏设计的方法更难应用时。

  • 晦涩-代码难以理解

  • 【晦涩性】没有很好的表现出意图

  • 过度设计、copy-paste 代码

  • 【不必要的复杂与重复】

OOD 原则一:开闭原则(OCP)

OCP-OPEN/Closed Principle

  • 对于扩展是开放的

  • 对于更改是封闭的

  • 不需要修改软件实体(类、模块、函数等),就应该能实现功能的扩展。

传统的扩展模块的方式就是修改模块的源代码。如何实现不修改而扩展呢?

  • 关键是抽象

Phone-Dialer-digitButtons-sendButton【观察者模式】

OOD 原则二:依赖倒置原则(DIP)

DIP - Dependency Inversion Principle

  • 高层模块不能依赖低层模块,而是大家都依赖抽象;

  • 抽象不能依赖实现,而是依赖抽象。

DIP 倒置了什么?

  • 模块或包的依赖关系

  • 开发顺序和职责

软件的层次化

  • 高层决定低层

  • 高层被重用

图片

框架的核心

好莱坞规则:

  • Don’t call me,I’ll call you.

程序不要调用框架,框架来调用应用程序。【依赖倒置:你想用框架,但不用去调用框架(spring,Junit,Tomcat)】

OOD 原则三:Liskov 替换原则(LSP)

在 Java/C++ 这样的静态类型语言中,实现 OCP 的关键在于抽象,而抽象的威力在于多态和继承。

  • 一个正确的继承要符合什么要求呢?

  • 答案:Liskov 替换原则

1988 年 Liskov 描述这个原则:

  • 若对每个类型 T1 的对象 o1,都存在一个类型 T2 的对象 o2,使得在所有针对 T2 编写的程序 P 中,用 o1 替换 o2后,程序 P 的行为功能不变,则 T1 是 T2的子类型。

  • 简言之:子类型(subtype)必须能够替换掉它们的基类型(base type)

错误示范 【使用基类的地方,不能用子类代替】

  • 形状:圆,方形

  • JDK:hashtable-Properties;Vector-Stack

  • 计算面积时,正方形做长方形的子类

从契约的角度看  LSP

  • LSP 要求,凡是使用基类的地方,一定也适用于其子类。

  • Java 语法上看,意味着:

  • 子类一定得拥有基类的整个接口。

  • 子类的访问控制不能比基类更严格。

  • 子类的契约不能比基类更严格

  • 例如,正方形长度相等,这个契约比长方形要严格,因此正方形不是长方形的子类

  • 例如,Properties 的契约比 Hashtbale 更严格。

如何重构代码,以解决 LSP 问题

  1. 提取共性到基类;

  2. 改成组合

继承 VS 组合

继承和组合是 OOP 的两种扩展手段。

继承的优点:

  • 比较容易,因为基类的大部分功能都可以通过继承直接进入子类。

继承的缺点:

  • 破坏封装,将基类细节暴露给子类,继承是白盒复用

  • 基类改变,影响子类

  • 继承是静态的,无法在运行时改变组合

  • 类数量爆炸

应该优先使用组合

OOD 原则四:单一职责原则(SRP)

SRP - Single Responsibility Principle

  • 也叫内聚性原则(Cohesion)

  • 一个模块的组成元素之间的功能相关性

  • 将它与引起一个模块改变的作用力相连,就形成了如下描述

  • 一个类,只能有一个引起它的变化的原因

什么是职责?

  • 单纯谈论,定义不同

  • 定义:一个职责是一个变化的原因。

违反 SRP 原则的后果

后果:

  • 脆弱性-把绘图和计算功能耦合在一起,当修改其中一个时,另一个功能可能会意外受损

  • 不可移植性-计算几何应用只需要使用「计算面积」的功能,却不得不包含 GUI 的依赖。

OOD 原则五:接口分离原则(ISP)

ISP- interface Segregation Principle

  • 不应该强迫客户程序依赖它们不需要的方法

ISP 和 SRP 的关系:

  • ISP 和 SRP 相关,都和内聚性有关

  • SRP 指出应该如何设计一个类–只能有一种原因才能促使类发生改变。

  • ISP 指出应该如何设计一个接口–从客户需求出发,强调不要让客户看到他们不需要的方法。

推荐书:敏捷软件开发

标签:框架,原则,子类,设计,模块,基类,架构师,设计模式
来源: https://blog.csdn.net/u013129932/article/details/120385330

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有