本文已参与「新人创作礼」活动, 一起开启掘金创作之路。
开闭原则
开闭原则是最基础也是最重要的一个原则 开闭原则的定义很简单就是对修改关闭,对扩展打开
举个例子:我每天计划学5个小时,对于学5个小时是不需要修改的,但是我学完了5个小时,当然可以去干别的事情
一个工程被很多地方引用到,要是修改了这个类,不免会出现想不到的错误,所有有了新需求应该扩展,而不是去修改。
遵循开闭原则可以带来很大的好处。
/**
* 获取价格的接口
*
* @author yang
* @date 2022/1/1
*/
public interface Money {
double getMoney(int price, int count);
}
/**
* 正常价的类
*
* @author yang
* @date 2022/1/1
*/
public class DangDang implements Money {
@Override
public double getMoney(int price, int count) {
return price * count;
}
}
这是一个书城类平时都是原价买,要是双十一搞活动打折那岂不是要修改这个类,不符合开闭原则
那就应该扩展一个折扣类出来
/**
* 打折的类
*
* @author yang
* @date 2022/1/1
*/
public class discountDangDang extends DangDang{
public double discount; // 折扣
public discountDangDang(double discount) {
this.discount = discount;
}
@Override
public double getMoney(int price, int count) {
return price * count * discount;
}
public static void main(String[] args) {
Money dangDang = new DangDang();
Money discountDangDang = new discountDangDang(0.7);
System.out.println("原价是:"+ dangDang.getMoney(10, 1)+"元 优惠后是"+ discountDangDang.getMoney(10,1) + "元");
// 原价是:10.0元 优惠后是7.0元
}
}
依赖倒置原则
对于依赖倒置原则的定义:高层模块不应该依赖于底层模块,二者都应该依赖就抽象
- 细节依赖就抽象,抽象不依赖于细节
- 面向接口编程,尽量不要针对实现编程
public class Yang {
public void readJava() {
System.out.println("读java的书");
}
public void readCpp() {
System.out.println("读c++的书");
}
}
public class Test {
public static void main(String[] args) {
Yang y = new Yang();
y.readCpp();
y.readJava();
}
}
这样写Test是高层完全依赖于Yang也就是底层模块,这些完全违背了依赖倒置原则,改造一下
public class Yang {
public void readBook(Book book) {
book.readBook();
}
}
interface Book {
void readBook();
}
class CppBook implements Book {
@Override
public void readBook() {
System.out.println("阅读c++的数");
}
}
class JavaBook implements Book {
@Override
public void readBook() {
System.out.println("阅读java的书");
}
}
class Test {
public static void main(String[] args) {
Yang y = new Yang();
y.readBook(new CppBook());
y.readBook(new JavaBook());
}
}
这样Test高层和Yang底层这个类就解耦合了看什么书由Test自己选择,Yang和具体的实现也没有耦合,只于Book这个接口有耦合,
这就是面向接口编程
抽象远远比细节要稳定的多
单一职责原则
对于单一职责原则的定义:不要存在多与一个导致类更改的原因
实现遵循的规则
- 一个类、接口、方法只负责一个功能
这个比较好理解就不写代码了,真实的开发中,类可以看情况来用单一职责,不然会出现类过多,对于接口和方法就最好采用单一职责了, 维护起来也很方便,代码的逻辑也非常清晰
接口隔离原则
对于接口隔离原则的定义:用多个专门的接口,而不使用单一的接口,客户端不应该依赖他不需要的接口
实现遵循的规则
- 一个类对一个类的依赖应该建立在最小的接口上
和单一职责原则差不多
迪米特原则
定义:一个对象应该对其他对象保持最少的了解,也叫最少知道原则
实现遵循的规则
- 强调只对朋友交流,不和陌生人接触
- 朋友就是成员变量,方法中的输入和输出变量
里氏替换原则
定义比较复杂简单来说就是子类必须能替换父类
举个例子:鸟是一个类,企鹅也是一种鸟,如果让企鹅去继承鸟,那就错了,企鹅根本不会飞, 我们在他们基础之上在抽象就一个动物就可以了,让企鹅去继承动物。
当子类替换掉父类,功能不受影响,父类才真正被复用
组合复用原则
定义:尽量使用组合或者聚合,而不是继承关系来达到复用
总结:这么多设计原则都是在找出抽象,减低耦合提高内聚