设计模式-七大设计原则

发布于:2024-05-17 ⋅ 阅读:(90) ⋅ 点赞:(0)

1.基本介绍

1.七大原则介绍

image-20240506200212888

2.设计模式的目的

image-20240506200522050

2.单一职责原则

1.基本介绍

image-20240506200923088

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 + "在公路上运行");
    }
}

image-20240506201808523

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 + "在天空上运行");
    }
}

image-20240506202721106

3.注意事项和细节

image-20240506203002086

4.小结

一个类只履行一个职责,在代码量少的情况下可以一个方法履行一个职责

3.接口隔离原则

1.基本介绍

image-20240507201421233

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.基本介绍

image-20240516192014784

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.细节说明
  • 每个类最好有抽象类或者接口,不要直接写一个类,要依赖抽象的

image-20240516195926395

5.里氏替换原则

1.基本介绍

image-20240516200136414

image-20240516200433091

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;
    }
}


image-20240516201606972

2.满足历史替换原则
  • 让A类和B类都继承一个更加基础的类型,实现了A和B类的解耦,这样就不会认为B类和A类有相同含义的方法了
  • 这个时候如果B类想要使用A类的方法,可以使用组合的方式

image-20240516201802990

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.开闭原则(最基础,最重要)

image-20240516203308765

7.迪米特法则

1.基本介绍

image-20240516205105284

2.细节

image-20240516210601943

3.小结
  • 直接朋友分为三种,属性,方法的参数,方法的返回值
  • 迪米特法则就是只与直接朋友进行通信,陌生的类不要以局部变量的形式出现在类的内部
  • 简单点来说,一个陌生的类要么作为类的属性,要么就作为方法的参数或者返回值,这就是迪米特法则

8.合成复用原则

1.基本介绍

image-20240516211054592

2.具体实例

image-20240516211712668

9.设计原则核心思想

image-20240516211958597


网站公告

今日签到

点亮在社区的每一天
去签到