Does implementing multiple interfaces violate Sing

2019-03-18 20:27发布

问题:

From Wikipedia:

Single responsibility principle states that every class should have a single responsibility, and that responsibility should be entirely encapsulated by the class.

Does that mean implementing multiple interfaces violates this principle?

回答1:

I would say not by itself. A class can have one responsibility, but do multiple things in the process, and implement one interface for each set of things it needs to do to fulfill its responsibility.

Also, interfaces in Java can be used to say things about what properties the class has (for example, Comparable and Serializable), but not really say anything the class's responsibility.

However, if a class implements multiple interfaces, each of which corresponds to one responsibility, then that would be a violation of that principle.



回答2:

"Single Responsibility" depends on the level of abstraction. For example, a complex system, considering it at a system level, may have one responsibility. For instance, a TV system's responsibility is to show video picture. At the next, lower level, that system is made of sub-systems, monitor, power unit, etc. At this level, each of these units have their own responsibilities.

In the same way, a class, at one level may be considered to have a single responsibility. But, at a lower level, it may have other constituent modules (classes, interfaces etc) that perform parts of its job. For example, a Student class's responsibility is to represent a student abstraction. It may however have another unit (a class) that represents student's address.

In this way, using multiple interfaces do not by itself violate object-oriented principles.



回答3:

Maybe, but not necessarily.

An interface is not a responsibility. There's a very powerful mode of architecture which views interfaces as defining the role the object may play in the application.

Think of what that means. You can have a Person class with all sorts of interfaces (let's use a .net convention for naming)

class Person : IAmAStudent, IDrawSocialSecurity, IAmACitizen {
   public SocialSecurityNumber getSocialSecurityNumber() {
      return this.ssn;
   }
   private SocialSecurityNumber ssn;
   public Person(SocialSecurityNumber ssn) { this.ssn = ssn; }
}

Now obviously this cannot violate SRP. It clearly has only one reason for change - if the relationship between people and social security numbers changes. Yet the object implements many interfaces and plays several roles in the application.

Now if you're implementing multiple interfaces that expose different functionality you might be violating SRP but that can be a bit of a judgement call as well. Single Responsibility Principle is a great rule of thumb for achieving loose coupling, but that's not the only ideal in town. There's also high cohesion which states that related code should live together. The two are fundamentally at odds (though there is often ways to achieve good balance). So you might reasonably make a choice in the direction of one over another and decide consciously to violate SRP.

Ultimately, SRP and all the SOLID rules are more about making sure you think along certain lines, not that you follow them blindly every time.