LOGO OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 开发文档 其他文档  
 
网站管理员

面向对象编程的SOLID 原则

admin
2024年12月4日 18:2 本文热度 331

在本文中,将介绍 SOLID 原则,并且将通过 Java 代码示例来帮助你理解每个原则。SOLID 原则是面向对象编程中使用的一组五个设计原则。遵循这些原则将帮助你开发健壮的软件,使你的代码更高效、可读和可维护。

SOLID 是以下原则的缩写:

  • 单一职责原则
  • 开闭原则
  • 里氏替换原则
  • 接口隔离原则
  • 依赖倒置原则

单一职责原则

单一职责原则规定每个类必须有单一、明确的职责。

public class Employee{
   public String getDesignation(int employeeID){ // }
   public void updateSalary(int employeeID){ // }
   public void sendMail(){ // }
}

在上述示例中,Employee 类有一些特定于员工类的行为,如获取职位(getDesignation)和更新薪水(updateSalary)。此外,它还有一个名为 sendMail 的方法,该方法偏离了 Employee 类的职责。此行为并非该类所特有的,拥有它违反了单一职责原则。要解决此问题,可以将 sendMail 方法移动到单独的类中,如下所示:

public class Employee{
   public String getDesignation(int employeeID){ // }
   public void updateSalary(int employeeID){ // }
}

public class NotificationService {
   public void sendMail() { // }
}

开闭原则

根据开闭原则,组件必须对扩展开放,但对修改关闭。为了理解这个原则,让我们以一个计算面积的类为例。

public class AreaCalculator(){
   public double area(Shape shape){
       double areaOfShape;
       if(shape instanceof Square){
           // 计算正方形的面积
       } else if(shape instanceof Circle){
           // 计算圆形的面积
       }
       return areaOfShape;
   }
}

上述示例的问题在于,如果将来有一个新的 Shape 类型实例需要计算面积,你必须通过添加另一个条件 else - if 块来修改上述类。对于每个新的 Shape 类型对象,你都要这样做。

要解决这个问题,可以创建一个接口,并让每个 Shape 实现此接口。然后,每个类可以提供自己的计算面积的实现。

interface IAreaCalculator(){
   double area();
}

class Square implements IAreaCalculator{
   @Override
   public double area(){
       System.out.println("Calculating area for Square");
       return 0.0;
   }
}

class Circle implements IAreaCalculator{
   @Override
   public double area(){
       System.out.println("Calculating area for Circle");
       return 0.0;
   }
}

里氏替换原则

里氏替换原则规定,你必须能够用子类对象替换父类对象,而不影响程序的正确性。

abstract class Bird{
   abstract void fly();
}

class Eagle extends Bird {
   @Override
   public void fly() { // 一些实现 }
}

class Ostrich extends Bird {
   @Override
   public void fly() { // 虚拟实现 }
}

在上述示例中,Eagle 类和 Ostrich 类都扩展了 Bird 类并覆盖了 fly() 方法。然而,Ostrich 类被迫提供一个虚拟实现,因为它不能飞,因此如果我们用它替换 Bird 类对象,它的行为就不一样了。

这违反了里氏替换原则。要解决此问题,我们可以为能飞的鸟创建一个单独的类,让 Eagle 扩展它,而其他鸟可以扩展一个不同的类,该类不包含任何飞行行为。

abstract class FlyingBird{
   abstract void fly();
}

abstract class NonFlyingBird{
   abstract void doSomething();
}

class Eagle extends FlyingBird {
   @Override
   public void fly() { // 一些实现 }
}

class Ostrich extends NonFlyingBird {
   @Override
   public void doSomething() { // 一些实现 }
}

接口隔离原则

根据接口隔离原则,你应该构建小而专注的接口,不强迫客户端实现他们不需要的行为。

一个简单的例子是有一个计算形状面积和体积的接口。

interface IShapeAreaCalculator{
   double calculateArea();
   double calculateVolume();
}

class Square implements IShapeAreaCalculator{
   double calculateArea(){ // 计算面积 }
   double calculateVolume(){ // 虚拟实现 }
}

问题在于,如果 Square 形状实现了这个接口,那么它被迫实现 calculateVolume() 方法,而它并不需要这个方法。另一方面,Cube 可以同时实现这两个方法。

要解决此问题,我们可以隔离接口,有两个单独的接口:一个用于计算面积,另一个用于计算体积。这将允许单个形状决定要实现什么。

interface IAreaCalculator {
   double calculateArea();
}

interface IVolumeCalculator {
   double calculateVolume();
}

class Square implements IAreaCalculator {
   @Override
   public double calculateArea() { // 计算面积 }
}

class Cube implements IAreaCalculator, IVolumeCalculator {
   @Override
   public double calculateArea() { // 计算面积 }
   @Override
   public double calculateVolume() {// 计算体积 }
}

依赖倒置原则

在依赖倒置原则中,高层模块不应该依赖低层模块。换句话说,你必须遵循抽象并确保松散耦合。

public interface Notification {
   void notify();
}

public class EmailNotification implements Notification {
   public void notify() {
       System.out.println("Sending notification via email");
   }
}

public class Employee {
   private EmailNotification emailNotification;

   public Employee(EmailNotification emailNotification) {
       this.emailNotification = emailNotification;
   }

   public void notifyUser() {
       emailNotification.notify();
   }
}

在给定的示例中,Employee 类直接依赖于 EmailNotification 类,这是一个低层模块。这违反了依赖倒置原则。

public interface Notification{
   public void notify();
}

public class Employee{
   private Notification notification;

   public Employee(Notification notification){
       this.notification = notification;
   }

   public void notifyUser(){
       notification.notify();
   }
}

public class EmailNotification implements Notification{
   public void notify(){
       // 通过电子邮件实现通知
   }
}

public static void main(String [] args){
   Notification notification = new EmailNotification();
   Employee employee = new Employee(notification);
   employee.notifyUser();
}

在上述示例中,我们确保了松散耦合。Employee 不依赖于任何具体实现,而是仅依赖于抽象(通知接口)。如果我们需要更改通知方式,可以创建一个新的实现并将其传递给 Employee。

结论

在本文中,我们通过示例深入剖析了SOLID原则。这些原则是构建高质量软件的关键,对软件的扩展性和可维护性意义重大。 单一职责原则让类职责单一,使代码简洁易维护。开闭原则使系统可灵活扩展,减少修改成本。里氏替换原则保障继承体系合理可靠,维持程序行为一致。接口隔离原则助于设计简洁接口,提升代码可读性。依赖倒置原则构建松散耦合关系,增强系统灵活性。 这些原则构成了开发高度可扩展和可重用应用程序的基石。


该文章在 2024/12/4 18:02:01 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2024 ClickSun All Rights Reserved