设计模式的六大原则是软件工程中的基本概念,使得构建可维护、可扩展和可重用的代码。
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{@Overridepublic String getMovement() {return "打篮球咯!!!";}
}
public class Football implements Campaign{@Overridepublic 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 {@Overridepublic void methodA() {System.out.println("类BasicsDepend实现接口ConnectorsA的方法A");}@Overridepublic void methodB() {System.out.println("类BasicsDepend实现接口ConnectorsA的方法B");}@Overridepublic void methodC() {System.out.println("类BasicsDepend实现接口ConnectorsA的方法C");}@Overridepublic void methodD() {}@Overridepublic 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 {@Overridepublic void methodA() {System.out.println("类BasicsBDepend实现接口ConnectorsA的方法A");}@Overridepublic void methodB() {}@Overridepublic void methodC() {}@Overridepublic void methodD() {System.out.println("类BasicsBDepend实现接口ConnectorsA的方法D");}@Overridepublic 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 {@Overridepublic void methodA() {System.out.println("类BasicsDepend实现接口ConnectorsA1的方法A");}@Overridepublic void methodB() {System.out.println("类BasicsDepend实现接口ConnectorsA2的方法B");}@Overridepublic 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 {@Overridepublic void methodA() {System.out.println("类BasicsBDepend实现接口ConnectorsA1的方法A");}@Overridepublic void methodD() {System.out.println("类BasicsBDepend实现接口ConnectorsA3的方法D");}@Overridepublic 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
学习分享输出是一种对大脑的刺激