类 设置、获取和计算数据是否遵循 SOLID 中的 S?

Do classes that set, get and calculate data follow the S in SOLID?

假设我住在一个每个汽车品牌都有不同税率的国家,我有一个名为 Car 的基础 class:

public class Car{
    public string CarType { get; set;}
    public int Year {get; set;}
    public abstract double calculateSalesTax();
}

添加一个计算销售税的抽象方法可以吗?或者这是否已经打破了 SOLID 原则? SOLID 中 S 的通常准则是“如果在描述 class 时必须使用 AND 这个词,这很可能违反了原则”。在这里,计算销售税的方法的实现似乎需要 AND。 class 设置汽车的属性并计算其销售税。

所以如果我实现派生的 class

public class Volkswagen : Car{
    
    public override double calculateSalesTax(){
         //Something to calculate a VWs tax
    }
}

它已经打破 SOLID 中的 S 了吗?

SOLID 原则是很好的启发式方法,但它们可能有点模糊。它们是思想的食粮,而不是绝对的规则。

Robert C. Martin 将单一职责原则 (SRP) 描述为:

A class should have only one reason to change

SRP 和其他 SOLID 原则为您提供了超前思考的框架,但您无法预测未来。未来可能会出现计划外的变更原因。

不过,提前想一想,您将来必须更改这些 class 的原因是否不止一个?

可以想象,您将来可能需要更改 calculateSalesTax 方法,但是您是否需要更改 class 的属性?

如果不是,则不违反 SRP。另一方面,如果您预计将来必须更改class的属性,以及calculateSalesTax 方法,那么 SRP 就会被破坏。如果是这种情况,您应该考虑替代设计。

暴露同一模块的数据和逻辑违反了一个更基本的原则:definition of an object

用 Martin 的话说,一个对象隐藏它的数据并暴露它的行为。数据结构公开数据并且没有行为。将两者都暴露出来,他称之为 混合体 ,这是两个世界中最糟糕的。

满足 SRP 还不是问题,因为根据 SRP 所指的定义,这不是对象。