单一责任原则


Single-responsability principle

假设抽象类A在做一些事情。然后你有抽象的B类在做其他的事情。

最后是一些普通类,比如C。。。Z.

A和B都提供C类使用的功能。。Z类。在我的案例中,主要是一个静态的观察者模式,以及某些类型的属性的__getmagic+延迟加载——这不是静态的。我想把它合并成一个类,但我确信它违反了SRP:)

所以我在C,D等中扩展A,B…本质上所有的C。。Z类继承了A&B类。因此,除了他们应该做的事情,他们还做观测者的事情,等等

这是否违反了单一责任原则?

我不知道这是否适用于您的特定情况,但我发现大多数时候,一个抽象类及其实现可以拆分为两个普通类。

例如:

abstract class AbstractAdder {
    int AddThree(int a) {
        Add(a, 3);
    }
    abstract int Add(int a, int b);
}
class NormalAdder inherits AbstractAdder {
    int Add(int a, int b) {
        return a + b;
    }
}
var result = new NormalAdder().AddThree(6);

可更改为:

class ThreeAdder {
    ThreeAdder(IGenericAdder genericAdder) {
        this.genericAdder = genericAdder;
    }
    int AddThree(int a) {
        return this.genericAdder.Add(a, 3);
    }
}
class NormalAdder implements IGenericAdder {
    int Add(int a, int b) {
        return a + b;
    }
}
var result = new ThreeAdder(new NormalAdder()).AddThree(6);

这有几个优点:

  • 这些类的耦合不那么紧密,因为它们不相互继承。因为类是独立的,所以职责更加独立和明确
  • 您可以使用多个类的功能,而只能从一个抽象类继承。(编辑:显然不是在PHP中,因为您有多重继承)
  • 在哪个类上调用该方法(IMHO)就更清楚了

您似乎在使用继承来耦合多个类,但这不是继承的目的。

我读到这是"多重继承是否违反SRP"?

从技术上讲,我会答应的。

实际上,它更模糊。什么是"责任"?您可能需要功能的两个部分来履行复合责任。您还必须平衡与实现和维护对对象层次结构的严格性相关的工作。

这是一个原则。它的存在是为了让你的思维集中在关注点的封装和分离上,避免试图把所有东西都扔进混乱的一刀切的超类中。

现在来看一个具体的例子:为了方便起见,你把A和B都拉进来了吗?如果你看看A和B的不同消费者需要什么,是否有一些重构正在尝试突破(例如,一些不需要或应该在其他地方完成的功能子集?)抽象地说,这是不可能的。

多重继承不会强制实现这一点,但往往会导致这一点。您的基本接口是为单一目的设计的,继承两者确实会创建一个具有多重职责的类。您可以将类和接口划分为两个主要组——一组处理系统的基本复杂性,另一组处理其意外复杂性。我认为,如果您继承了一个以上的"基本"类,那就不好了。但是,如果您继承了一个"本质"类和一个或多个"偶然"类,这是正常的。