发布于 2026-01-06 0 阅读
0

SOLID、KISS、YAGNI 和 DRY 原则

SOLID、KISS、YAGNI 和 DRY 原则

坚硬的

罗伯特·C·马丁和迈克尔·费瑟斯提出了这一原则,旨在鼓励我们创建更易于维护、更易于理解和更灵活的软件。该原则包含5个子原则:

  • 单一责任原则(SRP
  • 开/闭原理(OCP
  • 里氏替换原理(L SP)
  • 界面隔离原理(ISP
  • 依赖倒置原理(D IP)

单一职责原则(SRP)

该原则规定,每个班级应该只有一个职责。
建议零售价

如果一个类承担多个职责,那么更改其中一项职责可能会影响其他职责。

❌违反SRP:

public class Animal {
    public void catSays() {
        System.out.println("I am a cat.");
    }

    public void lionSays() {
        System.out.println("I am a lion.");
    }

    public void hippoSays() {
        System.out.println("I am a hippo.");
    }
}
Enter fullscreen mode Exit fullscreen mode

✔️遵循建议零售价:

public abstract class Animal {
    public abstract void makeSound();
}

public class Cat extends Animal {
    @Override
    public void makeSound() {
        System.out.println("I am a cat.");
    }
}

public class Lion extends Animal {
    @Override
    public void makeSound() {
        System.out.println("I am a lion.");
    }
}

public class Hippo extends Animal {
    @Override
    public void makeSound() {
        System.out.println("I am a hippo.");
    }
}
Enter fullscreen mode Exit fullscreen mode

开闭原理 - OCP

该原则规定,如果存在一个新函数,你不应该修改或添加到现有的类中,而应该编写另一个类来扩展现有的类。

有机氯农药

课程应该允许扩展,但不允许修改。

❌违反OCP:

public class Animal {
    private String type;

    public Animal(String type) {
        this.type = type;
    }

    public void draw() {
        if (type.equalsIgnoreCase("cat")) {
            System.out.println("Drawing a cat");
        } else if (type.equalsIgnoreCase("lion")) {
            System.out.println("Drawing a lion");
        }
        // More animals can be added here, violating OCP
    }
}
Enter fullscreen mode Exit fullscreen mode

✔️遵循OCP:

public abstract class Animal {
    public abstract void draw();
}

public class Cat extends Animal {
    @Override
    public void draw() {
        System.out.println("Drawing a cat");
    }
}

public class Lion extends Animal {
    @Override
    public void draw() {
        System.out.println("Drawing a lion");
    }
}

// You can add more animal classes without modifying existing code
Enter fullscreen mode Exit fullscreen mode

里氏替换原理 - LSP

该原则规定,继承自父类的子类可以替换父类,而不会影响程序的正确性。

本地化服务协议 (LSP)

子类应该能够处理与父类相同的请求并给出相同的结果,或者给出相同类型的结果。

❌违反LSP:

public class Animal
{
    public void run()
    {
        System.out.println("Run...");
    }

    public void fly()
    {
        System.out.println("Fly...");
    }
}

public class Bird extends Animal
{
    // Bird can fly and run...
}

public class Cat extends Animal
{
    // Cat can't fly...
}
Enter fullscreen mode Exit fullscreen mode

✔️ 遵循 LSP:

public interface Flyable {
    public void fly();
}

public class Animal
{
    public void run()
    {
        System.out.println("Run...");
    }
}

public class Bird extends Animal implements Flyable
{
    @Override
    public void fly()
    {
        System.out.println("Fly...");
    }
}

public class Cat extends Animal
{

}
Enter fullscreen mode Exit fullscreen mode

接口隔离原则 - ISP

这条原则规定,接口不应包含过多需要实现的方法。如果接口过大,则应将其拆分为多个处理不同功能的较小接口。

互联网服务提供商

任何代码都不应该被迫依赖它未使用的方法。类应该只执行履行其职责所必需的操作。

❌ 违反互联网服务提供商 (ISP) 规定:

interface Animal {
    List<Animal> getAll();
    get(String id);
    save(Animal animal);
    update(String id, Animal animal);
    delete(String id);
    getAllWithPaginate(int page, int size);
    getAllWithSort(String sortCriteria);
    /* ... */
}
Enter fullscreen mode Exit fullscreen mode

✔️ 关注 ISP:

interface CrudAnimal {
    List<Animal> getAll();
    get(String id);
    save(Animal animal);
    update(String id, Animal animal);
    delete(String id);
}

interface PagingAndSortingAnimal {
    getAllWithPaginate(int page, int size);
    getAllWithSort(String sortCriteria);
}
Enter fullscreen mode Exit fullscreen mode

依赖倒置原理(DIP)

这一原则规定:

  1. 高层模块不应该依赖于底层模块。两者都应该依赖于抽象概念。
  2. 抽象概念不应依赖于细节,细节应依赖于抽象概念。

蘸

该原则的核心在于避免依赖模块(即在编码过程中容易更改的特定组件),而应依赖抽象组件,因为这些组件的变更可能性较小。应用和实现该原则的方法是,由高层模块定义接口,然后由底层模块实现这些接口。

❌ 违反DIP:

// Abstraction
interface Animal {
    void makeSound();
}

// Low-level Module
class Cat implements Animal {
    @Override
    public void makeSound() {
        System.out.println("I am a cat");
    }
}

// Low-level Module
class Lion implements Animal {
    @Override
    public void makeSound() {
        System.out.println("I am a lion");
    }
}

// Low-level Module
class Hippo implements Animal {
    @Override
    public void makeSound() {
        System.out.println("I am a hippo");
    }
}

// High-level Module
class AnimalFactory {
    // High-level modules depend on low-level modules
    private final Cat animal;

    public AnimalFactory() {
        this.animal = new Cat();
        this.animal.makeSound();
    }

    public Cat getAnimal() {
        return this.animal;
    }
}

public class Main {
    public static void main(String[] args) {
        AnimalFactory factory = new AnimalFactory();
    }
}
Enter fullscreen mode Exit fullscreen mode

✔️ 遵循 DIP:

// Abstraction
interface Animal {
    void makeSound();
}

// Low-level Module
class Cat implements Animal {
    @Override
    public void makeSound() {
        System.out.println("I am a cat");
    }
}

// Low-level Module
class Lion implements Animal {
    @Override
    public void makeSound() {
        System.out.println("I am a lion");
    }
}

// Low-level Module
class Hippo implements Animal {
    @Override
    public void makeSound() {
        System.out.println("I am a hippo");
    }
}

// High-level Module
class AnimalFactory {
    // High-level modules depend on abstractions
    private final Animal animal;

    public AnimalFactory(Animal animal) {
        this.animal = animal;
        this.animal.makeSound();
    }

    public Animal getAnimal() {
        return this.animal;
    }
}

public class Main {
    public static void main(String[] args) {
        Animal animal = new Cat();
        AnimalFactory factory = new AnimalFactory(animal);
    }
}
Enter fullscreen mode Exit fullscreen mode

保持简单,笨蛋——KISS

凯利·约翰逊提出了这一原则,旨在强调代码简洁性的重要性。代码越简洁,阅读和理解的速度就越快,维护和修改也就越容易,这将有助于节省大量时间。

KISS原则的几种运用方式:

  • 除非必要,否则不要滥用设计模式或库。
  • 将大问题分解成小问题来处理。
  • 明确命名变量和方法。

你不需要它 - YAGNI

这条原则由肯特·贝克提出。它强调不要用对未来的假设来复杂化需求。换句话说,不要在需要使用软件之前就假设并构建其功能。

不要重复自己 - 干

DRY(Don't Repeat Yourself,不要重复自己)是编程行业中一个为人熟知的核心原则,它强调尽可能地重用代码。该原则由 Andrew Hunt 和 David Thomas 提出。

这一原则使得代码的重复性降低,从而更容易、更快速地更改代码段。

为了实现这一原则,每当有一段代码在不同的地方被使用了两次,你就应该重新打包这段代码(创建函数、创建类……),以便以后可以调用它。

参考

  1. SOLID 原则
  2. 代码整洁原则:DRY、KISS 和 YAGNI
文章来源:https://dev.to/nknghiem/solid-kiss-yagni-and-dry-principles-ie7