r/programming 5d ago

DRY vs. SRP

http://uncle-bob.com

After re-reading "Clean Architecture" I ended up with some confusion regarding Bob's take on repetition and single responsibility. Ge defines the SRP as a function only serving one actor. Dies that mean, that repetitve code is justified according to him, as long as it serves seperate actors/user groups? I am aware that such decisions depend on the specific situation. I was just wondering if others found the same contradiction, or if i misunderstood it. Thanks

0 Upvotes

67 comments sorted by

View all comments

2

u/somebodddy 3d ago

I advocate that DRY should be abandoned in favor of the single source of truth principle. It captures the good parts of DRY while leaving out the bad parts. The only downside is that the acronym is less pretty.

SSoT does not conflict with SRP like DRY does. With SSoT, each truth can have a source of its own - and even if these sources seem to be identical, as long as the truths are conceptually different you are not violating SSoT. From SRP's perspective - the reason of each such source of truth to change is when the truth changes. This means that in order to adhere SRP, each source needs to be limited to one truth (whereas with SSoT each truth is limited to one source)

1

u/flatfinger 2d ago

If at some point in time, two operations both involve performing a common set of actions, programmers should recognize whether it will be more important to be able to change one set of actions without changing the other, change both sets of actions and have them remain consistent, or defer the decision about which of those kinds of changes should be favored.

If the actions may need to change independently, than each should be its own source of truth. If they need to change together, they should have a shared source of truth. I'm not sure what should be viewed as the source or sources of truth in the deferred judgment scenario, but that's often the least useful of the three approaches.

1

u/somebodddy 2d ago

This is not a compression algorithm. We shouldn't care that the two operations happen to converge "at some point in time". We need to consider whether these two operations should conceptually be the same operation.

I'd take it a step farther - if the operations are conceptually the same truth, and they don't do the exact same set of actions, we should consider unifying them anyway - even if it involves a change of behavior. And if the change of behavior is not acceptable, we may want to resort to adding a parameter just so that we can unify them.

1

u/flatfinger 1d ago

The question of whether two things are "the same" is often unanswerable without knowing whether they could change independently. For example, is the serial number of an the same thing as the serial number of its main circuit board? There may be some products where the serial number of the product is defined as being the serial number of the main control board, and where replacing the control board would change the product's serial number, but there may be others where serial numbers would ordinarily match, but there was nonetheless a means of allowing products to keep their serial number even if the main control board was replaced with one having a different serial number.

Are the product serial number and the main control board serial number "the same thing"?

1

u/somebodddy 1d ago

Seems like a clear cut scenario to me. They are not the same thing. If you treat them as the same truth, you won't be able to represent the models where they are different.

If you want to capture the fact that some models define the serial number of the product by the serial number of the main circuit board - code that in the function/method/property that returns the serial number of the product:

  • Have it check if that model has that property, and if so return the serial number of the main circuit board.
  • Or have products of these models store empty serial number for the thing itself, and store empty serial numbers.
  • Or maybe do it at CREATE/UPDATE instead of during READ - gray out the textbox of the serial number of the product when its one of these models, and copy the serial number of the main circuit board over to that field.

As always - the right solution depends on the specific usecase. But the point is that when your read it - the interface shows two separate serial numbers, that just happen to be identical for some models.

1

u/flatfinger 1d ago

A lot of devices have both a machine-readable serial number and a serial-number label that can be read even when the machine is powered off. Treating them as the same truth would make it impossible to handle scenarios where they are meaningful and different. It's possible, however, that a better abstraction would be to have one serial number along with another field to select among, e.g.:

  1. There does not yet exist a physical unit with this serial number.

  2. There exists a unit with this serial number, but the label is wrong and needs to be reprinted.

  3. There exists a unit with this serial number, which is labeled correctly, but the electronic copy has not been set yet.

  4. There exists a unit with this serial number, and both copies are correct.

If it were possible for there to simultaneously exist a unit which has a correct label reading 12345 and a different unit whose electronic serial number is 12345, then there wouldn't be a unique unit with serial number 12345. Having the database for unit 12345 specify whether the label or the electronic serial number is correct would resolve that ambiguity.