Java 中的 SOLID 原则是什么?

126 阅读3分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 27 天,点击查看活动详情

SOLID 原则是一种设计原则,在应用时有助于创建易于维护和扩展新功能的软件设计。它们是一组由 Robert C.

SOLID 是五个设计原则的首字母缩写,旨在使软件设计更易于理解、更灵活和更易于维护。他们是:

  1. 单一职责 原则(SRP)  ——一个类应该有一个,而且只有一个改变的理由。每个模块或类都应该对软件提供的功能的单个部分负责,并且该职责应该完全由类封装。

这个原则如何帮助我们构建更好的软件? 让我们看看它的一些好处:

  1. 测试——一个只负责一个类的测试用例会少得多。
  2. 较低的耦合——单个类中的较少功能将具有较少的依赖性。
  3. 组织——较小的、组织良好的类比单一的类更容易搜索。

例子:

一个类应该只有单一的责任(即只对软件规范的一部分进行更改应该在同一个类中进行)。

public class Car {  
  
    // Single responsibility of a car is to drive  
    public void drive() {  
            System.out.println("Car is driving");  
        }  
}
public class Charger {
// Charges the battery
 public void charge(){
  // code logic
  System.out.println("The battery is being charged");
 }
}

2.开闭原则(OCP)  ——软件实体应该对扩展开放,对修改关闭。设计应允许用户扩展对象的行为而无需修改它。

例子:

对象或实体应该对扩展开放,对修改关闭。

public interface Animal{
    void eat();
    void move();
}

public class Lion implements Animal{
  
    public void eat(){
        //Lion eating
    }
  
    public void move(){
        //Lion moving
    }
    
    //Added method in the implementation
    public void roar(){
        //Lion roaring
    }
    
}

3. Liskov 替换原则 (LSP)  — 程序中的对象应该可以用其子类型的实例替换,而不会改变该程序的正确性。

例子:

程序中的对象应该可以用其子类型的实例替换,而不会改变该程序的正确性。

public interface ImageStorage {  
  void storeImage(String image);  
}  

public class CloudImageStorage implements ImageStorage {  
  @Override  
  public void storeImage(String image) {  
    // connect to cloud storage 
    // upload image
  }  
}  
public class DatabaseImageStorage implements ImageStorage {  
  @Override  
  public void storeImage(String image) {  
    // connect to database 
    // save image 
  }  
} 
public class ImageUploader {  
  private ImageStorage imageStorage;  
  
  public ImageUploader(ImageStorage imageStorage) {  
     this.imageStorage = imageStorage;
  }  
  
  public void uploadImage(String image) {  
    // compress image 
    // resize image 
    // ... 
    this.imageStorage.storeImage(image);  
  }  
}

4.接口隔离原则(ISP)  ——不应该强迫客户依赖他们不使用的方法。许多特定于客户端的接口比一个通用接口要好。

例子:

不应强迫客户依赖于他们不使用的方法。许多特定于客户端的接口比一个通用接口要好。

public interface Animal { 
 
    public void eat(); 
    public void travel(); 
 } 
  
 //interface for animals that can fly 
 public interface Flyable { 
    public void fly(); 
 } 
  
 //interface for animals that can swim  
 public interface Swimmable { 
    public void swim(); 
 } 

//Bird class that implements both Flyable and Animal interfaces  
 public class Bird implements Flyable, Animal{ 
    public void eat(){ 
        //implement eat method 
    } 
    public void travel(){ 
        //implement travel method 
    } 
    public void fly(){ 
        //implement fly method 
    } 
 }
//Fish class that implements Swimmable and Animal interfaces  
 public class Fish implements Swimmable, Animal{ 
    public void eat(){ 
        //implement eat method 
    } 
    public void travel(){ 
        //implement travel method 
    } 
    public void swim(){ 
        //implement swim method 
    } 
 }

5.依赖倒置原则(DIP)  ——依赖于抽象,而不是具体化。依赖注入是这一原则的一种形式。

例子:

依赖于抽象,而不是具体化。依赖注入是这一原则的一种形式。

public interface IDataAccessor {
    public void saveData(String data);
    public void loadData();
}

public class FileSystemAccessor implements IDataAccessor {
    public void saveData(String data) {
        // Implementation of saving data to a file system.
    }
    public void loadData() {
        // Implementation of loading data from a file system.
    }
}
public class DatabaseAccessor implements IDataAccessor {
    public void saveData(String data) {
        // Implementation of saving data to a database.
    }
    public void loadData() {
        // Implementation of loading data from a database.
    }
}
public class HighLevelModule {
    private IDataAccessor dataAccessor;
    
    public HighLevelModule(IDataAccessor dataAccessor) {
        this.dataAccessor = dataAccessor;
    }
    
    public void saveData(String data) {
        dataAccessor.saveData(data);
    }
    
    public void loadData() {
        dataAccessor.loadData();
    }
}