Let's say you have abstract class A doing some stuff. Then you have abstract class B doing other stuff.

And lastly a few normal classes, let's say C ... Z.

Both A and B provide functionality that are used by class C .. Z classes. In my case mainly an observer pattern which is static, and some __get magic + lazy-loading for a certain type of properties - this is not static. I'm thinking to merge this into one class, but then I'm sure it violates SRP :)

So I am extending A, B in C, D etc... Essentially all C .. Z classes inherit the functionality of the A & B classes. So besides what they are supposed to do, they also do the observer stuff and so on

Does this violate the single-responsability principle?

有帮助吗?

解决方案

I don't know if this applies to your specific case, but I find that most of the time, an abstract class and its implementation can be split into two normal classes.

For example:

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);

Can be changed into:

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);

This has several advantages:

  • The classes are less tightly coupled, because they don't inherit from each other. Because the classes are separate, the responsibilities are more separate and well-defined.
  • You can use functionality of multiple classes, whereas you can only inherit from one abstract class. (Edit: apparently not in PHP because you have multiple inheritance)
  • It is clearer (IMHO) on which class the method is called.

It seems like you are using inheritance to couple multiple classes, but that is not what inheritance is meant for.

其他提示

I read this as "does multiple inheritance violate the SRP"?

Technically, I'd say yes.

Practically, it's more vague. What is a 'responsibility'? It's possible you need both parts of functionality to meet composite responsibility. You also have to balance the effort associated with implementation and maintenance of the strictness you impose on an object hierarchy.

It's a principle. It exists to focus your thinking around encapsulation and separation of concerns, to keep from trying to just throw everything into messy one-size-fits-all superclasses.

Now to the specific example: are you pulling in A and B for conveniences sake? If you look at what different consumers of A and B need, is there some refactoring that's trying to break out (e.g. some subset of functionality that isn't needed or should be done elsewhere?) In the abstract it's impossible to say.

Multiple inheritance doesn't force this, but tends to lead to it. Your base interfaces are designed for a single purpose, inheriting both of them does create a class with multiple responsibilities. You can partition your classes and interfaces into two major groups - the ones addressing the essential complexity of your system, and the ones addressing its accidental complexity. I think if you inherit from more than one "essential" classes, it is bad . But if you inherit from one "essential" and one or more "accidental" classes, it is normal.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top