1.基本介绍
1.七大原则介绍
2.设计模式的目的
2.单一职责原则
1.基本介绍
2.代码演示
1.违反单一职责原则
- 由于只有一个run方法来决定运行,所以飞机只能调用run方法
- 但是run方法是负责在公路上运行的,而飞机不是在公路上运行的,不应该由这个run方法来处理
package com.sun.principle.singleresponseibility;
/**
* Description: 单一职责原则
*
* @Author sun
* @Create 2024/5/6 20:12
* @Version 1.0
*/
public class SingleResponsibility1 {
public static void main(String[] args) {
Vehicle vehicle = new Vehicle();
vehicle.run("汽车");
vehicle.run("火车");
vehicle.run("飞机");
}
}
class Vehicle {
public void run(String vehicle) {
System.out.println(vehicle + "在公路上运行");
}
}
2.基本符合单一职责原则
- 虽然在类上没有符合单一职责原则,但是在方法的级别符合
package com.sun.principle.singleresponseibility;
/**
* Description: 单一职责原则
*
* @Author sun
* @Create 2024/5/6 20:12
* @Version 1.0
*/
public class SingleResponsibility2 {
public static void main(String[] args) {
Vehicle2 vehicle = new Vehicle2();
vehicle.RoadRun("汽车");
vehicle.RoadRun("火车");
vehicle.AirRun("飞机");
}
}
class Vehicle2 {
public void RoadRun(String vehicle) {
System.out.println(vehicle + "在公路上运行");
}
public void AirRun(String vehicle) {
System.out.println(vehicle + "在天空上运行");
}
}
3.注意事项和细节
4.小结
一个类只履行一个职责,在代码量少的情况下可以一个方法履行一个职责
3.接口隔离原则
1.基本介绍
2.代码演示
1.违反接口隔离原则
package com.sun.principle.segreation1;
/**
* Description: 违反接口隔离原则
*
* @Author sun
* @Create 2024/5/7 20:22
* @Version 1.0
*/
public class Segreation1 {
public static void main(String[] args) {
}
}
/**
* 一个接口中有五个方法
*/
interface Interface1 {
void operation1();
void operation2();
void operation3();
void operation4();
void operation5();
}
/**
* 类B实现了接口中的五个方法
*/
class B implements Interface1 {
@Override
public void operation1() {
System.out.println("B中实现了operation1");
}
@Override
public void operation2() {
System.out.println("B中实现了operation2");
}
@Override
public void operation3() {
System.out.println("B中实现了operation3");
}
@Override
public void operation4() {
System.out.println("B中实现了operation4");
}
@Override
public void operation5() {
System.out.println("B中实现了operation5");
}
}
/**
* 类D实现了接口中的五个方法
*/
class D implements Interface1 {
@Override
public void operation1() {
System.out.println("D中实现了operation1");
}
@Override
public void operation2() {
System.out.println("D中实现了operation2");
}
@Override
public void operation3() {
System.out.println("D中实现了operation3");
}
@Override
public void operation4() {
System.out.println("D中实现了operation4");
}
@Override
public void operation5() {
System.out.println("D中实现了operation5");
}
}
/**
* 类A只依赖接口的3个方法
*/
class A {
public void depend1(Interface1 interface1) {
interface1.operation1();
}
public void depend2(Interface1 interface1) {
interface1.operation2();
}
public void depend3(Interface1 interface1) {
interface1.operation3();
}
}
/**
* 类C只依赖接口的2个方法
*/
class C {
public void depend4(Interface1 interface1) {
interface1.operation4();
}
public void depend5(Interface1 interface1) {
interface1.operation5();
}
}
2.符合接口隔离原则
package com.sun.principle.segreation1;
/**
* Description:
*
* @Author sun
* @Create 2024/5/7 20:49
* @Version 1.0
*/
public class Segreation2 {
}
interface interface2 {
void operation1();
}
interface interface3 {
void operation2();
void operation3();
}
interface interface4 {
void operation4();
void operation5();
}
/**
* 依赖1,2,3方法
*/
class B2 implements interface2, interface3 {
@Override
public void operation1() {
}
@Override
public void operation2() {
}
@Override
public void operation3() {
}
}
/**
* 依赖1,4,5方法
*/
class C2 implements interface2, interface4 {
@Override
public void operation1() {
}
@Override
public void operation4() {
}
@Override
public void operation5() {
}
}
3.小结
将接口拆分为最小接口,使得客户端“一依赖,全使用”
4.依赖倒转原则
1.基本介绍
2.代码演示
1.违反依赖倒转原则
- 这样设计,如果用户要接受微信,QQ的信息,就需要再写一个方法
- 解决思路:引入一个抽象的接口IReceiver,使细节依赖抽象
package com.sun.principle.invergation;
/**
* Description: 依赖倒置原则
*
* @Author sun
* @Create 2024/5/16 19:21
* @Version 1.0
*/
public class DependcyInversion {
public static void main(String[] args) {
// 一个人
Person person = new Person();
// 一个人接收邮件,并获取邮件的信息
person.receive(new Email());
}
}
/**
* 一个邮件类,有一个方法可以获取邮件的信息
*/
class Email {
public String getInfo() {
return "电子邮件信息:hello";
}
}
/**
* 一个人可以通过邮件类来获取邮件的信息
*/
class Person {
public void receive(Email email) {
System.out.println(email.getInfo());
}
}
2.满足依赖倒转原则
- 这里使用了一个Message接口来表示所有的消息,使用Email来实现了消息的接口,表示这个是一个Email消息
- 用户直接接受了一个消息类型,这样不管具体是什么消息,用户都可以直接获取那个消息的信息
package com.sun.principle.invergation.improve;
/**
* Description: 依赖倒置原则
*
* @Author sun
* @Create 2024/5/16 19:21
* @Version 1.0
*/
public class DependcyInversion {
public static void main(String[] args) {
// 一个人
Person person = new Person();
// 一个人接收邮件,并获取邮件的信息
person.receive(new Email());
}
}
/**
* 一个抽象的接口,表示要接受的信息
*/
interface Message {
String getInfo();
}
/**
* 一个邮件类,有一个方法可以获取邮件的信息
*/
class Email implements Message {
@Override
public String getInfo() {
return "电子邮件信息:hello";
}
}
/**
* 一个人可以通过邮件类来获取邮件的信息
*/
class Person {
public void receive(Message message) {
System.out.println(message.getInfo());
}
}
3.细节说明
- 每个类最好有抽象类或者接口,不要直接写一个类,要依赖抽象的
5.里氏替换原则
1.基本介绍
2.代码演示
1.违反里氏替换原则
- 由于B类重写了A类的方法,但是在调用时可能还认为func1是两个数相减的结果,所以可能会导致程序运行不正常
- 简单来说,就是要求,子类在继承父类的时候完全具备父类的一切能力,尽量不要去重写父类的方法
package com.sun.principle.liskov;
/**
* Description:
*
* @Author sun
* @Create 2024/5/16 20:05
* @Version 1.0
*/
public class Liskov {
public static void main(String[] args) {
A a = new A();
System.out.println("11-3=" + a.func1(11, 3));
System.out.println("1-8=" + a.func1(1, 8));
System.out.println("==============");
B b = new B();
// 由于B类重写了A类的方法,但是在调用时可能还认为func1是两个数相减的结果,所以可能会导致程序运行不正常
System.out.println("11-3=" + b.func1(11, 3));
System.out.println("1-8=" + b.func1(1, 8));
System.out.println("11 + 3 + 9 = " + b.func2(11, 3));
}
}
/**
* 类A,实现了两个参数相减
*/
class A {
public int func1(int num1, int num2) {
return num1 - num2;
}
}
/**
* B类继承A类,重写了func1的方法,使其变为两个参数相加
* 新增一个func2方法,调用B类的func1方法
*/
class B extends A {
@Override
public int func1(int num1, int num2) {
return num1 + num2;
}
public int func2(int a, int b) {
return func1(a, b) + 9;
}
}
2.满足历史替换原则
- 让A类和B类都继承一个更加基础的类型,实现了A和B类的解耦,这样就不会认为B类和A类有相同含义的方法了
- 这个时候如果B类想要使用A类的方法,可以使用组合的方式
package com.sun.principle.liskov.improve;
/**
* Description:
*
* @Author sun
* @Create 2024/5/16 20:05
* @Version 1.0
*/
public class Liskov {
public static void main(String[] args) {
A a = new A();
System.out.println("11-3=" + a.func1(11, 3));
System.out.println("1-8=" + a.func1(1, 8));
System.out.println("==============");
B b = new B();
// 由于A类和B类没有关系,所以就不会认为两个类的方法有相同的意思
System.out.println("11+3=" + b.func1(11, 3));
System.out.println("1+8=" + b.func1(1, 8));
System.out.println("11 - 3 + 9 = " + b.func2(11, 3));
}
}
class Base {
// 将更基础的方法,放到Base类中
}
/**
* 类A,实现了两个参数相减,继承基础类
*/
class A extends Base{
public int func1(int num1, int num2) {
return num1 - num2;
}
}
/**
* 类B,继承基础类
* 新增一个func2方法,调用B类的func1方法
*/
class B extends Base {
// B类想要使用A类的方法,采用组合的方式
private A a = new A();
public int func1(int num1, int num2) {
return num1 + num2;
}
public int func2(int a, int b) {
return this.a.func1(a, b) + 9;
}
}
3.小结
- 当子类继承父类的时候,尽量不要去重写父类的方法,子类应该具备父类全部的方法
6.开闭原则(最基础,最重要)
7.迪米特法则
1.基本介绍
2.细节
3.小结
- 直接朋友分为三种,属性,方法的参数,方法的返回值
- 迪米特法则就是只与直接朋友进行通信,陌生的类不要以局部变量的形式出现在类的内部
- 简单点来说,一个陌生的类要么作为类的属性,要么就作为方法的参数或者返回值,这就是迪米特法则