-3

SRP insists that a class should have only a single a reason to change. Please guide me through the following example.

class Car
{
    drive_forward();
    embark();
    disembark();
    fuel_up();
}

All the methods are business level of abstraction. But driving depends on the quality of the road while fueling depends on gas prizes. And all 4 depend on implementation details. How do we apply the S from SOLID here?

3
  • Since you're making the software, you have to define what a distinct reason for change is (as in, you get to to come up with it) - the idea is to build your classes in a way that supports the most common kinds of changes you face (not all changes!). It's part of domain modeling. Your success there depends on how well you understood what drives changes in your particular case. There's no magic bullet here. Say you decide road quality and gas prices could change for reasons unrelated with how the Car class works. Well, pull those out into their own classes and use dependency injection. 1/2 May 22 at 2:44
  • 1
    "how well you understood" - I don't mean that in some vague academic way, it just means that since you're the one working on the software, you're the one who knows (or can find out) what is it that that you clients/users actually need built, what kinds of issues they deal with in their everyday work, where they need flexibility and where they don't, what drives changes, what kind of changes, etc. That's what's called the problem domain you're working on. Nobody who's not involved in the project can tell you how to model these responsibilities, except in a very general way. 2/2 May 22 at 2:44
  • 4
    I don't think this question can be answered as it is now. You ask how to apply SRP to a model, but you already defined the constraints in terms of a class (although maybe you don't mean that to be as much constraint as it appears?). Also, you say "business level abstractions", but what is the business? Automated cars driving passengers from A to B? ECU software? route planning for mass transit? It seems like you are trying to model every aspect of a car, but no piece of real-world software would do that.
    – Pete
    May 22 at 9:17

1 Answer 1

1

There is no global answer to this, and in particular it depends on what your program is simulating. To take some highly simplified examples:

  • If your Car represents a Formula 1 race car, you probably want to go into great detail as to how drive_forward() is implemented, but don't need to worry so much about the price of fuel.
  • On the other hand, if your Car represents a car in a taxi service, your drive_forward() implementation is going to be a lot simpler than that for the Formula 1 car, but the price of fuel is something you're going to want to model.

This is where the skill of a programmer comes in - it's your job to identify which parts of the business domain which are complex and/or may need to change in the future and ensure that your domain model allows those parts to be testable and modified easily. For the bits which are simple and not likely to change in the future, YAGNI applies and you can just hard-code those assumptions - for example, it's probably a safe assumption that your Formula 1 car has 4 wheels.

2
  • 1
    Let's see if I got this straight. "SRP is make each class represent exactly one thing important to the business venture." In other words, if say gas price is paramount, having the class also do drive_forward() and other stuff is OK. What is prohibited is doing two paramount responsibilties in the same class?
    – Vorac
    May 23 at 18:39
  • 1
    That's probably not a bad rule of thumb to use. May 23 at 19:24

Not the answer you're looking for? Browse other questions tagged or ask your own question.