设计模式之七大设计原则

最近跟着B站上 尚硅谷Java设计模式(图解+框架源码剖析) 视频学习了设计模式,现将其中的七大设计原则整理如下。

七大设计原则:

1)单一职责原则

2)接口隔离原则

3)依赖倒转原则

4)里氏替换原则

5)开闭原则(ocp原则)

6)迪米特法则

7)合成复用原则

1.单一职责原则

概念:对一个类来讲,一个类应该只负责一项职责。

拿Dao举例,userDao应该只负责关于User表的增删改查,而不应该负责Order表,那样会使得代码结构混乱。如果一个类负责多项职责,还可能由于不同功能间相互影响导致错误。

总的来说,单一职责原则的目的有以下几点:

1)降低类的复杂度,一个类只负责一项职责;

2)提高类的可读性、可维护性;

3)降低变更功能引起的风险

2.接口隔离原则

理解:一个类对另一个类的依赖应该建立在最小接口上。

简单点的例子:假设A类实现了B接口,那么在设计时,应该把A类用得到的方法放在在B接口中,尽量不要放用不到的方法,否则A在实现B接口时,也要实现那些用不到的方法。

复杂点的例子:假设有4个类:A,B,C,D,以及一个接口:a,a中有5个方法:m1,m2,m3,m4,m5。A通过接口a依赖C(比如A a=new A(new C()),而C实现了a接口),B通过接口a依赖D;A只会用到接口a中的m1,m2,m3方法,B只会用到接口a中的m1,m4,m5方法。也就是说,接口a对于A和B来说都不是最小接口,解决办法:把接口a拆分为最小接口:a1(包含m1方法),a2(包含m2,m3方法),a3(包含m4,m5方法),这时只需让C实现a1接口、a2接口,而D实现a1接口、a3接口,就避免了C、D去实现它们不用实现的方法。

3.依赖倒转原则

理解:1)高层模块不应该依赖底层模块,二者都应该依赖其抽象;

           2)抽象不应该依赖细节,细节应该依赖抽象;(在java中,抽象指的是接口或抽象类,细节就是具体的实现类)

           3)中心思想是面向接口编程

例子

public class Demo {
    public static void main(String[] args) {
        Person person = new Person();
        person.receive(new Email());
    }
}
class Email {
    public String getInfo() {
        return "电子邮件信息: hello,world";
    }
}

//完成Person接收消息的功能
//方式1分析
//1. 简单,比较容易想到
//2. 如果我们获取的对象是 微信,短信等等,则新增类,同时Perons也要增加相应的接收方法
//3. 解决思路:引入一个抽象的接口IReceiver, 表示接收者, 这样Person类与接口IReceiver发生依赖
//   因为Email, WeiXin 等等属于接收的范围,他们各自实现IReceiver 接口就ok, 这样我们就符号依赖倒转原则
class Person {
    public void receive(Email email ) {
        System.out.println(email.getInfo());
    }
}

改进

public class Demo{

	public static void main(String[] args) {
		//客户端无需改变
		Person person = new Person();
		person.receive(new Email());
		
		person.receive(new WeiXin());
	}

}

//定义接口
interface IReceiver {
	public String getInfo();
}

class Email implements IReceiver {
	public String getInfo() {
		return "电子邮件信息: hello,world";
	}
}

//增加微信
class WeiXin implements IReceiver {
	public String getInfo() {
		return "微信信息: hello,ok";
	}
}

//方式2
class Person {
	//这里我们是对接口的依赖
	public void receive(IReceiver receiver ) {
		System.out.println(receiver.getInfo());
	}
}

总的来说就是,类与类之间如果有依赖关系,尽量利用接口或抽象类作为中间缓冲层。

:依赖关系传递的三种方式:

       1)接口传递

       2)构造方法传递

       3)set方法传递

public class Demo{

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		ChangHong changHong = new ChangHong();
//		OpenAndClose openAndClose = new OpenAndClose();
//		openAndClose.open(changHong);
		
		//通过构造器进行依赖传递
//		OpenAndClose openAndClose = new OpenAndClose(changHong);
//		openAndClose.open();
		//通过setter方法进行依赖传递
		OpenAndClose openAndClose = new OpenAndClose();
		openAndClose.setTv(changHong);
		openAndClose.open();

	}

}

// 方式1: 通过接口传递实现依赖
// 开关的接口
// interface IOpenAndClose {
// public void open(ITV tv); //抽象方法,接收接口
// }
//
// interface ITV { //ITV接口
// public void play();
// }
// 
// class ChangHong implements ITV {
//
//	@Override
//	public void play() {
//		// TODO Auto-generated method stub
//		System.out.println("长虹电视机,打开");
//	}
//	 
// }
 实现接口
// class OpenAndClose implements IOpenAndClose{
// public void open(ITV tv){
// tv.play();
// }
// }

// 方式2: 通过构造方法依赖传递
// interface IOpenAndClose {
// public void open(); //抽象方法
// }
// interface ITV { //ITV接口
// public void play();
// }
// class OpenAndClose implements IOpenAndClose{
// public ITV tv; //成员
// public OpenAndClose(ITV tv){ //构造器
// this.tv = tv;
// }
// public void open(){
// this.tv.play();
// }
// }


// 方式3 , 通过setter方法传递
interface IOpenAndClose {
	public void open(); // 抽象方法

	public void setTv(ITV tv);
}

interface ITV { // ITV接口
	public void play();
}

class OpenAndClose implements IOpenAndClose {
	private ITV tv;

	public void setTv(ITV tv) {
		this.tv = tv;
	}

	public void open() {
		this.tv.play();
	}
}

class ChangHong implements ITV {

	@Override
	public void play() {
		// TODO Auto-generated method stub
		System.out.println("长虹电视机,打开");
	}
	 
}

4.里氏替换原则

针对编程时涉及到继承时的一种编码规范。

理解:1)所有引用基类的地方必须能透明地使用其子类的对象;

           2)子类中尽量不要重写父类的方法;

           3)如果两个类之间的关系不是那么密切,尽量不要使用继承,而通过组合、聚合、依赖来解决问题。

5.开闭原则(ocp原则)

理解:1)编程中最基础、最重要的设计原则

          2)一个类中的方法应该对扩展开放(提供方),对修改关闭(使用方)

例子与依赖倒转原则的例子相仿。开闭原则的侧重点在于,设计程序时,尽量利用接口、抽象类,使得在添加新功能时,尽量不修改或少修改代码,并且使用方的代码不用修改,ocp原则较好地可扩展性、可重用性。

下面的例子体现了ocp原则:

public class Ocp {

	public static void main(String[] args) {
		GraphicEditor graphicEditor = new GraphicEditor();
		graphicEditor.drawShape(new Rectangle());
		graphicEditor.drawShape(new Circle());
		graphicEditor.drawShape(new Triangle());
	}

}

//这是一个用于绘图的类 [使用方]
class GraphicEditor {
	//接收Shape对象,调用draw方法
	public void drawShape(Shape s) {
		s.draw();
	}

	
}

//Shape类,基类
abstract class Shape {
	int m_type;
	
	public abstract void draw();//抽象方法
}

class Rectangle extends Shape {
	Rectangle() {
		super.m_type = 1;
	}

	@Override
	public void draw() {
		// TODO Auto-generated method stub
		System.out.println(" 绘制矩形 ");
	}
}

class Circle extends Shape {
	Circle() {
		super.m_type = 2;
	}
	@Override
	public void draw() {
		// TODO Auto-generated method stub
		System.out.println(" 绘制圆形 ");
	}
}

//新增画三角形
class Triangle extends Shape {
	Triangle() {
		super.m_type = 3;
	}
	@Override
	public void draw() {
		// TODO Auto-generated method stub
		System.out.println(" 绘制三角形 ");
	}
}

6.迪米特法则(最少知道原则)

理解:1)一个对象应该对其他对象保持最少的了解

           2)只与直接的朋友通信;

           3)直接的朋友:如果两个对象之间有耦合关系,那么它们就是朋友关系,我们称 A类的对象作为成员变量、方法参数、方法返回值存在于B类中 时,A类就是B类的直接朋友;而如果A类的对象只作为局部变量存在于B类中,A类不是B类直接的朋友。迪米特法则讲的就是编程时不要出现陌生的朋友。

7.合成复用原则

理解:尽量使用合成/聚合的方式,而不是使用继承。

设计原则核心思想:

1)把可能产生变化的代码独立出来;

2)针对接口编程,而不是针对实现;

3)最终目的是松耦合。

继承、依赖、聚合、组合图解:

 

上面是我结合自己的理解以及视频上的笔记总结出来的,一些容易理解的我就没有粘代码出来。

这位博友写的文章也是按照视频总结出来的,所有代码都有粘上:原创-Java设计模式篇章1

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值