设计模式-六原则

1、单一职责原则

定义:不能存在多个导致类变更的原因;既:一个类只负责一个职责。

问题的原因:一个类class1负责两个不同的职责:P1,P2,如需职责P1需要变更类class1时,有可能导致可以正常运行的职责P2功能出现问题。

解决方案:遵循单一职责原则,一个类负责一个职责功能,要更改该职责是不会影响其他类的职责功能。

2、里氏替换原则

定义:所有引用基类的地方必须能透明的使用其子类的对象。

或:

子类对象可以在程序中替换父类对象;

或:

如果对每一个类型为 T1的对象 o1,都有类型为 T2 的对象o2,使得以 T1定义的所有程序 P 在所有的对象 o1 都代换成 o2 时,程序 P 的行为没有发生变化,那么类型 T2 是类型 T1 的子类型。

问题原因:功能P1由类A完成。需要对功能P1进行扩展,扩展后的功能为P,其中P由原来功能P1和新功能P2组成;新功能P由类A和子类B完成,则子类B完成新功能P2时可能原有功能P1发生故障。

解决方案:当使用继承时,遵循里氏替换原则。类B继承类A时,除了添加新的方法完成新增功能P2外,尽量不要重写父类A的方法,也尽量不要重载父类A的方法。

里氏替换原则通俗讲:子类可以扩展父类的功能,但不能改变父类原有的功能
包含以下含义:

  • 子类可以实现父类的抽像方法,但不能覆盖父类的非抽像方法
  • 子类中可以增加自己特有的方法;
  • 当子类要重载父类的方法时,方法的形参(既要传入的参数)要比父类方法输入的参数更宽松(参数多);
  • 当子类的方法实现父类的抽象方法时,方法的返回值要比父类更严格。

3、开闭原则

1、面向对象设计的基础原则,指导我们如何建立稳定灵活的系统;

2、软件设计中使用设计模式就是为了遵循开闭原则的;

3、用抽象构建框架,用实现扩展细节

定义:一个软件实体 如类、模块和方法(函数)应该对扩展开放,对修改关闭。

问题原因:在软件的生命周期内,因为变化、升级和维护等原因对软件的圆代码进行修改时,可能给旧代码引入错误,对整个功能进行重构, 并且需要对原有代码重新测试。

解决方案:当软件需要变化时,尽量通过扩展软件实体来实现变化,而不是通过修改原有代码来实现变化。

优点:可复用性,可维护性。

4、接口隔离原则

定义:客户端不应该依赖它不需要的接口;一个类对另一个类的依赖应建立在最小的接口上。

问题原因:类A通过接口 I 依赖类B,类D通过接口 I 依赖类D,如果接口 I 对于类A和类B来说不是最小接口,则类B和类D必须去实现他们不需要的方法。

解决方案:将臃肿的接口 I 拆分成多个接口,建立需要的依赖关系,即:接口隔离原则。

在这里插入图片描述

类A依赖接口 I 中的方法1、2、3,类B是对类A的实现;

类C依赖接口 I 中的方法1、4、5,类D是对类C的实现;

4.1、例子

接口 I:

interface I {
	public void method1();
	public void method2();
	public void method3();
	public void method4();
	public void method5();
}

类A:依赖类接口调用类B

class A{
	public void depend1(I i){
		i.method1();
	}
	public void depend2(I i){
		i.method2();
	}
	public void depend3(I i){
		i.method3();
	}
}

类B:实现接口

class B implements I{
	public void method1() {
		System.out.println("类B实现接口I的方法1");
	}
	public void method2() {
		System.out.println("类B实现接口I的方法2");
	}
	public void method3() {
		System.out.println("类B实现接口I的方法3");
	}
	//对于类B来说,method4和method5不是必需的,但是由于接口A中有这两个方法,
	//所以在实现过程中即使这两个方法的方法体为空,也要将这两个没有作用的方法进行实现。
	public void method4() {}
	public void method5() {}
}

类C:依赖接口调用类D

class C{
	public void depend1(I i){
		i.method1();
	}
	public void depend2(I i){
		i.method4();
	}
	public void depend3(I i){
		i.method5();
	}
}

类D:实现接口I

class D implements I{
	public void method1() {
		System.out.println("类D实现接口I的方法1");
	}
	//对于类D来说,method2和method3不是必需的,但是由于接口A中有这两个方法,
	//所以在实现过程中即使这两个方法的方法体为空,也要将这两个没有作用的方法进行实现。
	public void method2() {}
	public void method3() {}
 
	public void method4() {
		System.out.println("类D实现接口I的方法4");
	}
	public void method5() {
		System.out.println("类D实现接口I的方法5");
	}
}

Main:

public class Main{
	public static void main(String[] args){
		A a = new A();
		a.depend1(new B());
		a.depend2(new B());
		a.depend3(new B());
		
		C c = new C();
		c.depend1(new D());
		c.depend2(new D());
		c.depend3(new D());
	}
}

结果:接口过于臃肿。

接口分离原则

在这里插入图片描述

接口 I1:定义方法1

interface I1 {
	public void method1();
}

接口 I2:定义方法2、3

interface I2 {
	public void method2();
	public void method3();
}

接口 I3:定义方法4、5

interface I3 {
	public void method4();
	public void method5();
}

类A:依赖接口调用类B

class A{
	public void depend1(I1 i){
		i.method1();
	}
	public void depend2(I2 i){
		i.method2();
	}
	public void depend3(I2 i){
		i.method3();
	}
}

类B:实现接口 I1,I2

class B implements I1, I2{
	public void method1() {
		System.out.println("类B实现接口I1的方法1");
	}
	public void method2() {
		System.out.println("类B实现接口I2的方法2");
	}
	public void method3() {
		System.out.println("类B实现接口I2的方法3");
	}
}

类C:依赖接口调用类D

class C{
	public void depend1(I1 i){
		i.method1();
	}
	public void depend2(I3 i){
		i.method4();
	}
	public void depend3(I3 i){
		i.method5();
	}
}

类D:实现接口 I1,I3

class D implements I1, I3{
	public void method1() {
		System.out.println("类D实现接口I1的方法1");
	}
	public void method4() {
		System.out.println("类D实现接口I3的方法4");
	}
	public void method5() {
		System.out.println("类D实现接口I3的方法5");
	}
}

5、依赖倒转原则

定义:高层模块不应该依赖底层模块,两者都应依赖其抽象;抽象不应该依赖细节,细节应该依赖抽象。

问题原因:类A直接依赖类B,若要将类A改为依赖类C,则必须要更改类A的代码,带来极高的风险。

类A一般是高层模块,负责复杂的业务逻辑;

类B和类C是底层模块,负责基本的原子操作。

解决方案:将类A改为依赖接口 I,类B和类C各自实现接口 I,类A通过接口 I 间接联系类B和类C。

5.1、例子

数据访问抽像层
在这里插入图片描述

编写业务代码的时候,不应该直接在业务代码处直接用jdbc操作数据库,而是通过数据访问层的抽象接口中间接访问,操作层再对接口进行实现。

数据访问操作层对代码进行更改则不会影响业务代码

6、迪米特法则

定义:软件实体应尽可能少的与其他实体发生相互作用。

降低软件类之间的耦合

问题原因:类与类之间关系越密切耦合度越高,一个类发生改变时,对另一个类的影响越大。

解决方案:尽量降低类与类之间的耦合度。


部分内容从csdn作者@割韭韭转载

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值