开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 27 天,点击查看活动详情
SOLID 原则是一种设计原则,在应用时有助于创建易于维护和扩展新功能的软件设计。它们是一组由 Robert C.
SOLID 是五个设计原则的首字母缩写,旨在使软件设计更易于理解、更灵活和更易于维护。他们是:
- 单一职责 原则(SRP) ——一个类应该有一个,而且只有一个改变的理由。每个模块或类都应该对软件提供的功能的单个部分负责,并且该职责应该完全由类封装。
这个原则如何帮助我们构建更好的软件? 让我们看看它的一些好处:
- 测试——一个只负责一个类的测试用例会少得多。
- 较低的耦合——单个类中的较少功能将具有较少的依赖性。
- 组织——较小的、组织良好的类比单一的类更容易搜索。
例子:
一个类应该只有单一的责任(即只对软件规范的一部分进行更改应该在同一个类中进行)。
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();
}
}