原文网址:Java设计模式--原则_IT利刃出鞘的博客-CSDN博客
简介
说明
本文介绍Java设计模式的原则,包括:单一职责原则,开闭原则, 里氏代换原则,依赖倒转原则,接口隔离原则,合成复用原则。
概述
对于面向对象软件系统的设计而言,在支持可维护性的同时,提高系统的可复用性是一个至关重要的问题,如何同时提高一个软件系统的可维护性和可复用性是面向对象设计需要解决的核心问题之一。
在面向对象设计中,可维护性的复用是以设计原则为基础的。面向对象设计原则也是我们用于评价一个设计模式的使用效果的重要指标之一,在设计模式的学习中,大家经常会看到诸如“XXX模式符合XXX原则”、“XXX模式违反了XXX原则”这样的语句。
一、单一职责原则(迪米特原则)
单一职责定义
一个类只负责一个功能领域中的相应职责,或者可以定义为:就一个类而言,应该只有一个引起它变化的原因。
又称为:迪米特法则、最少知道原则(Demeter Principle)
从定义中不难思考,一个类的所做的事情越多,也就越难以复用,因为一旦做的事情多了,职责的耦合度就变高了所以我们根据这个原则应该将不同职责封装在不同类中,不同的变化封装在不同类中。从我们平常的开发中不难发现,如果一个类或者方法接口等等只做一件事,那么可读性很高,并且复用性也很高,并且一旦需求变化,也容易维护,假如你一个类糅杂多个职责,那么很难维护。
单一职责举例分析
从实际业务来剥离一个例子:现在有这么一种情况,某租车平台个人模块类涉及多个方法,有如下登录、注册、支付宝押金支付、微信押金支付、支付宝套餐支付、微信套餐支付、整个结构如下:
/**
* 个人模块
*/
@Controller
public class userController{
/**
* 登录
*/
public void login(){
}
/**
* 注册
*/
public void register(){
}
/**
* 押金支付(阿里)
*/
public void payAliDeposit(){
}
/**
* 押金支付(微信)
*/
public void payWXDeposit(){
}
/**
* 套餐支付(阿里)
*/
public void payAliPackage(){
}
/**
* 套餐支付(微信)
*/
public void payWXPackage(){
}
}
我们可以看到很多功能都糅杂在一起,一个类做了那么多事情,很臃肿,别提维护,就连找代码都很困难,所以我们可以对这个UserController进行拆解,与此同时我们应该分包,比如这个应该在xxx.xxx.userMoudule下面,可能支付相关的有公共的方法,登录抑或也有公共的方法,那边抽成公共服务去调用。
public class LoginController(){}
public class RegisterController(){}
public class DepositPayController(){
// 支付宝支付
// 微信支付
}
public class PackagePayController(){
// 支付宝支付
// 微信支付
}
整个方案实现的目的就是为了解决高耦合,代码复用率低下的问题。
二、开闭原则
开闭原则简介
开闭原则是面向对象的可复用设计的第一块基石,它是最重要的面向对象设计原则,定义如下:一个软件实体应当对扩展开放,对修改关闭。即软件实体应尽量在不修改原有代码的情况下进行扩展。
软件实体包括以下几个部分:
- 项目或软件产品中按照一定的逻辑规则划分的模块
- 抽象和类
- 方法
注意:开闭原则是指对扩展开放,对修改关闭,并不是说不做任何的修改。
开闭原则的优势
- 可以使原来的测试代码依旧可以运行,只需要对扩展的代码进行测试即可
- 可以提高代码的复用性
- 可以提高系统的维护性
如何使用开闭原则
- 抽象约束
- 通过接口或者抽象类约束扩展,对扩展进行边界限定,不允许出现在接口或抽象类中不存在的public方法;
- 参数类型、引用对象尽量使用接口或者抽象类,而不是实现类;(针对抽象编程)
- 抽象层尽量保持稳定,一旦确定即不允许修改。
- 元数据控制模块行为
- 通俗来说就是通过配置文件来操作数据,spring的控制反转就是一个很典型的例子。
- 约定优于配置
- 封装变化
- 将相同的变化封装到一个接口或者类中
- 将不同的变化封装到不同的类或者接口中(单一职责的体现)
案例
上边只是部分内容,为便于维护,本文已迁移到此地址:Java设计模式-原则 - 自学精灵