[HN Gopher] Software Design Principles I Learned the Hard Way
___________________________________________________________________
Software Design Principles I Learned the Hard Way
Author : thunderbong
Score : 30 points
Date : 2024-04-25 09:36 UTC (3 days ago)
(HTM) web link (read.engineerscodex.com)
(TXT) w3m dump (read.engineerscodex.com)
| Waterluvian wrote:
| > Far too many times I've seen code that looks mostly the same
| try to get abstracted out into a "re-usable" class.
|
| I've had a hard time explaining this but I know it when I see it.
| Two things that are the same shape but aren't really semantically
| related. So if you try to share code, your abstraction breaks the
| moment they start to inevitably express how they're not related.
| Maxatar wrote:
| Sure, if the abstraction is very broad like a class, but I find
| I have a lot of success factoring out code that mostly looks
| the same into a plain function.
| foobarkey wrote:
| +1000 to PRY, if something needs to possibly evolve separately
| dont force it into some shared abstraction, I think DRY probably
| causes the most bad code but we still keep doing it.
|
| Agree with mocks also, currently not even using them, just go
| with integration tests and set db back to known state between
| every test run, oh and wiremock for rest
| monero-xmr wrote:
| The hill I'll die on is to avoid classes, everywhere. You don't
| need classes. Just use functions and structs (or plain objects,
| etc.). OOP was a terrible mistake and mixing state with logic was
| a major catastrophe that poisoned a few generations of engineers.
| Burn the Gang of Four design patterns and scatter the ashes into
| the ocean.
| foobarkey wrote:
| I will join you on that hill, just make a pureish
| function/method that does the thing its supposed to do and job
| done. Although in 10% of cases OOP and inheritance is useful
| mvdtnz wrote:
| From 15 years industry experience my biggest takeaway is to
| ignore advice from anyone who claims their point of view
| applies "everywhere".
| monero-xmr wrote:
| Well I have over 20 years experience so maybe you need 5 more
| years or so
| klysm wrote:
| I generally agree with you. The only time I find classes make
| sense is when you need a stateful imperative handle. Those
| cases are rare.
| mvdtnz wrote:
| Absolutely agree with 1 ("Maintain one source of truth"), not
| just in a service but in an architecture. I am dealing with a
| microservice architecture where decisions have been made to store
| the same state across different services. Needless to say this is
| massively challenging to keep in sync and requires a ton of work
| keeping the production systems consistent. Not to mention the
| difficulty of setting up proper test environments where any given
| data store might be reset or refreshed at any given moment,
| causing all kinds of havoc and causing people to lose trust in
| the test environments.
|
| For number 2, (please repeat yourself), the truth is in the
| middle. Don't repeat yourself when the proper abstractions
| present themselves, and always be on the lookout for a good
| abstraction. But don't force an abstraction where it's not
| appropriate. Where to draw the line is the hard part and in my
| opinion comes from experience and intuition. If in doubt, repeat
| yourself.
|
| Number 3 (overused mocks) I find myself swimming against the tide
| of popular opinion. I think mocks are very valuable for unit
| testing. This doesn't mean you don't write your integration tests
| without the mocks, but I still think there's a ton of value in
| being able to quickly write a large number of fast unit tests
| that say "when this component does this, I expect the system
| under test to do that". As for leaking implementation details, I
| don't think it's such a big deal at the unit testing level. The
| details need to be tested somewhere. I appreciate this is an
| increasingly unpopular viewpoint but it has served me well.
|
| For number 4 (minimize mutable state) this is software
| engineering 101, but always bears repeating.
| xwowsersx wrote:
| What I've noticed over the years is that software engineers tend
| to sometimes mistakenly believe that when they are, for example,
| modeling some domain that they are involved in some sort of
| Aristotelian categorization exercise wherein they are trying to
| capture the true essence of some pure Platonic form. In reality,
| whenever anything comes under the umbrella of software, we are
| doing it not because we are interested in some ontological sense
| of the thing under consideration, but because it has some
| usefulness for a particular line of business. This I think is the
| key thing. There are unifications and abstractions that make
| sense in a pure theoretical sense, but that serve no purpose when
| it comes to software that is meant to serve some practical end.
___________________________________________________________________
(page generated 2024-04-28 23:00 UTC)