- 本文已参与「新人创作礼」活动,一起开启掘金创作之路。
前言
自己最近在学习Java的设计模式,本篇讲的是设计模式常用七大设计原则的单一职责原则和接口隔离原则。自己每记录一些知识笔记就会首发在CSDN博客上,能够确保学习完设计模式之后,能够对其有一定程度上的理解和知识记录,形成一个相对不错的知识点框架,来在寒假记录自己学习的点点滴滴。希望大家喜欢💗
一、为什么要学习设计模式?
在编写软件的过程中,设计模式是为了让软件具有更好的以下优点:
代码重用性(相同功能的代码不用多次编写)可读性(编程规范性,便于其他程序员的阅读和理解)可扩展性(当需要增加新的功能时,非常的方便)可靠性(当增加新的功能后,对原来的功能没有影响)使程序呈现高内聚、低耦合的特性
二、常用的七大原则
单一职责原则接口隔离原则依赖倒转原则里氏替换原则开闭原则迪米特法则合成复用原则
三、单一职责原则
1、基本介绍
对类来说,一个类应该只负责一项职责。如果类A负责两个不同的职责:职责1、职责2。当职责1需求变更而改变A时,可能造成职责2执行错误,所以需要将类A分解为A1、A2。
这么说有点抽象,下面用代码来演示一下,化抽象为具体。
2、代码对比
代码一:
public class class01 {
public static void main(String[] args) {
Vehicle1 vehicle = new Vehicle1();
vehicle.run("汽车");
vehicle.run("飞机");
vehicle.run("轮船");
}
}
class Vehicle1 {
public void run(String vehicle){
System.out.println(vehicle + "在高速上行驶");
}
}
通过代码一可以看出,这样设计的结果是:飞机和轮船也是在高速上行驶,违反了单一职责原则,这显然是错误的。接下来看看代码二,与其对比一下。
代码二:
public class class02 {
public static void main(String[] args) {
VehicleRoad road = new VehicleRoad();
road.run("汽车");
VehicleWater water = new VehicleWater();
water.run("轮船");
}
}
class VehicleRoad {
public void run(String vehicle) {
System.out.println(vehicle + "在高速上行驶");
}
}
class VehicleWater {
public void run(String vehicle) {
System.out.println(vehicle + "在水中行驶");
}
}
通过代码二,我们根据交通工具运行方法不同,分解成不同的类,解决了代码一的问题。但是有一个问题就是,这样很浪费资源,改动很大。貌似不太完美,接下来看看代码三
代码三:
public class class03 {
public static void main(String[] args) {
Vehicle2 vehicle = new Vehicle2();
vehicle.runRoad("汽车");
vehicle.runWater("轮船");
}
}
class Vehicle2{
public void runRoad(String vehicle){
System.out.println(vehicle + "在高速上行驶");
}
public void runWater(String vehicle){
System.out.println(vehicle + "在水中行驶");
}
}
代码三通过修改方法,与代码二比较,对原来的类没有做很大的修改,只是增加方法。这里虽然没有在类这个级别上遵守单一职责原则,但是在方法级别上,仍然是遵守单一职责原则。
3、注意事项和使用细节
要降低类的复杂度,一个类只负责一项职责确保提高类的可读性,可维护性降低变更引起的风险通常情况下,我们应当遵守单一职责原则,只有逻辑 足够简单,才可以在代码级别违反单一职责原则;只有类中方法数量足够少,可以在方法级别保持单一职责原则
四、接口隔离原则
1、基本介绍
客户端不应该依赖它不需要的接口,一个类对另一个类的依赖应该建立在最小的接口上。
先看看一张图:
代码一:
public class class01 {
public static void main(String[] args) {
A a = new A();
a.method1(new B());
C c = new C();
c.method2(new D());
}
}
interface Interface1{
void opertion1();
void opertion2();
void opertion3();
void opertion4();
void opertion5();
}
class B implements Interface1{
public void opertion1() {
System.out.println("B 实现了 operation1");
}
public void opertion2() {
System.out.println("B 实现了 operation2");
}
public void opertion3() {
System.out.println("B 实现了 operation3");
}
public void opertion4() {
System.out.println("B 实现了 operation4");
}
public void opertion5() {
System.out.println("B 实现了 operation5");
}
}
class D implements Interface1{
public void opertion1() {
System.out.println("D 实现了 operation1");
}
public void opertion2() {
System.out.println("D 实现了 operation2");
}
public void opertion3() {
System.out.println("D 实现了 operation3");
}
public void opertion4() {
System.out.println("D 实现了 operation4");
}
public void opertion5() {
System.out.println("D 实现了 operation5");
}
}
class A { // A 类 通过接口Interface1 依赖 B类,但只使用1、2、3方法
public void method1(Interface1 interface1){
interface1.opertion1();
}
public void method2(Interface1 interface1){
interface1.opertion2();
}
public void method3(Interface1 interface1){
interface1.opertion3();
}
}
class C { // C 类 通过接口Interface1 依赖 D类,但只使用1、4、5方法
public void method1(Interface1 interface1){
interface1.opertion1();
}
public void method2(Interface1 interface1){
interface1.opertion4();
}
public void method3(Interface1 interface1){
interface1.opertion5();
}
}
代码一中,类A通过接口Interface1 依赖类B,类C通过接口Interface1 依赖类D,因为接口Interface1 对于类A 和类C来说不是最小接口,所以要想实现图片的功能,需要实现接口的所有方法,违反了接口隔离原则! 接下来看看代码二,与其对比一下。
代码二:
public class class02 {
public static void main(String[] args) {
AA aa = new AA();
aa.method1(new BB());
CC cc = new CC();
cc.method1(new DD());
}
}
interface Interface2{
void opertion1();
}
interface Interface3{
void opertion2();
void opertion3();
}
interface Interface4{
void opertion4();
void opertion5();
}
class BB implements Interface2,Interface3{
public void opertion1() {
System.out.println("BB 实现了operation1");
}
public void opertion2() {
System.out.println("BB 实现了operation2");
}
public void opertion3() {
System.out.println("BB 实现了operation3");
}
}
class DD implements Interface2,Interface4{
public void opertion1() {
System.out.println("DD 实现了operation1");
}
public void opertion4() {
System.out.println("DD 实现了operation4");
}
public void opertion5() {
System.out.println("DD 实现了operation5");
}
}
class AA {
public void method1(Interface2 interface2){
interface2.opertion1();
}
public void method2(Interface3 interface3){
interface3.opertion2();
}
public void method3(Interface3 interface3){
interface3.opertion3();
}
}
class CC {
public void method1(Interface2 interface2){
interface2.opertion1();
}
public void method2(Interface4 interface4){
interface4.opertion4();
}
public void method3(Interface4 interface4){
interface4.opertion5();
}
}
代码二的UML类图:
代码二采用了接口隔离原则。根据实际情况,把代码一中的接口Interface1拆分成三个接口,即最小接口。这样就完美的去除了类BB和类DD不用实现他们不需要的方法