设计模式学习心得 - 面向对象的设计思想

文章目录

  • 面向对象
    • 特性
    • 优点
    • 常见误区
    • 抽象类和接口
    • 基于接口编程而非实现编程
    • 多用组合少用继承
    • 贫血模式的MVC架构 和 充血模型DDD对比
  • 评判代码的几个维度

面向对象

特性

封装:作用是信息保护,类通过暴露有限的接口,让外部通过函数来访问内部数据。
抽象:隐藏方法的具体实现,调用者只需关心方法提供了哪些功能,忽略如何实现。
继承:表示类之间is-a的关系,便于代码复用。
多态:子类可以替换父类/接口。提高代码的可扩展性、可复用性。

优点

  1. 把大规模的场景拆分为多个类,设计类之间的交互关系,应对复杂程序的开发。
  2. 基于四大特性,能写出易复用,易扩展,易维护的代码。
  3. 人性化,更贴近人的思考方式,容易理解。

常见误区

  • 滥用getter、setter方法:违背了封装性,给用户带来过度的自由,可能会导致数据不一致。比如get到一个属性List infos,那用户就可以随意操作infos的元素了,此时并没有更新该类中和infos数据关联的其他属性。

  • 滥用全局变量和全局方法:
    问题一:
    大而全的Consotant类(存全局常量)要避免,容易造成冲突影响代码可维护性,增加代码编译时间,也会让其他模块引入大量的无效常量影响复用性。
    解决方案:分为多个类,AConstants,BConstants。

    问题二:
    Utils类 ,大的Utils类(存全局方法)也有上面的问题。

抽象类和接口

抽象类是is-a的关系,为了解决代码复用问题。
接口是has-a的关系,表示具有某一组行为特征,解耦。 接口的本质是一组约定,是功能提供者给使用者的一个功能列表。

基于接口编程而非实现编程

  • 接口中函数的命名不能包含任何细节,否则以后实现类出现替换类会很麻烦。
  • 封装具体的细节。
  • 为实现类定义抽象的接口。使用者依赖接口,不依赖接口实现。

多用组合少用继承

举个接+组合+委托的例子:

public interface Runable{
	void run();
}

public class RunAbility implements Runable{
	void run(){
		//具体实现
	}
}

public class Chicken implements Runable,Flyable{  //接口
	private RunAbility runAbility= new RunAbility();  //组合
	private FlyAbility flyAbility = new Flyability(); //组合

	public void run(){  
		runAbility.run(;  //委托
	}
	
	public void fly(){
		flyability.fly(;
	}
}

继承有三种作用,表示类之间的is-a关系、解决代码复用的问题、支持多态的特性。这三个作用可以通过组合、接口、委托来达成。为了避免但继承层次过深,过复杂影响代码的课维护性,我们应该少用继承。

贫血模式的MVC架构 和 充血模型DDD对比

贫血模型中,VO、BO、Entity都属于纯粹的数据结构,业务逻辑主要在Service层中,这种模型将操作和数据分离,破坏了面向对象的封装特性,是一种典型的面向过程的风格。但对于业务不复杂的系统来说,这种模型简单而且够用。

充血模型要数据和对应的业务逻辑封装到同一个类中,属于面向对象的风格。DDD(Domain Driven Design)领域驱动设计。和贫血模型相比,该模型把业务逻辑放到Domain中,Service变得很薄,此时Service层负责的事情是:和Repository打交道、调用多个领域模型、和其他系统交互(记日志、发消息、事务、RPC等)

基于充血模型的DDD和贫血模型相比,Controller层和Repository层基本一样,差异主要是在Service层。

评判代码的几个维度

  • 可维护性: 在不破坏原有设计,不引入bug的情况下,快速地修改或者添加代码。
  • 可读性: 编码符合规范、命名合适、注释详尽、函数长短合适、模块划分清晰、高内聚低耦合
  • 可扩展性:在不修改或者少修改代码的情况下,通过扩展添加新的代码。
  • 简洁性:思从深而行从简。
  • 可复用性:减少重复代码的编写。
  • 可测试性:写的代码要容易写单元测试。

你可能感兴趣的:(设计模式,设计模式)