设计模式之美
2019-12-18 09:44:25 0 举报
AI智能生成
设计模式总结
作者其他创作
大纲/内容
设计模式
设计原则与思想
面向对象
什么是面向对象
面向对象的特性
封装
封装也叫作信息隐藏或者数据访问保护。类通过暴露有限的访问接口,授权外部仅能通过类提供的方式(或者叫函数)来访问内部信息或者数据
主要讲的是如何隐藏信息、保护数据
意义
访问受限,保证数据的一致性
提高类的易用性
将属性封装起来,暴露少许的几个必要的方法给调用者使用,调用者就不需要了解太多背后的业务细节,用错的概率就减少很多
语法支持
private、protected、public
抽象
讲的是如何隐藏方法的具体实现,让调用者只需要关心方法提供了哪些功能,并不需要知道这些功能是如何实现的
接口类、抽象类、函数(方法)
只关注功能点不关注实现的设计思路
根据一些抽象性的设计原则指导设计,开闭、单一等
方法名、类名定义
继承
是用来表示类之间的 is-a 关系
extends
代码复用
重用父类的属性和方法
可以通过抽象类,实现多态特性
反应真是从属关系
多态
多态是指,子类可以替换父类,在实际的代码运行过程中,调用子类的方法实现
语法机制
编程语言要支持父类对象可以引用子类对象
编程语言要支持继承
编程语言要支持子类可以重写(override)父类中的方法
实现方法
继承加子类重写
接口类
静态语言-java
有传参限制,而动态类型的没有
利用 duck-typing 语法。
动态语言-python
只要两个类具有相同的方法,就可以实现多态,并不要求两个类之间有任何关系,这就是所谓的 duck-typing
多态特性能提高代码的可扩展性和复用性
只需增加新的实现类并实现接口的方法,不需要修改调用时的方法
接口和抽象类的区别
特性
抽象类
抽象类不允许被实例化,只能被继承
抽象类可以包含属性和方法。方法既可以包含代码实现,也可以不包含代码实现。不包含代码实现的方法叫作抽象方法
子类继承抽象类,必须实现抽象类中的所有抽象方法
接口不能包含属性(也就是成员变量)。
类实现接口的时候,必须实现接口中声明的所有方法
接口只能声明方法,方法不能包含代码实现。
解决什么问题
子类继承抽象类-代码复用
?继承普通类也可以实现代码复用,使用抽象类的必要性
如果父类没有定义子类的方法,是无法使用多态特性(通过父类调用子类的方法)
如果父类定义了子类的方法,为空或者有具体的实现
如果是为空,影响代码可读性
子类可能忘记重写父类的方法,因为不是强制的,抽象类必须重写
父类可以被实例化,这样就可能会调用父类的方法,而不是子类的,容易出错
抽象类更多的是为了代码复用,而接口就更侧重于解耦。接口是对行为的一种抽象,相当于一组协议或者契约
接口实现了约定和实现相分离,可以降低代码间的耦合性,提高代码的可扩展性
什么使用使用
为了解决代码复用的问题,是一种自下而上的设计思想
接口
为了解决抽象而非代码复用的问题,是一种自上而下的设计思想
如何正确使用继承和组合
继承改写成组合,意味着定义更多的类和接口,增加维护成本
继承可以通过组合、接口、委托三个技术手段
is-a关系可以通过组合和接口的has-a关系类替代
多态可以利用接口来实现
代码复用可以通过委托来实现
当没有权限父类,只能通过继承重写父类的方法
实战
模型
贫血模型
只包含数据不包含业务逻辑的类
贫血模型将数据与操作分离,破坏了面向对象的封装性,是一种典型的面向过程的编程风格
充血模型
数据和对应的业务逻辑被封装到同一个类中
满足面向对象的封装特性,是典型的面向对象编程风格
充血模型主要是针对service层的改变
针对domain的处理封装在领域对象中
service层主要起到连接和组合的作用
service主要与repository交互,可以保持领域模型的独立
service负责跨领域模型的业务聚合、以及一些非功能比如幂等、事物、邮件、消息、日志、调用其他rpc接口等
controller和repository还是使用贫血模型
repository层中entity生命周期有限,一般传递到service就被转换成bo
controller层vo作为数据传输对象,不包含相关业务方法
鉴权实战
面向对象分析
面向对象设计
根据需求描述,把其中涉及的功能点,一个一个罗列出来,功能点尽可能要小,每个功能点只负责一件事情«然后再去看哪些功能点职责相近,操作同样的属性,可否应该归为同一个类
对负责的系统可以先进行模块划分。再罗列功能点
具体分析方法
根据罗列出的功能点看都和哪个相关,可以作为类
识别需求中的名词作为类的属性
识别名词相关的动词,作为类的方法
对上面筛选出的进行筛选
设计原则
一个类或者模块只负责完成一个职责或者功能
定义
目的是实现代码高内聚、低耦合,提高代码的复用性、可读性、可维护性
类中的代码行数、函数或者属性过多,会影响代码的可读性和可维护性,就需要考虑对类的职责进行更细致的划分,拆成不同职责的类
类依赖的其他类过多,或者依赖类的其他类过多,不符合高内聚、低耦合的设计思想,也要考虑进行拆分。依赖其他类过多,耦合性增加
私有方法过多,就要考虑能否将私有方法独立到新的类中,设置为 public 方法,供更多的类使用,从而提高代码的复用性
比较难给类起一个合适名字,很难用一个业务名词概括,或者只能用一些笼统的 Manager、Context 之类的词语来命名,这就说明类的职责定义得可能不够清晰
类中大量的方法都是集中操作类中的某几个属性,比如,在 UserInfo 中,如果一半的方法都是在操作 address 信息,那就可以考虑将这几个属性和对应的方法拆分出来
如何判断类的职责是否单一
单一化的目的是实现代码高内聚、低耦合,提高代码的复用性、可读性、可维护性,应该在此前提下进行合理的职责单一化,不是为了单一化儿单一化,要结合实际的业务场景
拆分的过细会降低代码的内聚性,也会增加维护成本
注意过渡单一化
单一职责( Single Responsibility Principle,缩写为 SRP)
对扩展开放、对修改封闭
提高可扩展性
考虑未来可能的需求变更,
扩展意识、抽象意识、封装意识
如何做到ocp
开闭原则(Open Closed Principle,简写为 OCP)
是用来指导,继承关系中子类该如何设计的一个原则
定义:子类对象(object of subtype/derived class)能够替换程序(program)中父类对象(object of base/parent class)出现的任何地方,并且保证原来程序的逻辑行为(behavior)不变及正确性不被破坏。
父类定义了函数的“约定”(或者叫协议),那子类可以改变函数的内部实现逻辑,但不能改变函数原有的“约定”。这里的约定包括:函数声明要实现的功能;对输入、输出、异常的约定;甚至包括注释中所罗列的任何特殊说明
类似于接口和实现类的要求
里式替换原则
接口隔离原则
0 条评论
回复 删除
下一页