Interface Segregation Principle in Clean Architecture












3














In Chapter 10 of Clean Architecture, Martin gives an example for the Interface Segregation Principle. I have some trouble understanding that example and his explanations.



In this example we have three separate Users (Classes) that use a Class called OPS. OPS has three methods, op1, op2, and op3. Each of these is only used by one user (op1 only by User1 and so on).



Martin now tells us that any change in OPS would result in a recompilation for the other classes since they all depend on OPS, even if the change was performed in a method that is of no interest to them. (So a change in op2 would require a recompilation of User1.)



He argues that thus there should be three separate interfaces, one for each method. The OPS class then implements all of them. The users only use the interface they use. So you have User1 implementing only Interface1 and so on.



According to Martin, this would stop the otherwise necessary redeployment of, say, User1 if the implementation of ops2 in OPS was changed (since User1 does not use the interface that describes op2).



I had my doubts and did some testing. (Martin explicitly used Java for his example, so I did as well.) Even without any interfaces any change in OPS does not cause any user to be recompiled.



And even if it did (which I thought it would), using three interfaces and then having the same class implement all three of them makes no sense to me either. Wouldn't any change in that class require all of the users to be recompiled, interface or no? Is the compiler smart enough to separate where I did my changes and then only recompile those users that rely on the interface describing the method I changed? I kind of doubt that.



The only way how this principle makes sense to me is if we were to split the OPS class into three different classes, interfaces or no. That I could understand, but that's explicitly not the answer Martin gives.



Any help would be greatly appreciated.










share|improve this question







New contributor




zalaponia is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.




















  • are you using dynamic linking to link the User to OPS?
    – Ewan
    4 hours ago
















3














In Chapter 10 of Clean Architecture, Martin gives an example for the Interface Segregation Principle. I have some trouble understanding that example and his explanations.



In this example we have three separate Users (Classes) that use a Class called OPS. OPS has three methods, op1, op2, and op3. Each of these is only used by one user (op1 only by User1 and so on).



Martin now tells us that any change in OPS would result in a recompilation for the other classes since they all depend on OPS, even if the change was performed in a method that is of no interest to them. (So a change in op2 would require a recompilation of User1.)



He argues that thus there should be three separate interfaces, one for each method. The OPS class then implements all of them. The users only use the interface they use. So you have User1 implementing only Interface1 and so on.



According to Martin, this would stop the otherwise necessary redeployment of, say, User1 if the implementation of ops2 in OPS was changed (since User1 does not use the interface that describes op2).



I had my doubts and did some testing. (Martin explicitly used Java for his example, so I did as well.) Even without any interfaces any change in OPS does not cause any user to be recompiled.



And even if it did (which I thought it would), using three interfaces and then having the same class implement all three of them makes no sense to me either. Wouldn't any change in that class require all of the users to be recompiled, interface or no? Is the compiler smart enough to separate where I did my changes and then only recompile those users that rely on the interface describing the method I changed? I kind of doubt that.



The only way how this principle makes sense to me is if we were to split the OPS class into three different classes, interfaces or no. That I could understand, but that's explicitly not the answer Martin gives.



Any help would be greatly appreciated.










share|improve this question







New contributor




zalaponia is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.




















  • are you using dynamic linking to link the User to OPS?
    – Ewan
    4 hours ago














3












3








3







In Chapter 10 of Clean Architecture, Martin gives an example for the Interface Segregation Principle. I have some trouble understanding that example and his explanations.



In this example we have three separate Users (Classes) that use a Class called OPS. OPS has three methods, op1, op2, and op3. Each of these is only used by one user (op1 only by User1 and so on).



Martin now tells us that any change in OPS would result in a recompilation for the other classes since they all depend on OPS, even if the change was performed in a method that is of no interest to them. (So a change in op2 would require a recompilation of User1.)



He argues that thus there should be three separate interfaces, one for each method. The OPS class then implements all of them. The users only use the interface they use. So you have User1 implementing only Interface1 and so on.



According to Martin, this would stop the otherwise necessary redeployment of, say, User1 if the implementation of ops2 in OPS was changed (since User1 does not use the interface that describes op2).



I had my doubts and did some testing. (Martin explicitly used Java for his example, so I did as well.) Even without any interfaces any change in OPS does not cause any user to be recompiled.



And even if it did (which I thought it would), using three interfaces and then having the same class implement all three of them makes no sense to me either. Wouldn't any change in that class require all of the users to be recompiled, interface or no? Is the compiler smart enough to separate where I did my changes and then only recompile those users that rely on the interface describing the method I changed? I kind of doubt that.



The only way how this principle makes sense to me is if we were to split the OPS class into three different classes, interfaces or no. That I could understand, but that's explicitly not the answer Martin gives.



Any help would be greatly appreciated.










share|improve this question







New contributor




zalaponia is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











In Chapter 10 of Clean Architecture, Martin gives an example for the Interface Segregation Principle. I have some trouble understanding that example and his explanations.



In this example we have three separate Users (Classes) that use a Class called OPS. OPS has three methods, op1, op2, and op3. Each of these is only used by one user (op1 only by User1 and so on).



Martin now tells us that any change in OPS would result in a recompilation for the other classes since they all depend on OPS, even if the change was performed in a method that is of no interest to them. (So a change in op2 would require a recompilation of User1.)



He argues that thus there should be three separate interfaces, one for each method. The OPS class then implements all of them. The users only use the interface they use. So you have User1 implementing only Interface1 and so on.



According to Martin, this would stop the otherwise necessary redeployment of, say, User1 if the implementation of ops2 in OPS was changed (since User1 does not use the interface that describes op2).



I had my doubts and did some testing. (Martin explicitly used Java for his example, so I did as well.) Even without any interfaces any change in OPS does not cause any user to be recompiled.



And even if it did (which I thought it would), using three interfaces and then having the same class implement all three of them makes no sense to me either. Wouldn't any change in that class require all of the users to be recompiled, interface or no? Is the compiler smart enough to separate where I did my changes and then only recompile those users that rely on the interface describing the method I changed? I kind of doubt that.



The only way how this principle makes sense to me is if we were to split the OPS class into three different classes, interfaces or no. That I could understand, but that's explicitly not the answer Martin gives.



Any help would be greatly appreciated.







java solid clean-architecture






share|improve this question







New contributor




zalaponia is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











share|improve this question







New contributor




zalaponia is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









share|improve this question




share|improve this question






New contributor




zalaponia is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









asked 5 hours ago









zalaponia

182




182




New contributor




zalaponia is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.





New contributor





zalaponia is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.






zalaponia is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.












  • are you using dynamic linking to link the User to OPS?
    – Ewan
    4 hours ago


















  • are you using dynamic linking to link the User to OPS?
    – Ewan
    4 hours ago
















are you using dynamic linking to link the User to OPS?
– Ewan
4 hours ago




are you using dynamic linking to link the User to OPS?
– Ewan
4 hours ago










2 Answers
2






active

oldest

votes


















5














In that particular example the use of Java as compared to C++ does indeed hide the benefit of interfaces. Interfaces (or more generally, late binding) are useful to break direct dependencies.



Direct dependency    Indirect dependency
================= ===================

+---------+ +-----------+
| Service | | Interface |
+---------+ +-----------+
^ ^ ^
| | |
+--------+ +---------+ +--------+
| Client | | Service | | Client |
+--------+ +---------+ +--------+


However, Java already uses some amount of late-ish binding: the .class files that the Java compiler produces are not linked in a meaningful way. Instead, the kind of linking in the sense of C++ happens later during runtime when the JVM loads the .class file. Therefore, the focus on Java's compilation model is misleading here. Furthermore, a focus on avoiding recompilation would mean that the ISP would be irrelevant for interpreted language implementations, which is nonsensical.



To be clear: breaking direct dependencies through polymorphism (and applying the ISP more carefully) does have significant effect on compile times in ahead-of-time compiled systems (such as nearly all C++ implementations). This is also related to C++ specific idioms such as pImpl.



The much more universal ISP benefit is that by avoiding unneeded dependencies, the system becomes




  • easier to understand;

  • easier to test;

  • easier to change.


One kind of unneeded dependency is the dependency of a client on a specific service implementation, which can be avoided via polymorphism/interfaces (compare the Dependency Inversion Principle). Another unneeded dependency is the dependency of a consumer on extra methods in an interface. Keeping interfaces small and segregated minimizes these extra dependencies.



The main takeaway from the ISP for me is that




  1. Interfaces should be defined by how an object is used, not by how the object is implemented. It is preferable to define an interface at the point of its usage, and to then implement this interface (possibly by implementing an adapter to an existing class).

  2. Small interfaces are basically the Single Responsibility Principle applied to interfaces.






share|improve this answer

















  • 1




    Right, bringing recompilation to the table in an explanation of ISP is just confusing and totally irrelevant. I suspect the author's point was about breaking interfaces, which you do not want to do once they are out there and users of your library depend on them. Then having lots of small interfaces will be less disruptive than having one big one. Say you have op1, op2, op3 and op4 and you have to change op4 for some reason, you will make user4 unhappy whereas with one big broken interface you would have had 4 unhappy users.
    – Martin Maat
    3 hours ago












  • Thanks @amon, I was thinking about C++ too and was surprised to see that Java didn't recompile the classes that depended on the changed ones - now I even know why :) Those broader reasons of the ISP were something I already suspected, I was wondering why he didn't talk about it. Your explanation makes a lot of sense. Thank you very much.
    – zalaponia
    3 hours ago












  • This is not completely accurate, late binding does not remove the need for recompilation. Overload resolution is an example of something that happens at compile time, if you added a new overload to a class without recompiling the clients, you will end up calling the wrong method at runtime.
    – casablanca
    3 hours ago










  • Also it doesn't matter whether a language is interpreted or not, what matters is whether it uses static typing or not. Java and C++ are both statically typed, and ISP is equally useful in both languages. On the other hand, it wouldn't matter in a dynamically typed language such as Ruby or Python because method dispatches are resolved at runtime.
    – casablanca
    3 hours ago










  • @casablanca while that is true humans still don't react well to interfaces that provide more than they need. It's nice when constructors and method signatures make real needs clear.
    – candied_orange
    23 mins ago



















0














Note that even if you don't "implement" an interface, the public members of your class form an implicit interface.




I had my doubts and did some testing. (Martin explicitly used Java for his example, so I did as well.) Even without any interfaces any change in OPS does not cause any user to be recompiled.




This is true only if you did not change the public interface of OPS, i.e. you only changed implementation details. If you added, removed or changed the signature of any public methods, it could potentially break existing consumers and any good build tool would recompile your user classes.




Wouldn't any change in that class require all of the users to be recompiled, interface or no?




If your clients are only coupled to an interface, they don't need to be recompiled as long as the interface doesn't change. If OPS changes in a way that it no longer correctly implements an interface, it causes a compile error in OPS, not in the user classes.




The only way how this principle makes sense to me is if we were to split the OPS class into three different classes, interfaces or no.




Think of a class as "how something is implemented" and an interface as "what I can do with it". It might make sense for a single class to implement three interfaces if the implementation happens to provide the services of all three interfaces. No point in splitting it out into three classes in that case.






share|improve this answer





















  • "If you added, removed or changed the signature of any public methods, it could potentially break existing consumers and any good build tool would recompile your user classes." I would likely have to rewrite the code in that case anyway since the signature changed.
    – zalaponia
    1 hour ago












  • @zalaponia The point is that the compiler doesn't know whether your change is compatible or not, a recompilation of user classes is required to determine that. But if you have an interface, your user classes aren't directly coupled to OPS and will not need to be recompiled unless the interface changes.
    – casablanca
    1 hour ago











Your Answer








StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "131"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});






zalaponia is a new contributor. Be nice, and check out our Code of Conduct.










draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fsoftwareengineering.stackexchange.com%2fquestions%2f384787%2finterface-segregation-principle-in-clean-architecture%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























2 Answers
2






active

oldest

votes








2 Answers
2






active

oldest

votes









active

oldest

votes






active

oldest

votes









5














In that particular example the use of Java as compared to C++ does indeed hide the benefit of interfaces. Interfaces (or more generally, late binding) are useful to break direct dependencies.



Direct dependency    Indirect dependency
================= ===================

+---------+ +-----------+
| Service | | Interface |
+---------+ +-----------+
^ ^ ^
| | |
+--------+ +---------+ +--------+
| Client | | Service | | Client |
+--------+ +---------+ +--------+


However, Java already uses some amount of late-ish binding: the .class files that the Java compiler produces are not linked in a meaningful way. Instead, the kind of linking in the sense of C++ happens later during runtime when the JVM loads the .class file. Therefore, the focus on Java's compilation model is misleading here. Furthermore, a focus on avoiding recompilation would mean that the ISP would be irrelevant for interpreted language implementations, which is nonsensical.



To be clear: breaking direct dependencies through polymorphism (and applying the ISP more carefully) does have significant effect on compile times in ahead-of-time compiled systems (such as nearly all C++ implementations). This is also related to C++ specific idioms such as pImpl.



The much more universal ISP benefit is that by avoiding unneeded dependencies, the system becomes




  • easier to understand;

  • easier to test;

  • easier to change.


One kind of unneeded dependency is the dependency of a client on a specific service implementation, which can be avoided via polymorphism/interfaces (compare the Dependency Inversion Principle). Another unneeded dependency is the dependency of a consumer on extra methods in an interface. Keeping interfaces small and segregated minimizes these extra dependencies.



The main takeaway from the ISP for me is that




  1. Interfaces should be defined by how an object is used, not by how the object is implemented. It is preferable to define an interface at the point of its usage, and to then implement this interface (possibly by implementing an adapter to an existing class).

  2. Small interfaces are basically the Single Responsibility Principle applied to interfaces.






share|improve this answer

















  • 1




    Right, bringing recompilation to the table in an explanation of ISP is just confusing and totally irrelevant. I suspect the author's point was about breaking interfaces, which you do not want to do once they are out there and users of your library depend on them. Then having lots of small interfaces will be less disruptive than having one big one. Say you have op1, op2, op3 and op4 and you have to change op4 for some reason, you will make user4 unhappy whereas with one big broken interface you would have had 4 unhappy users.
    – Martin Maat
    3 hours ago












  • Thanks @amon, I was thinking about C++ too and was surprised to see that Java didn't recompile the classes that depended on the changed ones - now I even know why :) Those broader reasons of the ISP were something I already suspected, I was wondering why he didn't talk about it. Your explanation makes a lot of sense. Thank you very much.
    – zalaponia
    3 hours ago












  • This is not completely accurate, late binding does not remove the need for recompilation. Overload resolution is an example of something that happens at compile time, if you added a new overload to a class without recompiling the clients, you will end up calling the wrong method at runtime.
    – casablanca
    3 hours ago










  • Also it doesn't matter whether a language is interpreted or not, what matters is whether it uses static typing or not. Java and C++ are both statically typed, and ISP is equally useful in both languages. On the other hand, it wouldn't matter in a dynamically typed language such as Ruby or Python because method dispatches are resolved at runtime.
    – casablanca
    3 hours ago










  • @casablanca while that is true humans still don't react well to interfaces that provide more than they need. It's nice when constructors and method signatures make real needs clear.
    – candied_orange
    23 mins ago
















5














In that particular example the use of Java as compared to C++ does indeed hide the benefit of interfaces. Interfaces (or more generally, late binding) are useful to break direct dependencies.



Direct dependency    Indirect dependency
================= ===================

+---------+ +-----------+
| Service | | Interface |
+---------+ +-----------+
^ ^ ^
| | |
+--------+ +---------+ +--------+
| Client | | Service | | Client |
+--------+ +---------+ +--------+


However, Java already uses some amount of late-ish binding: the .class files that the Java compiler produces are not linked in a meaningful way. Instead, the kind of linking in the sense of C++ happens later during runtime when the JVM loads the .class file. Therefore, the focus on Java's compilation model is misleading here. Furthermore, a focus on avoiding recompilation would mean that the ISP would be irrelevant for interpreted language implementations, which is nonsensical.



To be clear: breaking direct dependencies through polymorphism (and applying the ISP more carefully) does have significant effect on compile times in ahead-of-time compiled systems (such as nearly all C++ implementations). This is also related to C++ specific idioms such as pImpl.



The much more universal ISP benefit is that by avoiding unneeded dependencies, the system becomes




  • easier to understand;

  • easier to test;

  • easier to change.


One kind of unneeded dependency is the dependency of a client on a specific service implementation, which can be avoided via polymorphism/interfaces (compare the Dependency Inversion Principle). Another unneeded dependency is the dependency of a consumer on extra methods in an interface. Keeping interfaces small and segregated minimizes these extra dependencies.



The main takeaway from the ISP for me is that




  1. Interfaces should be defined by how an object is used, not by how the object is implemented. It is preferable to define an interface at the point of its usage, and to then implement this interface (possibly by implementing an adapter to an existing class).

  2. Small interfaces are basically the Single Responsibility Principle applied to interfaces.






share|improve this answer

















  • 1




    Right, bringing recompilation to the table in an explanation of ISP is just confusing and totally irrelevant. I suspect the author's point was about breaking interfaces, which you do not want to do once they are out there and users of your library depend on them. Then having lots of small interfaces will be less disruptive than having one big one. Say you have op1, op2, op3 and op4 and you have to change op4 for some reason, you will make user4 unhappy whereas with one big broken interface you would have had 4 unhappy users.
    – Martin Maat
    3 hours ago












  • Thanks @amon, I was thinking about C++ too and was surprised to see that Java didn't recompile the classes that depended on the changed ones - now I even know why :) Those broader reasons of the ISP were something I already suspected, I was wondering why he didn't talk about it. Your explanation makes a lot of sense. Thank you very much.
    – zalaponia
    3 hours ago












  • This is not completely accurate, late binding does not remove the need for recompilation. Overload resolution is an example of something that happens at compile time, if you added a new overload to a class without recompiling the clients, you will end up calling the wrong method at runtime.
    – casablanca
    3 hours ago










  • Also it doesn't matter whether a language is interpreted or not, what matters is whether it uses static typing or not. Java and C++ are both statically typed, and ISP is equally useful in both languages. On the other hand, it wouldn't matter in a dynamically typed language such as Ruby or Python because method dispatches are resolved at runtime.
    – casablanca
    3 hours ago










  • @casablanca while that is true humans still don't react well to interfaces that provide more than they need. It's nice when constructors and method signatures make real needs clear.
    – candied_orange
    23 mins ago














5












5








5






In that particular example the use of Java as compared to C++ does indeed hide the benefit of interfaces. Interfaces (or more generally, late binding) are useful to break direct dependencies.



Direct dependency    Indirect dependency
================= ===================

+---------+ +-----------+
| Service | | Interface |
+---------+ +-----------+
^ ^ ^
| | |
+--------+ +---------+ +--------+
| Client | | Service | | Client |
+--------+ +---------+ +--------+


However, Java already uses some amount of late-ish binding: the .class files that the Java compiler produces are not linked in a meaningful way. Instead, the kind of linking in the sense of C++ happens later during runtime when the JVM loads the .class file. Therefore, the focus on Java's compilation model is misleading here. Furthermore, a focus on avoiding recompilation would mean that the ISP would be irrelevant for interpreted language implementations, which is nonsensical.



To be clear: breaking direct dependencies through polymorphism (and applying the ISP more carefully) does have significant effect on compile times in ahead-of-time compiled systems (such as nearly all C++ implementations). This is also related to C++ specific idioms such as pImpl.



The much more universal ISP benefit is that by avoiding unneeded dependencies, the system becomes




  • easier to understand;

  • easier to test;

  • easier to change.


One kind of unneeded dependency is the dependency of a client on a specific service implementation, which can be avoided via polymorphism/interfaces (compare the Dependency Inversion Principle). Another unneeded dependency is the dependency of a consumer on extra methods in an interface. Keeping interfaces small and segregated minimizes these extra dependencies.



The main takeaway from the ISP for me is that




  1. Interfaces should be defined by how an object is used, not by how the object is implemented. It is preferable to define an interface at the point of its usage, and to then implement this interface (possibly by implementing an adapter to an existing class).

  2. Small interfaces are basically the Single Responsibility Principle applied to interfaces.






share|improve this answer












In that particular example the use of Java as compared to C++ does indeed hide the benefit of interfaces. Interfaces (or more generally, late binding) are useful to break direct dependencies.



Direct dependency    Indirect dependency
================= ===================

+---------+ +-----------+
| Service | | Interface |
+---------+ +-----------+
^ ^ ^
| | |
+--------+ +---------+ +--------+
| Client | | Service | | Client |
+--------+ +---------+ +--------+


However, Java already uses some amount of late-ish binding: the .class files that the Java compiler produces are not linked in a meaningful way. Instead, the kind of linking in the sense of C++ happens later during runtime when the JVM loads the .class file. Therefore, the focus on Java's compilation model is misleading here. Furthermore, a focus on avoiding recompilation would mean that the ISP would be irrelevant for interpreted language implementations, which is nonsensical.



To be clear: breaking direct dependencies through polymorphism (and applying the ISP more carefully) does have significant effect on compile times in ahead-of-time compiled systems (such as nearly all C++ implementations). This is also related to C++ specific idioms such as pImpl.



The much more universal ISP benefit is that by avoiding unneeded dependencies, the system becomes




  • easier to understand;

  • easier to test;

  • easier to change.


One kind of unneeded dependency is the dependency of a client on a specific service implementation, which can be avoided via polymorphism/interfaces (compare the Dependency Inversion Principle). Another unneeded dependency is the dependency of a consumer on extra methods in an interface. Keeping interfaces small and segregated minimizes these extra dependencies.



The main takeaway from the ISP for me is that




  1. Interfaces should be defined by how an object is used, not by how the object is implemented. It is preferable to define an interface at the point of its usage, and to then implement this interface (possibly by implementing an adapter to an existing class).

  2. Small interfaces are basically the Single Responsibility Principle applied to interfaces.







share|improve this answer












share|improve this answer



share|improve this answer










answered 4 hours ago









amon

85.2k21163250




85.2k21163250








  • 1




    Right, bringing recompilation to the table in an explanation of ISP is just confusing and totally irrelevant. I suspect the author's point was about breaking interfaces, which you do not want to do once they are out there and users of your library depend on them. Then having lots of small interfaces will be less disruptive than having one big one. Say you have op1, op2, op3 and op4 and you have to change op4 for some reason, you will make user4 unhappy whereas with one big broken interface you would have had 4 unhappy users.
    – Martin Maat
    3 hours ago












  • Thanks @amon, I was thinking about C++ too and was surprised to see that Java didn't recompile the classes that depended on the changed ones - now I even know why :) Those broader reasons of the ISP were something I already suspected, I was wondering why he didn't talk about it. Your explanation makes a lot of sense. Thank you very much.
    – zalaponia
    3 hours ago












  • This is not completely accurate, late binding does not remove the need for recompilation. Overload resolution is an example of something that happens at compile time, if you added a new overload to a class without recompiling the clients, you will end up calling the wrong method at runtime.
    – casablanca
    3 hours ago










  • Also it doesn't matter whether a language is interpreted or not, what matters is whether it uses static typing or not. Java and C++ are both statically typed, and ISP is equally useful in both languages. On the other hand, it wouldn't matter in a dynamically typed language such as Ruby or Python because method dispatches are resolved at runtime.
    – casablanca
    3 hours ago










  • @casablanca while that is true humans still don't react well to interfaces that provide more than they need. It's nice when constructors and method signatures make real needs clear.
    – candied_orange
    23 mins ago














  • 1




    Right, bringing recompilation to the table in an explanation of ISP is just confusing and totally irrelevant. I suspect the author's point was about breaking interfaces, which you do not want to do once they are out there and users of your library depend on them. Then having lots of small interfaces will be less disruptive than having one big one. Say you have op1, op2, op3 and op4 and you have to change op4 for some reason, you will make user4 unhappy whereas with one big broken interface you would have had 4 unhappy users.
    – Martin Maat
    3 hours ago












  • Thanks @amon, I was thinking about C++ too and was surprised to see that Java didn't recompile the classes that depended on the changed ones - now I even know why :) Those broader reasons of the ISP were something I already suspected, I was wondering why he didn't talk about it. Your explanation makes a lot of sense. Thank you very much.
    – zalaponia
    3 hours ago












  • This is not completely accurate, late binding does not remove the need for recompilation. Overload resolution is an example of something that happens at compile time, if you added a new overload to a class without recompiling the clients, you will end up calling the wrong method at runtime.
    – casablanca
    3 hours ago










  • Also it doesn't matter whether a language is interpreted or not, what matters is whether it uses static typing or not. Java and C++ are both statically typed, and ISP is equally useful in both languages. On the other hand, it wouldn't matter in a dynamically typed language such as Ruby or Python because method dispatches are resolved at runtime.
    – casablanca
    3 hours ago










  • @casablanca while that is true humans still don't react well to interfaces that provide more than they need. It's nice when constructors and method signatures make real needs clear.
    – candied_orange
    23 mins ago








1




1




Right, bringing recompilation to the table in an explanation of ISP is just confusing and totally irrelevant. I suspect the author's point was about breaking interfaces, which you do not want to do once they are out there and users of your library depend on them. Then having lots of small interfaces will be less disruptive than having one big one. Say you have op1, op2, op3 and op4 and you have to change op4 for some reason, you will make user4 unhappy whereas with one big broken interface you would have had 4 unhappy users.
– Martin Maat
3 hours ago






Right, bringing recompilation to the table in an explanation of ISP is just confusing and totally irrelevant. I suspect the author's point was about breaking interfaces, which you do not want to do once they are out there and users of your library depend on them. Then having lots of small interfaces will be less disruptive than having one big one. Say you have op1, op2, op3 and op4 and you have to change op4 for some reason, you will make user4 unhappy whereas with one big broken interface you would have had 4 unhappy users.
– Martin Maat
3 hours ago














Thanks @amon, I was thinking about C++ too and was surprised to see that Java didn't recompile the classes that depended on the changed ones - now I even know why :) Those broader reasons of the ISP were something I already suspected, I was wondering why he didn't talk about it. Your explanation makes a lot of sense. Thank you very much.
– zalaponia
3 hours ago






Thanks @amon, I was thinking about C++ too and was surprised to see that Java didn't recompile the classes that depended on the changed ones - now I even know why :) Those broader reasons of the ISP were something I already suspected, I was wondering why he didn't talk about it. Your explanation makes a lot of sense. Thank you very much.
– zalaponia
3 hours ago














This is not completely accurate, late binding does not remove the need for recompilation. Overload resolution is an example of something that happens at compile time, if you added a new overload to a class without recompiling the clients, you will end up calling the wrong method at runtime.
– casablanca
3 hours ago




This is not completely accurate, late binding does not remove the need for recompilation. Overload resolution is an example of something that happens at compile time, if you added a new overload to a class without recompiling the clients, you will end up calling the wrong method at runtime.
– casablanca
3 hours ago












Also it doesn't matter whether a language is interpreted or not, what matters is whether it uses static typing or not. Java and C++ are both statically typed, and ISP is equally useful in both languages. On the other hand, it wouldn't matter in a dynamically typed language such as Ruby or Python because method dispatches are resolved at runtime.
– casablanca
3 hours ago




Also it doesn't matter whether a language is interpreted or not, what matters is whether it uses static typing or not. Java and C++ are both statically typed, and ISP is equally useful in both languages. On the other hand, it wouldn't matter in a dynamically typed language such as Ruby or Python because method dispatches are resolved at runtime.
– casablanca
3 hours ago












@casablanca while that is true humans still don't react well to interfaces that provide more than they need. It's nice when constructors and method signatures make real needs clear.
– candied_orange
23 mins ago




@casablanca while that is true humans still don't react well to interfaces that provide more than they need. It's nice when constructors and method signatures make real needs clear.
– candied_orange
23 mins ago













0














Note that even if you don't "implement" an interface, the public members of your class form an implicit interface.




I had my doubts and did some testing. (Martin explicitly used Java for his example, so I did as well.) Even without any interfaces any change in OPS does not cause any user to be recompiled.




This is true only if you did not change the public interface of OPS, i.e. you only changed implementation details. If you added, removed or changed the signature of any public methods, it could potentially break existing consumers and any good build tool would recompile your user classes.




Wouldn't any change in that class require all of the users to be recompiled, interface or no?




If your clients are only coupled to an interface, they don't need to be recompiled as long as the interface doesn't change. If OPS changes in a way that it no longer correctly implements an interface, it causes a compile error in OPS, not in the user classes.




The only way how this principle makes sense to me is if we were to split the OPS class into three different classes, interfaces or no.




Think of a class as "how something is implemented" and an interface as "what I can do with it". It might make sense for a single class to implement three interfaces if the implementation happens to provide the services of all three interfaces. No point in splitting it out into three classes in that case.






share|improve this answer





















  • "If you added, removed or changed the signature of any public methods, it could potentially break existing consumers and any good build tool would recompile your user classes." I would likely have to rewrite the code in that case anyway since the signature changed.
    – zalaponia
    1 hour ago












  • @zalaponia The point is that the compiler doesn't know whether your change is compatible or not, a recompilation of user classes is required to determine that. But if you have an interface, your user classes aren't directly coupled to OPS and will not need to be recompiled unless the interface changes.
    – casablanca
    1 hour ago
















0














Note that even if you don't "implement" an interface, the public members of your class form an implicit interface.




I had my doubts and did some testing. (Martin explicitly used Java for his example, so I did as well.) Even without any interfaces any change in OPS does not cause any user to be recompiled.




This is true only if you did not change the public interface of OPS, i.e. you only changed implementation details. If you added, removed or changed the signature of any public methods, it could potentially break existing consumers and any good build tool would recompile your user classes.




Wouldn't any change in that class require all of the users to be recompiled, interface or no?




If your clients are only coupled to an interface, they don't need to be recompiled as long as the interface doesn't change. If OPS changes in a way that it no longer correctly implements an interface, it causes a compile error in OPS, not in the user classes.




The only way how this principle makes sense to me is if we were to split the OPS class into three different classes, interfaces or no.




Think of a class as "how something is implemented" and an interface as "what I can do with it". It might make sense for a single class to implement three interfaces if the implementation happens to provide the services of all three interfaces. No point in splitting it out into three classes in that case.






share|improve this answer





















  • "If you added, removed or changed the signature of any public methods, it could potentially break existing consumers and any good build tool would recompile your user classes." I would likely have to rewrite the code in that case anyway since the signature changed.
    – zalaponia
    1 hour ago












  • @zalaponia The point is that the compiler doesn't know whether your change is compatible or not, a recompilation of user classes is required to determine that. But if you have an interface, your user classes aren't directly coupled to OPS and will not need to be recompiled unless the interface changes.
    – casablanca
    1 hour ago














0












0








0






Note that even if you don't "implement" an interface, the public members of your class form an implicit interface.




I had my doubts and did some testing. (Martin explicitly used Java for his example, so I did as well.) Even without any interfaces any change in OPS does not cause any user to be recompiled.




This is true only if you did not change the public interface of OPS, i.e. you only changed implementation details. If you added, removed or changed the signature of any public methods, it could potentially break existing consumers and any good build tool would recompile your user classes.




Wouldn't any change in that class require all of the users to be recompiled, interface or no?




If your clients are only coupled to an interface, they don't need to be recompiled as long as the interface doesn't change. If OPS changes in a way that it no longer correctly implements an interface, it causes a compile error in OPS, not in the user classes.




The only way how this principle makes sense to me is if we were to split the OPS class into three different classes, interfaces or no.




Think of a class as "how something is implemented" and an interface as "what I can do with it". It might make sense for a single class to implement three interfaces if the implementation happens to provide the services of all three interfaces. No point in splitting it out into three classes in that case.






share|improve this answer












Note that even if you don't "implement" an interface, the public members of your class form an implicit interface.




I had my doubts and did some testing. (Martin explicitly used Java for his example, so I did as well.) Even without any interfaces any change in OPS does not cause any user to be recompiled.




This is true only if you did not change the public interface of OPS, i.e. you only changed implementation details. If you added, removed or changed the signature of any public methods, it could potentially break existing consumers and any good build tool would recompile your user classes.




Wouldn't any change in that class require all of the users to be recompiled, interface or no?




If your clients are only coupled to an interface, they don't need to be recompiled as long as the interface doesn't change. If OPS changes in a way that it no longer correctly implements an interface, it causes a compile error in OPS, not in the user classes.




The only way how this principle makes sense to me is if we were to split the OPS class into three different classes, interfaces or no.




Think of a class as "how something is implemented" and an interface as "what I can do with it". It might make sense for a single class to implement three interfaces if the implementation happens to provide the services of all three interfaces. No point in splitting it out into three classes in that case.







share|improve this answer












share|improve this answer



share|improve this answer










answered 3 hours ago









casablanca

57926




57926












  • "If you added, removed or changed the signature of any public methods, it could potentially break existing consumers and any good build tool would recompile your user classes." I would likely have to rewrite the code in that case anyway since the signature changed.
    – zalaponia
    1 hour ago












  • @zalaponia The point is that the compiler doesn't know whether your change is compatible or not, a recompilation of user classes is required to determine that. But if you have an interface, your user classes aren't directly coupled to OPS and will not need to be recompiled unless the interface changes.
    – casablanca
    1 hour ago


















  • "If you added, removed or changed the signature of any public methods, it could potentially break existing consumers and any good build tool would recompile your user classes." I would likely have to rewrite the code in that case anyway since the signature changed.
    – zalaponia
    1 hour ago












  • @zalaponia The point is that the compiler doesn't know whether your change is compatible or not, a recompilation of user classes is required to determine that. But if you have an interface, your user classes aren't directly coupled to OPS and will not need to be recompiled unless the interface changes.
    – casablanca
    1 hour ago
















"If you added, removed or changed the signature of any public methods, it could potentially break existing consumers and any good build tool would recompile your user classes." I would likely have to rewrite the code in that case anyway since the signature changed.
– zalaponia
1 hour ago






"If you added, removed or changed the signature of any public methods, it could potentially break existing consumers and any good build tool would recompile your user classes." I would likely have to rewrite the code in that case anyway since the signature changed.
– zalaponia
1 hour ago














@zalaponia The point is that the compiler doesn't know whether your change is compatible or not, a recompilation of user classes is required to determine that. But if you have an interface, your user classes aren't directly coupled to OPS and will not need to be recompiled unless the interface changes.
– casablanca
1 hour ago




@zalaponia The point is that the compiler doesn't know whether your change is compatible or not, a recompilation of user classes is required to determine that. But if you have an interface, your user classes aren't directly coupled to OPS and will not need to be recompiled unless the interface changes.
– casablanca
1 hour ago










zalaponia is a new contributor. Be nice, and check out our Code of Conduct.










draft saved

draft discarded


















zalaponia is a new contributor. Be nice, and check out our Code of Conduct.













zalaponia is a new contributor. Be nice, and check out our Code of Conduct.












zalaponia is a new contributor. Be nice, and check out our Code of Conduct.
















Thanks for contributing an answer to Software Engineering Stack Exchange!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.





Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


Please pay close attention to the following guidance:


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fsoftwareengineering.stackexchange.com%2fquestions%2f384787%2finterface-segregation-principle-in-clean-architecture%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Costa Masnaga

Fotorealismo

Sidney Franklin