Confusion on Single Responsibility Principle (SRP) with modem example?2019 Community Moderator ElectionHow do...

If I delete my router's history can my ISP still provide it to my parents?

Table enclosed in curly brackets

Is Draco canonically good-looking?

Auto Insert date into Notepad

Inventor that creates machine that grabs man from future

Eww, those bytes are gross

Is there a way to help users from having to clicking emails twice before logging into a new sandbox

Which aircraft had such a luxurious-looking navigator's station?

Metadata API deployments are failing in Spring '19

Criticizing long fiction. How is it different from short?

What is Crew Dragon approaching in this picture?

How to avoid being sexist when trying to employ someone to function in a very sexist environment?

Where was Karl Mordo in Infinity War?

Crystal compensation for temp and voltage

When does coming up with an idea constitute sufficient contribution for authorship?

Finding an integral using a table?

Why is commutativity optional in multiplication for rings?

Is it a fallacy if someone claims they need an explanation for every word of your argument to the point where they don't understand common terms?

Quenching swords in dragon blood; why?

What is the wife of a henpecked husband called?

Word to be used for "standing with your toes pointing out"

Why is this code uniquely decodable?

Why zero tolerance on nudity in space?

It took me a lot of time to make this, pls like. (YouTube Comments #1)



Confusion on Single Responsibility Principle (SRP) with modem example?



2019 Community Moderator ElectionHow do you apply Single Responsibility principle to a repositoryIs SRP (Single Responsibility Principle) objective?Single Responsibility Principle ImplementationSingle Responsibility Principle: Responsibility unknownDoes multiple inheritance violate Single Responsibility Principle?Is this a Single Responsibility Principle violation?Confused about implementing Single Responsibility PrincipleEnums and single responsibility principle (SRP)Single Responsibility Principle Violation?Understanding Single Responsibility Pattern (SRP)Single responsibility principle - importer












1















I am currently reading through Robert Martins book "Agile Software Development" book and I am struggling to see how his modem example provides any benefit.



He says that he has an interface that violates the SRP



interface Modem 
{
public void dial(String pno);
public void hangup();
public void send(char c);
public char recv();
}


So he decides to break it up so that the Modem Implementation relies on a Connection interface and Data channel Interface. However then when Modem implements Connection and Data Channel Interfaces, his class Modem must still implement the methods individually!



enter image description here



To me, this doesn't seem right. I believe I may have a misunderstanding and hoping someone can point me where I'm wrong. Here is my implementation in Scala that represents my understanding.



I hope someone may be able to point me to where I'm wrong. Note In Scala a Trait is similar to an in an interface. For all intents of this example please assume that the Trait is just another word for "Interface" and that the return type "Unit" is the same as "Void".



trait IDataChannel {

def send(message: String)
def receive(): String

}

trait IConnection {

def dial(number: String)
def hangup()

}

trait IModem extends IConnection with IDataChannel{}

class ModemImpl extends IModem {

def hangup(): Unit = {}

def receive() = { "hi" }

def send(message: String): Unit = {}

def dial(number: String): Unit = {}

}









share|improve this question




















  • 1





    What doesn't seem right? Your ModemImpl class does indeed implement the methods individually.

    – Kache
    15 hours ago











  • Exactly. So, therefore, this still violates the SRP. ModemImpl still has more than "one reason to change".

    – alex
    14 hours ago











  • Please post the code with Martins fix. We shouldn't need the book handy to help you.

    – candied_orange
    14 hours ago











  • There is no code from his fix he just drew a UML diagram as his solution that pointed the Modem class to IConnection and IDataChannel. See the edit to my post I put a link to a picture that shows an example of what he drew.

    – alex
    14 hours ago


















1















I am currently reading through Robert Martins book "Agile Software Development" book and I am struggling to see how his modem example provides any benefit.



He says that he has an interface that violates the SRP



interface Modem 
{
public void dial(String pno);
public void hangup();
public void send(char c);
public char recv();
}


So he decides to break it up so that the Modem Implementation relies on a Connection interface and Data channel Interface. However then when Modem implements Connection and Data Channel Interfaces, his class Modem must still implement the methods individually!



enter image description here



To me, this doesn't seem right. I believe I may have a misunderstanding and hoping someone can point me where I'm wrong. Here is my implementation in Scala that represents my understanding.



I hope someone may be able to point me to where I'm wrong. Note In Scala a Trait is similar to an in an interface. For all intents of this example please assume that the Trait is just another word for "Interface" and that the return type "Unit" is the same as "Void".



trait IDataChannel {

def send(message: String)
def receive(): String

}

trait IConnection {

def dial(number: String)
def hangup()

}

trait IModem extends IConnection with IDataChannel{}

class ModemImpl extends IModem {

def hangup(): Unit = {}

def receive() = { "hi" }

def send(message: String): Unit = {}

def dial(number: String): Unit = {}

}









share|improve this question




















  • 1





    What doesn't seem right? Your ModemImpl class does indeed implement the methods individually.

    – Kache
    15 hours ago











  • Exactly. So, therefore, this still violates the SRP. ModemImpl still has more than "one reason to change".

    – alex
    14 hours ago











  • Please post the code with Martins fix. We shouldn't need the book handy to help you.

    – candied_orange
    14 hours ago











  • There is no code from his fix he just drew a UML diagram as his solution that pointed the Modem class to IConnection and IDataChannel. See the edit to my post I put a link to a picture that shows an example of what he drew.

    – alex
    14 hours ago
















1












1








1


1






I am currently reading through Robert Martins book "Agile Software Development" book and I am struggling to see how his modem example provides any benefit.



He says that he has an interface that violates the SRP



interface Modem 
{
public void dial(String pno);
public void hangup();
public void send(char c);
public char recv();
}


So he decides to break it up so that the Modem Implementation relies on a Connection interface and Data channel Interface. However then when Modem implements Connection and Data Channel Interfaces, his class Modem must still implement the methods individually!



enter image description here



To me, this doesn't seem right. I believe I may have a misunderstanding and hoping someone can point me where I'm wrong. Here is my implementation in Scala that represents my understanding.



I hope someone may be able to point me to where I'm wrong. Note In Scala a Trait is similar to an in an interface. For all intents of this example please assume that the Trait is just another word for "Interface" and that the return type "Unit" is the same as "Void".



trait IDataChannel {

def send(message: String)
def receive(): String

}

trait IConnection {

def dial(number: String)
def hangup()

}

trait IModem extends IConnection with IDataChannel{}

class ModemImpl extends IModem {

def hangup(): Unit = {}

def receive() = { "hi" }

def send(message: String): Unit = {}

def dial(number: String): Unit = {}

}









share|improve this question
















I am currently reading through Robert Martins book "Agile Software Development" book and I am struggling to see how his modem example provides any benefit.



He says that he has an interface that violates the SRP



interface Modem 
{
public void dial(String pno);
public void hangup();
public void send(char c);
public char recv();
}


So he decides to break it up so that the Modem Implementation relies on a Connection interface and Data channel Interface. However then when Modem implements Connection and Data Channel Interfaces, his class Modem must still implement the methods individually!



enter image description here



To me, this doesn't seem right. I believe I may have a misunderstanding and hoping someone can point me where I'm wrong. Here is my implementation in Scala that represents my understanding.



I hope someone may be able to point me to where I'm wrong. Note In Scala a Trait is similar to an in an interface. For all intents of this example please assume that the Trait is just another word for "Interface" and that the return type "Unit" is the same as "Void".



trait IDataChannel {

def send(message: String)
def receive(): String

}

trait IConnection {

def dial(number: String)
def hangup()

}

trait IModem extends IConnection with IDataChannel{}

class ModemImpl extends IModem {

def hangup(): Unit = {}

def receive() = { "hi" }

def send(message: String): Unit = {}

def dial(number: String): Unit = {}

}






object-oriented object-oriented-design single-responsibility






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 9 mins ago









Doc Brown

134k23246396




134k23246396










asked 15 hours ago









alexalex

294




294








  • 1





    What doesn't seem right? Your ModemImpl class does indeed implement the methods individually.

    – Kache
    15 hours ago











  • Exactly. So, therefore, this still violates the SRP. ModemImpl still has more than "one reason to change".

    – alex
    14 hours ago











  • Please post the code with Martins fix. We shouldn't need the book handy to help you.

    – candied_orange
    14 hours ago











  • There is no code from his fix he just drew a UML diagram as his solution that pointed the Modem class to IConnection and IDataChannel. See the edit to my post I put a link to a picture that shows an example of what he drew.

    – alex
    14 hours ago
















  • 1





    What doesn't seem right? Your ModemImpl class does indeed implement the methods individually.

    – Kache
    15 hours ago











  • Exactly. So, therefore, this still violates the SRP. ModemImpl still has more than "one reason to change".

    – alex
    14 hours ago











  • Please post the code with Martins fix. We shouldn't need the book handy to help you.

    – candied_orange
    14 hours ago











  • There is no code from his fix he just drew a UML diagram as his solution that pointed the Modem class to IConnection and IDataChannel. See the edit to my post I put a link to a picture that shows an example of what he drew.

    – alex
    14 hours ago










1




1





What doesn't seem right? Your ModemImpl class does indeed implement the methods individually.

– Kache
15 hours ago





What doesn't seem right? Your ModemImpl class does indeed implement the methods individually.

– Kache
15 hours ago













Exactly. So, therefore, this still violates the SRP. ModemImpl still has more than "one reason to change".

– alex
14 hours ago





Exactly. So, therefore, this still violates the SRP. ModemImpl still has more than "one reason to change".

– alex
14 hours ago













Please post the code with Martins fix. We shouldn't need the book handy to help you.

– candied_orange
14 hours ago





Please post the code with Martins fix. We shouldn't need the book handy to help you.

– candied_orange
14 hours ago













There is no code from his fix he just drew a UML diagram as his solution that pointed the Modem class to IConnection and IDataChannel. See the edit to my post I put a link to a picture that shows an example of what he drew.

– alex
14 hours ago







There is no code from his fix he just drew a UML diagram as his solution that pointed the Modem class to IConnection and IDataChannel. See the edit to my post I put a link to a picture that shows an example of what he drew.

– alex
14 hours ago












3 Answers
3






active

oldest

votes


















1














I can see why you are confused as his writing presumes a little more design savviness on the part of the reader, and so is a little handwavy.



Responsibilities are dependent on the domain and on how software evolves ("reason to change", not as imagined solely by the developer, but as established (possibly over time) by business needs - by the outside forces that drive changes in the codebase). To create maintainable code, you (and your team) have to figure these out and structure your software over time to support those kinds of changes. (Note that initially, doing design doesn't pay off in an obvious way, which is why it's not easy for less experienced developers to see its utility; on top of that there is risk of "overdesign". But later on, if you don't consider it, you get in trouble.)



So he starts with the assumption that it has somehow been established that connection management and data communication are two distinct responsibilities - in the sense that when you look at the change requests they generally don't change together.



Then he talks about the responsibilities of the interface itself - which you could read as different reasons for the interface to change. This is of interest, because, even though it has no implementation, it's a static peace of code that other code depends on. One of the major concerns in design is controlling the directions and the structure of dependencies, because changes propagate backwards along dependency arrows (which is why DIP is a technique to stop that propagation - it reverses the arrow at some point).



He doesn't say much about how separating the interface allows you to achieve (or rather, increase) independent evolvability of the client code that calls the two interfaces. But if I had to fill in the blanks: this relies on the discipline and design knowledge of the developers, in the sense that they can now, in client code, leverage this to separate the "orchestration" of these calls (the "orchestration", the logic of what is called and when - being the responsibility of the clients). This may be as simple as two different client classes, or something more involved, where the clients reside in separate DLLs. On top of that, clients do not know if the interface is implemented by a single class, or two separate classes, or a whole subsystem. So that gives you flexibility to change the implementation behind the interface.



He also says, and this is important, if these two don't change separately (either because they don't change at all, or because their changes are strongly correlated), you shouldn't apply SRP or ISP just for the sake of it.




An axis of change is an axis of change only if the changes occur. It
is not wise to apply SRP or any other principle, for that matter if
there is no symptom.




So, you don't do design once - yes, you come up with something initially, but you develop it and reconsider it over time.



As for the SRP violation in the implementation - in the paragraph just below the text you've read so far, he acknowledges that, and writes:




Note that [...] I kept both responsibilities coupled in the
ModemImplementation class. This is not desirable, but it may be
necessary. There are often reasons, having to do with the details of
the hardware or operating system, that force us to couple things that
we'd rather not couple. However, by separating their interfaces, we
have decoupled the concepts as far as the rest of the application is
concerned.



We may view the ModemImplementation class as a kludge or a wart;
however, note that all dependencies flow away from it. Nobody needs to
depend on this class. Nobody except main needs to know that it exists.
Thus, we've put the ugly bit behind a fence. Its ugliness need not
leak out and pollute the rest of the application.




So there's a fair bit of depth to it - understanding the domain, understanding practical considerations, understanding trade-offs, etc.






share|improve this answer


























  • Huh interesting. So even after his solution, he knows that the Modem class still violates SRP. So do you think of an implementation of Modem class that will not violate SRP?

    – alex
    12 hours ago






  • 1





    You just create two separate classes. But his point is that we don't work in an ideal world. E.g., you may be using a framework that makes it in some way difficult to to separate the implementation (e.g., because of the way it's structured, or the way it works, or for performance reasons), so that the cost of separation outweighs the benefits - and this is something that you (and your team) have to consider (it's kind of part of what your job is about). A lot of design has to do with thinking about trade-offs: you pay something to gain something, so it's about deciding if the cost is worth it.

    – Filip Milovanović
    12 hours ago













  • @alex: actually, I don't think the Modem class really violates the SRP on its level of abstraction. See my former answer to a similar question here.

    – Doc Brown
    10 mins ago



















2














SRP actually stands for Single Responsibility Principle. Mr. Martin is correct that the Modem interface violates SRP. You are correct that ModemImpl violates SRP. Neither separate the Connection and Data responsibilities. Mr. Martin was fixing the interface. He has not fixed the Modem class. One thing to understand about these principles is that they can be applied in stages as you make the code better.



Usually when SRP is focused on interfaces the Interface Segregation Principle is mentioned. When this is followed the rest of the system neither knows nor cares how messed up your implementation class is, so long as it can be used the way it needs to use it.



Now that the interface is fixed, and presumably the code that uses it, the implementation can be fixed painlessly, or it can be ignored while you work on more important things secure in the knowledge that at least this SRP violation isn't spreading around the code base.



To understand that better imagine what the using code might be. When data comes in it will need to wait if there is no connection. If data cannot be sent immediately it must be buffered or discarded. This couples the act of sending data to the connection state. If you have access to all four methods it's very temping to go ahead and manage all that.



However, if all you want to think about is sending and receiving it's very nice to focus on the Data interface and let the connection issue be something elses problem.



UDP is perfectly happy sending sending packets into oblivion. It doesn't care if they get there or not. If you're doing something like this why would you even want access to those other methods? If being sure that the modem is connected is something elses job don't make it look like we have to deal with it or some ambitious bug hunter will mistakenly think they have to deal with it and now the SRP violation is spreading in the code base. Don't make me think about things I don't need to think about.






share|improve this answer


























  • Thanks for the answer. So could you clarify how you mean "the rest of the system neither knows how messed up the impl. class is? " Is that because I may have some class "Computer" that programs to use the IModem interface?

    – alex
    13 hours ago











  • I'm also a little confused here. So is there no better way to create the Modem class so that it doesn't violate the SRP?

    – alex
    13 hours ago






  • 1





    If it needs to handle both connection and messaging, then no. Maybe you don't need a Modem class and would be better served with two classes? Objects in OOP don't need to correspond one-to-one with real life objects. Consider creating a ModemConnection class and a ModemData class.

    – Martin Epsz
    11 hours ago













  • Mechanically, @alex, actual code would just want an IData and/or an IConnection, to use the names from your question. It wouldn't care if the IData is a Modem, a post office, or cannons & parachutes; it just cares that you can use it for dispatch & delivery. Nor would it care if the IConnection is a Modem, a satellite, or hundreds of dogs on hills barking in code; it just cares that it can create and end a connection to a distant entity.

    – Justin Time
    11 hours ago













  • @alex better now?

    – candied_orange
    57 mins ago



















0














SRP is about reason for change, and people.




  1. The network guy is responsible for going in and writing the connection related code, and provide you basics for how to send packets (e.g. read4bytes and write4bytes)

  2. The application logic guy is responsible for going in and providing higher-level semantics like send and receive.


problem



trait IModem extends IConnection with IDataChannel{}


You wouldn't do that, as this IModem violates SRP. Your ModemImpl class would just consume those traits.




So he decides to break it up so that the Modem Implementation relies on a Connection interface and Data channel Interface. However then when Modem implements Connection and Data Channel Interfaces, his class Modem must still implement the methods individually!




Traits / Interfaces are what other parts of the software consume, so the interfaces are okay wrt. SRP. The implementation is up you, and you hide those details from the other parts of the system.
SRP does not do away with coupling, and you need to resolve that in the implementation, but conceptually the traits are clean.






share|improve this answer























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


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fsoftwareengineering.stackexchange.com%2fquestions%2f387966%2fconfusion-on-single-responsibility-principle-srp-with-modem-example%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    3 Answers
    3






    active

    oldest

    votes








    3 Answers
    3






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    1














    I can see why you are confused as his writing presumes a little more design savviness on the part of the reader, and so is a little handwavy.



    Responsibilities are dependent on the domain and on how software evolves ("reason to change", not as imagined solely by the developer, but as established (possibly over time) by business needs - by the outside forces that drive changes in the codebase). To create maintainable code, you (and your team) have to figure these out and structure your software over time to support those kinds of changes. (Note that initially, doing design doesn't pay off in an obvious way, which is why it's not easy for less experienced developers to see its utility; on top of that there is risk of "overdesign". But later on, if you don't consider it, you get in trouble.)



    So he starts with the assumption that it has somehow been established that connection management and data communication are two distinct responsibilities - in the sense that when you look at the change requests they generally don't change together.



    Then he talks about the responsibilities of the interface itself - which you could read as different reasons for the interface to change. This is of interest, because, even though it has no implementation, it's a static peace of code that other code depends on. One of the major concerns in design is controlling the directions and the structure of dependencies, because changes propagate backwards along dependency arrows (which is why DIP is a technique to stop that propagation - it reverses the arrow at some point).



    He doesn't say much about how separating the interface allows you to achieve (or rather, increase) independent evolvability of the client code that calls the two interfaces. But if I had to fill in the blanks: this relies on the discipline and design knowledge of the developers, in the sense that they can now, in client code, leverage this to separate the "orchestration" of these calls (the "orchestration", the logic of what is called and when - being the responsibility of the clients). This may be as simple as two different client classes, or something more involved, where the clients reside in separate DLLs. On top of that, clients do not know if the interface is implemented by a single class, or two separate classes, or a whole subsystem. So that gives you flexibility to change the implementation behind the interface.



    He also says, and this is important, if these two don't change separately (either because they don't change at all, or because their changes are strongly correlated), you shouldn't apply SRP or ISP just for the sake of it.




    An axis of change is an axis of change only if the changes occur. It
    is not wise to apply SRP or any other principle, for that matter if
    there is no symptom.




    So, you don't do design once - yes, you come up with something initially, but you develop it and reconsider it over time.



    As for the SRP violation in the implementation - in the paragraph just below the text you've read so far, he acknowledges that, and writes:




    Note that [...] I kept both responsibilities coupled in the
    ModemImplementation class. This is not desirable, but it may be
    necessary. There are often reasons, having to do with the details of
    the hardware or operating system, that force us to couple things that
    we'd rather not couple. However, by separating their interfaces, we
    have decoupled the concepts as far as the rest of the application is
    concerned.



    We may view the ModemImplementation class as a kludge or a wart;
    however, note that all dependencies flow away from it. Nobody needs to
    depend on this class. Nobody except main needs to know that it exists.
    Thus, we've put the ugly bit behind a fence. Its ugliness need not
    leak out and pollute the rest of the application.




    So there's a fair bit of depth to it - understanding the domain, understanding practical considerations, understanding trade-offs, etc.






    share|improve this answer


























    • Huh interesting. So even after his solution, he knows that the Modem class still violates SRP. So do you think of an implementation of Modem class that will not violate SRP?

      – alex
      12 hours ago






    • 1





      You just create two separate classes. But his point is that we don't work in an ideal world. E.g., you may be using a framework that makes it in some way difficult to to separate the implementation (e.g., because of the way it's structured, or the way it works, or for performance reasons), so that the cost of separation outweighs the benefits - and this is something that you (and your team) have to consider (it's kind of part of what your job is about). A lot of design has to do with thinking about trade-offs: you pay something to gain something, so it's about deciding if the cost is worth it.

      – Filip Milovanović
      12 hours ago













    • @alex: actually, I don't think the Modem class really violates the SRP on its level of abstraction. See my former answer to a similar question here.

      – Doc Brown
      10 mins ago
















    1














    I can see why you are confused as his writing presumes a little more design savviness on the part of the reader, and so is a little handwavy.



    Responsibilities are dependent on the domain and on how software evolves ("reason to change", not as imagined solely by the developer, but as established (possibly over time) by business needs - by the outside forces that drive changes in the codebase). To create maintainable code, you (and your team) have to figure these out and structure your software over time to support those kinds of changes. (Note that initially, doing design doesn't pay off in an obvious way, which is why it's not easy for less experienced developers to see its utility; on top of that there is risk of "overdesign". But later on, if you don't consider it, you get in trouble.)



    So he starts with the assumption that it has somehow been established that connection management and data communication are two distinct responsibilities - in the sense that when you look at the change requests they generally don't change together.



    Then he talks about the responsibilities of the interface itself - which you could read as different reasons for the interface to change. This is of interest, because, even though it has no implementation, it's a static peace of code that other code depends on. One of the major concerns in design is controlling the directions and the structure of dependencies, because changes propagate backwards along dependency arrows (which is why DIP is a technique to stop that propagation - it reverses the arrow at some point).



    He doesn't say much about how separating the interface allows you to achieve (or rather, increase) independent evolvability of the client code that calls the two interfaces. But if I had to fill in the blanks: this relies on the discipline and design knowledge of the developers, in the sense that they can now, in client code, leverage this to separate the "orchestration" of these calls (the "orchestration", the logic of what is called and when - being the responsibility of the clients). This may be as simple as two different client classes, or something more involved, where the clients reside in separate DLLs. On top of that, clients do not know if the interface is implemented by a single class, or two separate classes, or a whole subsystem. So that gives you flexibility to change the implementation behind the interface.



    He also says, and this is important, if these two don't change separately (either because they don't change at all, or because their changes are strongly correlated), you shouldn't apply SRP or ISP just for the sake of it.




    An axis of change is an axis of change only if the changes occur. It
    is not wise to apply SRP or any other principle, for that matter if
    there is no symptom.




    So, you don't do design once - yes, you come up with something initially, but you develop it and reconsider it over time.



    As for the SRP violation in the implementation - in the paragraph just below the text you've read so far, he acknowledges that, and writes:




    Note that [...] I kept both responsibilities coupled in the
    ModemImplementation class. This is not desirable, but it may be
    necessary. There are often reasons, having to do with the details of
    the hardware or operating system, that force us to couple things that
    we'd rather not couple. However, by separating their interfaces, we
    have decoupled the concepts as far as the rest of the application is
    concerned.



    We may view the ModemImplementation class as a kludge or a wart;
    however, note that all dependencies flow away from it. Nobody needs to
    depend on this class. Nobody except main needs to know that it exists.
    Thus, we've put the ugly bit behind a fence. Its ugliness need not
    leak out and pollute the rest of the application.




    So there's a fair bit of depth to it - understanding the domain, understanding practical considerations, understanding trade-offs, etc.






    share|improve this answer


























    • Huh interesting. So even after his solution, he knows that the Modem class still violates SRP. So do you think of an implementation of Modem class that will not violate SRP?

      – alex
      12 hours ago






    • 1





      You just create two separate classes. But his point is that we don't work in an ideal world. E.g., you may be using a framework that makes it in some way difficult to to separate the implementation (e.g., because of the way it's structured, or the way it works, or for performance reasons), so that the cost of separation outweighs the benefits - and this is something that you (and your team) have to consider (it's kind of part of what your job is about). A lot of design has to do with thinking about trade-offs: you pay something to gain something, so it's about deciding if the cost is worth it.

      – Filip Milovanović
      12 hours ago













    • @alex: actually, I don't think the Modem class really violates the SRP on its level of abstraction. See my former answer to a similar question here.

      – Doc Brown
      10 mins ago














    1












    1








    1







    I can see why you are confused as his writing presumes a little more design savviness on the part of the reader, and so is a little handwavy.



    Responsibilities are dependent on the domain and on how software evolves ("reason to change", not as imagined solely by the developer, but as established (possibly over time) by business needs - by the outside forces that drive changes in the codebase). To create maintainable code, you (and your team) have to figure these out and structure your software over time to support those kinds of changes. (Note that initially, doing design doesn't pay off in an obvious way, which is why it's not easy for less experienced developers to see its utility; on top of that there is risk of "overdesign". But later on, if you don't consider it, you get in trouble.)



    So he starts with the assumption that it has somehow been established that connection management and data communication are two distinct responsibilities - in the sense that when you look at the change requests they generally don't change together.



    Then he talks about the responsibilities of the interface itself - which you could read as different reasons for the interface to change. This is of interest, because, even though it has no implementation, it's a static peace of code that other code depends on. One of the major concerns in design is controlling the directions and the structure of dependencies, because changes propagate backwards along dependency arrows (which is why DIP is a technique to stop that propagation - it reverses the arrow at some point).



    He doesn't say much about how separating the interface allows you to achieve (or rather, increase) independent evolvability of the client code that calls the two interfaces. But if I had to fill in the blanks: this relies on the discipline and design knowledge of the developers, in the sense that they can now, in client code, leverage this to separate the "orchestration" of these calls (the "orchestration", the logic of what is called and when - being the responsibility of the clients). This may be as simple as two different client classes, or something more involved, where the clients reside in separate DLLs. On top of that, clients do not know if the interface is implemented by a single class, or two separate classes, or a whole subsystem. So that gives you flexibility to change the implementation behind the interface.



    He also says, and this is important, if these two don't change separately (either because they don't change at all, or because their changes are strongly correlated), you shouldn't apply SRP or ISP just for the sake of it.




    An axis of change is an axis of change only if the changes occur. It
    is not wise to apply SRP or any other principle, for that matter if
    there is no symptom.




    So, you don't do design once - yes, you come up with something initially, but you develop it and reconsider it over time.



    As for the SRP violation in the implementation - in the paragraph just below the text you've read so far, he acknowledges that, and writes:




    Note that [...] I kept both responsibilities coupled in the
    ModemImplementation class. This is not desirable, but it may be
    necessary. There are often reasons, having to do with the details of
    the hardware or operating system, that force us to couple things that
    we'd rather not couple. However, by separating their interfaces, we
    have decoupled the concepts as far as the rest of the application is
    concerned.



    We may view the ModemImplementation class as a kludge or a wart;
    however, note that all dependencies flow away from it. Nobody needs to
    depend on this class. Nobody except main needs to know that it exists.
    Thus, we've put the ugly bit behind a fence. Its ugliness need not
    leak out and pollute the rest of the application.




    So there's a fair bit of depth to it - understanding the domain, understanding practical considerations, understanding trade-offs, etc.






    share|improve this answer















    I can see why you are confused as his writing presumes a little more design savviness on the part of the reader, and so is a little handwavy.



    Responsibilities are dependent on the domain and on how software evolves ("reason to change", not as imagined solely by the developer, but as established (possibly over time) by business needs - by the outside forces that drive changes in the codebase). To create maintainable code, you (and your team) have to figure these out and structure your software over time to support those kinds of changes. (Note that initially, doing design doesn't pay off in an obvious way, which is why it's not easy for less experienced developers to see its utility; on top of that there is risk of "overdesign". But later on, if you don't consider it, you get in trouble.)



    So he starts with the assumption that it has somehow been established that connection management and data communication are two distinct responsibilities - in the sense that when you look at the change requests they generally don't change together.



    Then he talks about the responsibilities of the interface itself - which you could read as different reasons for the interface to change. This is of interest, because, even though it has no implementation, it's a static peace of code that other code depends on. One of the major concerns in design is controlling the directions and the structure of dependencies, because changes propagate backwards along dependency arrows (which is why DIP is a technique to stop that propagation - it reverses the arrow at some point).



    He doesn't say much about how separating the interface allows you to achieve (or rather, increase) independent evolvability of the client code that calls the two interfaces. But if I had to fill in the blanks: this relies on the discipline and design knowledge of the developers, in the sense that they can now, in client code, leverage this to separate the "orchestration" of these calls (the "orchestration", the logic of what is called and when - being the responsibility of the clients). This may be as simple as two different client classes, or something more involved, where the clients reside in separate DLLs. On top of that, clients do not know if the interface is implemented by a single class, or two separate classes, or a whole subsystem. So that gives you flexibility to change the implementation behind the interface.



    He also says, and this is important, if these two don't change separately (either because they don't change at all, or because their changes are strongly correlated), you shouldn't apply SRP or ISP just for the sake of it.




    An axis of change is an axis of change only if the changes occur. It
    is not wise to apply SRP or any other principle, for that matter if
    there is no symptom.




    So, you don't do design once - yes, you come up with something initially, but you develop it and reconsider it over time.



    As for the SRP violation in the implementation - in the paragraph just below the text you've read so far, he acknowledges that, and writes:




    Note that [...] I kept both responsibilities coupled in the
    ModemImplementation class. This is not desirable, but it may be
    necessary. There are often reasons, having to do with the details of
    the hardware or operating system, that force us to couple things that
    we'd rather not couple. However, by separating their interfaces, we
    have decoupled the concepts as far as the rest of the application is
    concerned.



    We may view the ModemImplementation class as a kludge or a wart;
    however, note that all dependencies flow away from it. Nobody needs to
    depend on this class. Nobody except main needs to know that it exists.
    Thus, we've put the ugly bit behind a fence. Its ugliness need not
    leak out and pollute the rest of the application.




    So there's a fair bit of depth to it - understanding the domain, understanding practical considerations, understanding trade-offs, etc.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited 13 hours ago

























    answered 13 hours ago









    Filip MilovanovićFilip Milovanović

    1,75439




    1,75439













    • Huh interesting. So even after his solution, he knows that the Modem class still violates SRP. So do you think of an implementation of Modem class that will not violate SRP?

      – alex
      12 hours ago






    • 1





      You just create two separate classes. But his point is that we don't work in an ideal world. E.g., you may be using a framework that makes it in some way difficult to to separate the implementation (e.g., because of the way it's structured, or the way it works, or for performance reasons), so that the cost of separation outweighs the benefits - and this is something that you (and your team) have to consider (it's kind of part of what your job is about). A lot of design has to do with thinking about trade-offs: you pay something to gain something, so it's about deciding if the cost is worth it.

      – Filip Milovanović
      12 hours ago













    • @alex: actually, I don't think the Modem class really violates the SRP on its level of abstraction. See my former answer to a similar question here.

      – Doc Brown
      10 mins ago



















    • Huh interesting. So even after his solution, he knows that the Modem class still violates SRP. So do you think of an implementation of Modem class that will not violate SRP?

      – alex
      12 hours ago






    • 1





      You just create two separate classes. But his point is that we don't work in an ideal world. E.g., you may be using a framework that makes it in some way difficult to to separate the implementation (e.g., because of the way it's structured, or the way it works, or for performance reasons), so that the cost of separation outweighs the benefits - and this is something that you (and your team) have to consider (it's kind of part of what your job is about). A lot of design has to do with thinking about trade-offs: you pay something to gain something, so it's about deciding if the cost is worth it.

      – Filip Milovanović
      12 hours ago













    • @alex: actually, I don't think the Modem class really violates the SRP on its level of abstraction. See my former answer to a similar question here.

      – Doc Brown
      10 mins ago

















    Huh interesting. So even after his solution, he knows that the Modem class still violates SRP. So do you think of an implementation of Modem class that will not violate SRP?

    – alex
    12 hours ago





    Huh interesting. So even after his solution, he knows that the Modem class still violates SRP. So do you think of an implementation of Modem class that will not violate SRP?

    – alex
    12 hours ago




    1




    1





    You just create two separate classes. But his point is that we don't work in an ideal world. E.g., you may be using a framework that makes it in some way difficult to to separate the implementation (e.g., because of the way it's structured, or the way it works, or for performance reasons), so that the cost of separation outweighs the benefits - and this is something that you (and your team) have to consider (it's kind of part of what your job is about). A lot of design has to do with thinking about trade-offs: you pay something to gain something, so it's about deciding if the cost is worth it.

    – Filip Milovanović
    12 hours ago







    You just create two separate classes. But his point is that we don't work in an ideal world. E.g., you may be using a framework that makes it in some way difficult to to separate the implementation (e.g., because of the way it's structured, or the way it works, or for performance reasons), so that the cost of separation outweighs the benefits - and this is something that you (and your team) have to consider (it's kind of part of what your job is about). A lot of design has to do with thinking about trade-offs: you pay something to gain something, so it's about deciding if the cost is worth it.

    – Filip Milovanović
    12 hours ago















    @alex: actually, I don't think the Modem class really violates the SRP on its level of abstraction. See my former answer to a similar question here.

    – Doc Brown
    10 mins ago





    @alex: actually, I don't think the Modem class really violates the SRP on its level of abstraction. See my former answer to a similar question here.

    – Doc Brown
    10 mins ago













    2














    SRP actually stands for Single Responsibility Principle. Mr. Martin is correct that the Modem interface violates SRP. You are correct that ModemImpl violates SRP. Neither separate the Connection and Data responsibilities. Mr. Martin was fixing the interface. He has not fixed the Modem class. One thing to understand about these principles is that they can be applied in stages as you make the code better.



    Usually when SRP is focused on interfaces the Interface Segregation Principle is mentioned. When this is followed the rest of the system neither knows nor cares how messed up your implementation class is, so long as it can be used the way it needs to use it.



    Now that the interface is fixed, and presumably the code that uses it, the implementation can be fixed painlessly, or it can be ignored while you work on more important things secure in the knowledge that at least this SRP violation isn't spreading around the code base.



    To understand that better imagine what the using code might be. When data comes in it will need to wait if there is no connection. If data cannot be sent immediately it must be buffered or discarded. This couples the act of sending data to the connection state. If you have access to all four methods it's very temping to go ahead and manage all that.



    However, if all you want to think about is sending and receiving it's very nice to focus on the Data interface and let the connection issue be something elses problem.



    UDP is perfectly happy sending sending packets into oblivion. It doesn't care if they get there or not. If you're doing something like this why would you even want access to those other methods? If being sure that the modem is connected is something elses job don't make it look like we have to deal with it or some ambitious bug hunter will mistakenly think they have to deal with it and now the SRP violation is spreading in the code base. Don't make me think about things I don't need to think about.






    share|improve this answer


























    • Thanks for the answer. So could you clarify how you mean "the rest of the system neither knows how messed up the impl. class is? " Is that because I may have some class "Computer" that programs to use the IModem interface?

      – alex
      13 hours ago











    • I'm also a little confused here. So is there no better way to create the Modem class so that it doesn't violate the SRP?

      – alex
      13 hours ago






    • 1





      If it needs to handle both connection and messaging, then no. Maybe you don't need a Modem class and would be better served with two classes? Objects in OOP don't need to correspond one-to-one with real life objects. Consider creating a ModemConnection class and a ModemData class.

      – Martin Epsz
      11 hours ago













    • Mechanically, @alex, actual code would just want an IData and/or an IConnection, to use the names from your question. It wouldn't care if the IData is a Modem, a post office, or cannons & parachutes; it just cares that you can use it for dispatch & delivery. Nor would it care if the IConnection is a Modem, a satellite, or hundreds of dogs on hills barking in code; it just cares that it can create and end a connection to a distant entity.

      – Justin Time
      11 hours ago













    • @alex better now?

      – candied_orange
      57 mins ago
















    2














    SRP actually stands for Single Responsibility Principle. Mr. Martin is correct that the Modem interface violates SRP. You are correct that ModemImpl violates SRP. Neither separate the Connection and Data responsibilities. Mr. Martin was fixing the interface. He has not fixed the Modem class. One thing to understand about these principles is that they can be applied in stages as you make the code better.



    Usually when SRP is focused on interfaces the Interface Segregation Principle is mentioned. When this is followed the rest of the system neither knows nor cares how messed up your implementation class is, so long as it can be used the way it needs to use it.



    Now that the interface is fixed, and presumably the code that uses it, the implementation can be fixed painlessly, or it can be ignored while you work on more important things secure in the knowledge that at least this SRP violation isn't spreading around the code base.



    To understand that better imagine what the using code might be. When data comes in it will need to wait if there is no connection. If data cannot be sent immediately it must be buffered or discarded. This couples the act of sending data to the connection state. If you have access to all four methods it's very temping to go ahead and manage all that.



    However, if all you want to think about is sending and receiving it's very nice to focus on the Data interface and let the connection issue be something elses problem.



    UDP is perfectly happy sending sending packets into oblivion. It doesn't care if they get there or not. If you're doing something like this why would you even want access to those other methods? If being sure that the modem is connected is something elses job don't make it look like we have to deal with it or some ambitious bug hunter will mistakenly think they have to deal with it and now the SRP violation is spreading in the code base. Don't make me think about things I don't need to think about.






    share|improve this answer


























    • Thanks for the answer. So could you clarify how you mean "the rest of the system neither knows how messed up the impl. class is? " Is that because I may have some class "Computer" that programs to use the IModem interface?

      – alex
      13 hours ago











    • I'm also a little confused here. So is there no better way to create the Modem class so that it doesn't violate the SRP?

      – alex
      13 hours ago






    • 1





      If it needs to handle both connection and messaging, then no. Maybe you don't need a Modem class and would be better served with two classes? Objects in OOP don't need to correspond one-to-one with real life objects. Consider creating a ModemConnection class and a ModemData class.

      – Martin Epsz
      11 hours ago













    • Mechanically, @alex, actual code would just want an IData and/or an IConnection, to use the names from your question. It wouldn't care if the IData is a Modem, a post office, or cannons & parachutes; it just cares that you can use it for dispatch & delivery. Nor would it care if the IConnection is a Modem, a satellite, or hundreds of dogs on hills barking in code; it just cares that it can create and end a connection to a distant entity.

      – Justin Time
      11 hours ago













    • @alex better now?

      – candied_orange
      57 mins ago














    2












    2








    2







    SRP actually stands for Single Responsibility Principle. Mr. Martin is correct that the Modem interface violates SRP. You are correct that ModemImpl violates SRP. Neither separate the Connection and Data responsibilities. Mr. Martin was fixing the interface. He has not fixed the Modem class. One thing to understand about these principles is that they can be applied in stages as you make the code better.



    Usually when SRP is focused on interfaces the Interface Segregation Principle is mentioned. When this is followed the rest of the system neither knows nor cares how messed up your implementation class is, so long as it can be used the way it needs to use it.



    Now that the interface is fixed, and presumably the code that uses it, the implementation can be fixed painlessly, or it can be ignored while you work on more important things secure in the knowledge that at least this SRP violation isn't spreading around the code base.



    To understand that better imagine what the using code might be. When data comes in it will need to wait if there is no connection. If data cannot be sent immediately it must be buffered or discarded. This couples the act of sending data to the connection state. If you have access to all four methods it's very temping to go ahead and manage all that.



    However, if all you want to think about is sending and receiving it's very nice to focus on the Data interface and let the connection issue be something elses problem.



    UDP is perfectly happy sending sending packets into oblivion. It doesn't care if they get there or not. If you're doing something like this why would you even want access to those other methods? If being sure that the modem is connected is something elses job don't make it look like we have to deal with it or some ambitious bug hunter will mistakenly think they have to deal with it and now the SRP violation is spreading in the code base. Don't make me think about things I don't need to think about.






    share|improve this answer















    SRP actually stands for Single Responsibility Principle. Mr. Martin is correct that the Modem interface violates SRP. You are correct that ModemImpl violates SRP. Neither separate the Connection and Data responsibilities. Mr. Martin was fixing the interface. He has not fixed the Modem class. One thing to understand about these principles is that they can be applied in stages as you make the code better.



    Usually when SRP is focused on interfaces the Interface Segregation Principle is mentioned. When this is followed the rest of the system neither knows nor cares how messed up your implementation class is, so long as it can be used the way it needs to use it.



    Now that the interface is fixed, and presumably the code that uses it, the implementation can be fixed painlessly, or it can be ignored while you work on more important things secure in the knowledge that at least this SRP violation isn't spreading around the code base.



    To understand that better imagine what the using code might be. When data comes in it will need to wait if there is no connection. If data cannot be sent immediately it must be buffered or discarded. This couples the act of sending data to the connection state. If you have access to all four methods it's very temping to go ahead and manage all that.



    However, if all you want to think about is sending and receiving it's very nice to focus on the Data interface and let the connection issue be something elses problem.



    UDP is perfectly happy sending sending packets into oblivion. It doesn't care if they get there or not. If you're doing something like this why would you even want access to those other methods? If being sure that the modem is connected is something elses job don't make it look like we have to deal with it or some ambitious bug hunter will mistakenly think they have to deal with it and now the SRP violation is spreading in the code base. Don't make me think about things I don't need to think about.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited 59 mins ago

























    answered 13 hours ago









    candied_orangecandied_orange

    53.8k17100188




    53.8k17100188













    • Thanks for the answer. So could you clarify how you mean "the rest of the system neither knows how messed up the impl. class is? " Is that because I may have some class "Computer" that programs to use the IModem interface?

      – alex
      13 hours ago











    • I'm also a little confused here. So is there no better way to create the Modem class so that it doesn't violate the SRP?

      – alex
      13 hours ago






    • 1





      If it needs to handle both connection and messaging, then no. Maybe you don't need a Modem class and would be better served with two classes? Objects in OOP don't need to correspond one-to-one with real life objects. Consider creating a ModemConnection class and a ModemData class.

      – Martin Epsz
      11 hours ago













    • Mechanically, @alex, actual code would just want an IData and/or an IConnection, to use the names from your question. It wouldn't care if the IData is a Modem, a post office, or cannons & parachutes; it just cares that you can use it for dispatch & delivery. Nor would it care if the IConnection is a Modem, a satellite, or hundreds of dogs on hills barking in code; it just cares that it can create and end a connection to a distant entity.

      – Justin Time
      11 hours ago













    • @alex better now?

      – candied_orange
      57 mins ago



















    • Thanks for the answer. So could you clarify how you mean "the rest of the system neither knows how messed up the impl. class is? " Is that because I may have some class "Computer" that programs to use the IModem interface?

      – alex
      13 hours ago











    • I'm also a little confused here. So is there no better way to create the Modem class so that it doesn't violate the SRP?

      – alex
      13 hours ago






    • 1





      If it needs to handle both connection and messaging, then no. Maybe you don't need a Modem class and would be better served with two classes? Objects in OOP don't need to correspond one-to-one with real life objects. Consider creating a ModemConnection class and a ModemData class.

      – Martin Epsz
      11 hours ago













    • Mechanically, @alex, actual code would just want an IData and/or an IConnection, to use the names from your question. It wouldn't care if the IData is a Modem, a post office, or cannons & parachutes; it just cares that you can use it for dispatch & delivery. Nor would it care if the IConnection is a Modem, a satellite, or hundreds of dogs on hills barking in code; it just cares that it can create and end a connection to a distant entity.

      – Justin Time
      11 hours ago













    • @alex better now?

      – candied_orange
      57 mins ago

















    Thanks for the answer. So could you clarify how you mean "the rest of the system neither knows how messed up the impl. class is? " Is that because I may have some class "Computer" that programs to use the IModem interface?

    – alex
    13 hours ago





    Thanks for the answer. So could you clarify how you mean "the rest of the system neither knows how messed up the impl. class is? " Is that because I may have some class "Computer" that programs to use the IModem interface?

    – alex
    13 hours ago













    I'm also a little confused here. So is there no better way to create the Modem class so that it doesn't violate the SRP?

    – alex
    13 hours ago





    I'm also a little confused here. So is there no better way to create the Modem class so that it doesn't violate the SRP?

    – alex
    13 hours ago




    1




    1





    If it needs to handle both connection and messaging, then no. Maybe you don't need a Modem class and would be better served with two classes? Objects in OOP don't need to correspond one-to-one with real life objects. Consider creating a ModemConnection class and a ModemData class.

    – Martin Epsz
    11 hours ago







    If it needs to handle both connection and messaging, then no. Maybe you don't need a Modem class and would be better served with two classes? Objects in OOP don't need to correspond one-to-one with real life objects. Consider creating a ModemConnection class and a ModemData class.

    – Martin Epsz
    11 hours ago















    Mechanically, @alex, actual code would just want an IData and/or an IConnection, to use the names from your question. It wouldn't care if the IData is a Modem, a post office, or cannons & parachutes; it just cares that you can use it for dispatch & delivery. Nor would it care if the IConnection is a Modem, a satellite, or hundreds of dogs on hills barking in code; it just cares that it can create and end a connection to a distant entity.

    – Justin Time
    11 hours ago







    Mechanically, @alex, actual code would just want an IData and/or an IConnection, to use the names from your question. It wouldn't care if the IData is a Modem, a post office, or cannons & parachutes; it just cares that you can use it for dispatch & delivery. Nor would it care if the IConnection is a Modem, a satellite, or hundreds of dogs on hills barking in code; it just cares that it can create and end a connection to a distant entity.

    – Justin Time
    11 hours ago















    @alex better now?

    – candied_orange
    57 mins ago





    @alex better now?

    – candied_orange
    57 mins ago











    0














    SRP is about reason for change, and people.




    1. The network guy is responsible for going in and writing the connection related code, and provide you basics for how to send packets (e.g. read4bytes and write4bytes)

    2. The application logic guy is responsible for going in and providing higher-level semantics like send and receive.


    problem



    trait IModem extends IConnection with IDataChannel{}


    You wouldn't do that, as this IModem violates SRP. Your ModemImpl class would just consume those traits.




    So he decides to break it up so that the Modem Implementation relies on a Connection interface and Data channel Interface. However then when Modem implements Connection and Data Channel Interfaces, his class Modem must still implement the methods individually!




    Traits / Interfaces are what other parts of the software consume, so the interfaces are okay wrt. SRP. The implementation is up you, and you hide those details from the other parts of the system.
    SRP does not do away with coupling, and you need to resolve that in the implementation, but conceptually the traits are clean.






    share|improve this answer




























      0














      SRP is about reason for change, and people.




      1. The network guy is responsible for going in and writing the connection related code, and provide you basics for how to send packets (e.g. read4bytes and write4bytes)

      2. The application logic guy is responsible for going in and providing higher-level semantics like send and receive.


      problem



      trait IModem extends IConnection with IDataChannel{}


      You wouldn't do that, as this IModem violates SRP. Your ModemImpl class would just consume those traits.




      So he decides to break it up so that the Modem Implementation relies on a Connection interface and Data channel Interface. However then when Modem implements Connection and Data Channel Interfaces, his class Modem must still implement the methods individually!




      Traits / Interfaces are what other parts of the software consume, so the interfaces are okay wrt. SRP. The implementation is up you, and you hide those details from the other parts of the system.
      SRP does not do away with coupling, and you need to resolve that in the implementation, but conceptually the traits are clean.






      share|improve this answer


























        0












        0








        0







        SRP is about reason for change, and people.




        1. The network guy is responsible for going in and writing the connection related code, and provide you basics for how to send packets (e.g. read4bytes and write4bytes)

        2. The application logic guy is responsible for going in and providing higher-level semantics like send and receive.


        problem



        trait IModem extends IConnection with IDataChannel{}


        You wouldn't do that, as this IModem violates SRP. Your ModemImpl class would just consume those traits.




        So he decides to break it up so that the Modem Implementation relies on a Connection interface and Data channel Interface. However then when Modem implements Connection and Data Channel Interfaces, his class Modem must still implement the methods individually!




        Traits / Interfaces are what other parts of the software consume, so the interfaces are okay wrt. SRP. The implementation is up you, and you hide those details from the other parts of the system.
        SRP does not do away with coupling, and you need to resolve that in the implementation, but conceptually the traits are clean.






        share|improve this answer













        SRP is about reason for change, and people.




        1. The network guy is responsible for going in and writing the connection related code, and provide you basics for how to send packets (e.g. read4bytes and write4bytes)

        2. The application logic guy is responsible for going in and providing higher-level semantics like send and receive.


        problem



        trait IModem extends IConnection with IDataChannel{}


        You wouldn't do that, as this IModem violates SRP. Your ModemImpl class would just consume those traits.




        So he decides to break it up so that the Modem Implementation relies on a Connection interface and Data channel Interface. However then when Modem implements Connection and Data Channel Interfaces, his class Modem must still implement the methods individually!




        Traits / Interfaces are what other parts of the software consume, so the interfaces are okay wrt. SRP. The implementation is up you, and you hide those details from the other parts of the system.
        SRP does not do away with coupling, and you need to resolve that in the implementation, but conceptually the traits are clean.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered 13 hours ago









        dnozaydnozay

        1595




        1595






























            draft saved

            draft discarded




















































            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.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fsoftwareengineering.stackexchange.com%2fquestions%2f387966%2fconfusion-on-single-responsibility-principle-srp-with-modem-example%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

            As a Security Precaution, the user account has been locked The Next CEO of Stack OverflowMS...

            Список ссавців Італії Природоохоронні статуси | Список |...

            Українські прізвища Зміст Історичні відомості |...