设计模式-六大原则

设计模式的六大原则是软件工程中的基本概念,使得构建可维护、可扩展和可重用的代码。
1.单一职责原则(Single Responsibility Principle):一个类或方法应该只有一个引起变化的原因,确保类或模块的功能高度内聚。
案例:

public class Affair {
    public void study(String animal){
        System.out.println(animal+"学习了");
    }
}
public class Client {
    public static void main(String[] args) {
      Affair affair=new Affair();
      affair.study("张三");
    }
}

遵循单一职责原则的优点有:
1.可以降低类的复杂度,一个类只负责一项职责,其逻辑肯定要比负责多项职责简单的多;
2.提高类的可读性,提高系统的可维护性;
3.变更引起的风险降低,变更是必然的,如果单一职责原则遵守的好,当修改一个功能时,可以显著降低对其他功能的影响。

2.开闭原则(Open-Closed Principle):软件实体(如类、模块等)应对扩展开放,对修改封闭。这意味着系统可以轻易地增加新功能而不需要修改已有的代码。

3.里氏替换原则(Liskov Substitution Principle):子类应该能够替换其基类,而不会改变程序的正确性。这保证了继承体系中的类型安全。
里氏替换原则:子类可以扩展父类的功能,但不能改变父类原有的功能。
1.子类可以实现父类的抽象方法,但不能覆盖父类的非抽象方法。
2.子类中可以增加自己特有的方法。
3.当子类的方法重载父类的方法时,方法的前置条件(即方法的形参)要比父类方法的输入参数更宽松。
4.当子类的方法实现父类的抽象方法时,方法的后置条件(即方法的返回值)要比父类更严格。
案例:

public class Student {
    public double grossScore(double m,double n){
        return m+n;
    }
}

public class Student1 extends Student{
    public double grossScore(double m,double n){
        return m+n;
    }

    public double average(double m,double n){
        return (m+n)/2;
    }
}
public class Client {
    public static void main(String[] args) {
        Student student=new Student();
        System.out.println("学生总分数为:"+student.grossScore(98.3, 81.3));

        Student1 student1=new Student1();
        System.out.println("学生平均分数为:"+student1.average(98.3, 81.3));
    }
}

4.依赖倒置原则(Dependency Inversion Principle):高层模块不应直接依赖于低层模块,而是都应该依赖于抽象。抽象不应该依赖细节,细节应该依赖抽象。这有助于减少代码之间的耦合,提高系统的可维护性。

public interface Campaign {
    String getMovement();
}

public class Exercise {
    public void motion(Campaign campaign){
        System.out.println("开始运动了");
        System.out.println(campaign.getMovement());
    }
}
public class BasketBall implements Campaign{

    @Override
    public String getMovement() {
        return "打篮球咯!!!";
    }
}

public class Football implements Campaign{
    @Override
    public String getMovement() {
        return "踢足球了咯!!!";
    }
}
public class Client {
    public static void main(String[] args) {
        Exercise exercise=new Exercise();
        exercise.motion(new BasketBall());
        exercise.motion(new Football());
    }
}

在这里插入图片描述
5.接口隔离原则(Interface Segregation Principle):客户端不应被要求依赖它们不需要的接口。这有助于减少类对接口的依赖,提高系统的灵活性和可重用性。
反例,代码臃肿:

//接口
public interface ConnectorsA {
    void methodA();
    void methodB();
    void methodC();
    void methodD();
    void methodE();
}
//调用
public class BasicsA {
    public void dependA(ConnectorsA connectorsA){
        connectorsA.methodA();
    }
    public void dependB(ConnectorsA connectorsA){
        connectorsA.methodB();
    }
    public void dependC(ConnectorsA connectorsA){
        connectorsA.methodC();
    }
}
//接口实现
public class BasicsADepend implements ConnectorsA {

    @Override
    public void methodA() {
        System.out.println("类BasicsDepend实现接口ConnectorsA的方法A");
    }

    @Override
    public void methodB() {
        System.out.println("类BasicsDepend实现接口ConnectorsA的方法B");
    }

    @Override
    public void methodC() {
        System.out.println("类BasicsDepend实现接口ConnectorsA的方法C");
    }

    @Override
    public void methodD() {
    }

    @Override
    public void methodE() {
    }
}
//调用
public class BasicsB {
    public void dependA(ConnectorsA connectorsA){
        connectorsA.methodA();
    }
    public void dependB(ConnectorsA connectorsA){
        connectorsA.methodD();
    }
    public void dependC(ConnectorsA connectorsA){
        connectorsA.methodE();
    }
}
//接口实现
public class BasicsBDepend implements ConnectorsA {
    @Override
    public void methodA() {
        System.out.println("类BasicsBDepend实现接口ConnectorsA的方法A");
    }
    @Override
    public void methodB() {

    }
    @Override
    public void methodC() {

    }
    @Override
    public void methodD() {
        System.out.println("类BasicsBDepend实现接口ConnectorsA的方法D");
    }
    @Override
    public void methodE() {
        System.out.println("类BasicsBDepend实现接口ConnectorsA的方法E");
    }
}
//Test
public class Client {
    public static void main(String[] args) {
        BasicsA basicsA=new BasicsA();
        basicsA.dependA(new BasicsADepend());
        basicsA.dependB(new BasicsADepend());
        basicsA.dependC(new BasicsADepend());

        BasicsB basicsB=new BasicsB();
        basicsB.dependA(new BasicsBDepend());
        basicsB.dependB(new BasicsBDepend());
        basicsB.dependC(new BasicsBDepend());
    }
}

使得接口分离优化为正例:

//接口拆分
public interface ConnectorsA1 {
    void methodA();
}
//接口拆分
public interface ConnectorsA2 {
    void methodB();
    void methodC();
}
//接口拆分
public interface ConnectorsA3 {
    void methodD();
    void methodE();
}
//调用
public class BasicsA {
    public void dependA(ConnectorsA1 connectorsA1){
        connectorsA1.methodA();
    }
    public void dependB(ConnectorsA2 connectorsA2){
        connectorsA2.methodB();
    }
    public void dependC(ConnectorsA2 connectorsA2){
        connectorsA2.methodC();
    }
}
//接口实现
public class BasicsADepend implements ConnectorsA1,ConnectorsA2 {

    @Override
    public void methodA() {
        System.out.println("类BasicsDepend实现接口ConnectorsA1的方法A");
    }
    @Override
    public void methodB() {
        System.out.println("类BasicsDepend实现接口ConnectorsA2的方法B");
    }
    @Override
    public void methodC() {
        System.out.println("类BasicsDepend实现接口ConnectorsA2的方法C");
    }
}
//调用
public class BasicsB {
    public void dependA(ConnectorsA1 connectorsA1){
        connectorsA1.methodA();
    }
    public void dependB(ConnectorsA3 connectorsA1){
        connectorsA1.methodD();
    }
    public void dependC(ConnectorsA3 connectorsA3){
        connectorsA3.methodE();
    }
}
//接口实现
public class BasicsBDepend implements ConnectorsA1,ConnectorsA3 {
    @Override
    public void methodA() {
        System.out.println("类BasicsBDepend实现接口ConnectorsA1的方法A");
    }
    @Override
    public void methodD() {
        System.out.println("类BasicsBDepend实现接口ConnectorsA3的方法D");
    }
    @Override
    public void methodE() {
        System.out.println("类BasicsBDepend实现接口ConnectorsA3的方法E");
    }
}
//Test
public class Client {
    public static void main(String[] args) {
        BasicsA basicsA=new BasicsA();
        basicsA.dependA(new BasicsADepend());
        basicsA.dependB(new BasicsADepend());
        basicsA.dependC(new BasicsADepend());

        BasicsB basicsB=new BasicsB();
        basicsB.dependA(new BasicsBDepend());
        basicsB.dependB(new BasicsBDepend());
        basicsB.dependC(new BasicsBDepend());
    }
}

采用接口隔离原则对接口进行约束时,要注意
1.接口尽量小,要适度。对接口进行细化,提高程序设计灵活性。过小,则会造成接口数量过多,使设计复杂化,即要适度。
2.为依赖接口的类定制服务,只暴露给调用的类它需要的方法,不需要的方法则隐藏起来。只有专注地为一个模块提供定制服务,才能建立最小的依赖关系。
3.提高内聚,减少对外交互。使接口用最少的方法去完成最多的事情。

6.迪米特法则(Law of Demeter):一个对象应对其他对象有最少的了解。这有助于降低类之间的耦合度,提高系统的稳定性和可维护性。
反例:一集团公司,下属单位有分公司和直属部门,现在要求打印出所有下属单位的员工ID。

//总公司
public class Employee {
    private String id;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }
}
//分公司
public class SubEmployee {
    private String id;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }
}
//分公司ID管理
public class SubCompanyManager {
    public List<SubEmployee> getAllEmployeee(){
        List<SubEmployee> list = new ArrayList<>();
        for (int i = 0; i < 20; i++) {
            SubEmployee employee = new SubEmployee();
            employee.setId("分公司"+i);
            list.add(employee);
        }
        return list;
    }
}
//总公司ID管理
public class CompanyManager {
    public List<Employee> getAllWmployee(){
        ArrayList<Employee> list = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            Employee employee = new Employee();
            employee.setId("总公司"+i);
            list.add(employee);
        }
        return list;
    }

    public void printAllEmployee(SubCompanyManager subCM){
        List<SubEmployee> allEmployeee = subCM.getAllEmployeee();
        for (SubEmployee subEmployee : allEmployeee) {
            System.out.print(subEmployee.getId()+" ");
        }
        System.out.println();
        System.out.println("------------------------------------------------------------");
        List<Employee> allWmployee = this.getAllWmployee();
        for (Employee employee : allWmployee) {
            System.out.print(employee.getId()+" ");
        }
    }
}
//Test
public class Client {
    public static void main(String[] args) {
        CompanyManager companyManager = new CompanyManager();
        companyManager.printAllEmployee(new SubCompanyManager());
    }
}

优化CompanyManager后

public class SubCompanyManager {
    public List<SubEmployee> getAllEmployeee(){
        List<SubEmployee> list = new ArrayList<>();
        for (int i = 0; i < 20; i++) {
            SubEmployee employee = new SubEmployee();
            employee.setId("分公司"+i);
            list.add(employee);
        }
        return list;
    }
    public void printEmployee(){
        List<SubEmployee> list = this.getAllEmployeee();
        for (SubEmployee subEmployee : list) {
            System.out.print(subEmployee.getId());
        }
    }
}

public class CompanyManager {
    public List<Employee> getAllWmployee(){
        ArrayList<Employee> list = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            Employee employee = new Employee();
            employee.setId("总公司"+i);
            list.add(employee);
        }
        return list;
    }

    public void printAllEmployee(SubCompanyManager subCM){
        subCM.printEmployee();
        System.out.println();
        System.out.println("------------------------------------------------------------");
        List<Employee> allWmployee = this.getAllWmployee();
        for (Employee employee : allWmployee) {
            System.out.print(employee.getId()+" ");
        }
    }
}

优化后:达到解耦

转自:https://www.cnblogs.com/bruce1992/p/15096265.html
学习分享输出是一种对大脑的刺激

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值