设计模式的六大原则是软件工程中的基本概念,使得构建可维护、可扩展和可重用的代码。
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
学习分享输出是一种对大脑的刺激