7 ms·
I would not follow any of this book anymore. Abstractions lead to coupling and complexity. So many outdated principles I can’t enumerate them all.
by ChicagoDave 3y ago
I would not follow any of this book anymore.
Abstractions lead to coupling and complexity.
So many outdated principles I can’t enumerate them all.
- Hypergraphe 3y agoIn fact, that could be useful to ellaborate a bit.
- ChicagoDave 3y agoPrimarily this book completely ignores communication with subject matter experts and the business. This is fundamentally more important than any language, process, or platform.
- deleted 3y ago[deleted]
- Ligma123 3y ago>Primarily this book completely ignores communication with subject matter experts and the business. Probably because this isn't an advanced book on Software Engineering, but an introductory book to programming.
- sussmannbaka 3y agoThis is wrong, it’s a core part of the design process as described in the book.
- geokon 3y agoI also found the outside-in way they solve problems (using stubs for inner calls) very bizarre. I could be wrong.. But I don't think anyone codes like that
- regularfry 3y ago"Using stubs for inner calls" is literally a top-level description of London-style TDD.
- kmac_ 3y agoOnly Detroid school! Mocks should be banned (unless they mock external system). London-style tests cargo culting is one of the reasons why OOP got bad name.
- regularfry 3y agoLeaving mocks in place once you're done should be banned, I agree with that. I think they're fine as an exploratory tool to figure out what an interface should look like.
- kmac_ 3y agoMocks means that there's a side effect neccessary (and that's quite rare) so the use is justified in such a case. If a stub is needed, then mostly it's gone when the code is refactored to a more functional style. Unfortunately, most OOP developers bury side effects at the bottom of the stack, instead of passing an object that describes the side effect to happen (which it's executed at the shallow and simple application layer). Said result object can be tested as any other function result and no mocking is required.
- segfaltnh 3y agoI love this sort of approach for one-shot externalities but what about when your entire program is a conversation with external components? My current project coordinates software repositories and services within AWS and I find myself using a lot of mocks in testing. I can return a tree of lambdas but then I have to resolve them against something and that's just replacing mocks with lambdas, really. Not sure it's any better in practice.
- atoav 3y ago> Abstractions lead to coupling and complexity. So you write everything in assembly and rewrite it completely for every new target system? Seems a bit tedious to me /s Just kidding abstraction serves it's function and the right amount of abstraction makes things better, more transferable, easier to maintain etc. I think for example about hardware abstraction layers (HAL) in embedded programming. But abstraction in programming is never a value in itself and its use needs to be weighed carefully. I think it is best to teach people to stick to the data and to think about transformations between said data. If they don't know abstraction (aka beginner's spaghetti code) it is worth telling them about it.
- SanderNL 3y agoI think ORMs fit that bill. For some reason they were (are?) incredibly popular, but I don't think they stood the test of time. In the case of SQL, it's already an abstraction. No need for elaborate wizardry to hide the fact you're about to JOIN a table or two. Just write the damn join. Every. Single. Project. I see using ORMs resulted in a baseline 20+ queries being fired under the hood for every screen. They are not bad in and of themselves, I think that they attract or are amenable to a certain type of development mindset that ends in bad results. I have a very hard time thinking of any kind of object oriented abstraction that turned out to be a very good idea.
- ChicagoDave 3y agoRelational databases are an operational anti-pattern. ORMs have proven that.
- barrkel 3y agoRelational databases have shown, and will continue to show more longevity than object orientation. Facts and the relationships between facts is a deeper foundational principle than the concept mashup of modularity, hidden [mutable] state, dynamic dispatch and interface subtyping that object orientation is formed from. Databases are more long-lived than applications, so applications tend towards adapting to the form of the data rather than the other way around.
- stinos 3y agoAbstractions lead to coupling and complexity. The wrong abstractions can lead to coupling and complexity. The right ones on the other hand are all about reducing coupling and complexity.
- ChicagoDave 3y agoWe have a history of abstraction-based code that’s turned applications into frozen balls of mud. We have so many tools to help write good code that the short-term savings of shared libraries is superseded by having distinct codebases that can be modified without those dependency concerns. Same is true for finding bugs in many places and easily setting those up for maintenance releases.
- kaba0 3y agoThere is no going around complexity. We are absolutely standing on the shoulders of huge giants; even if you think you don’t have any dependency, behind the scenes you use many decades-old libraries dealing with the complexity of floating point arithmetics and such. Also, Brooks paper is still true, the only real, significant productivity boost is reusing existing code. Even if you rewrite everything from scratch, you will still have to carry the exact same amount of essential complexity. Managing complexity is pretty much the most important part of CS.
- DanielHB 3y agoopen any network communications protocol RFC or any CPU design architecture or operating systems memory tables or operating systems filesystems with journaling or hardware I/O it is crazy that society hasn't collapsed yet
- DanielHB 3y agoSome engineer from Netflix once said something along the lines: "Microservices, not too many, mostly alongside team boundaries". Meaning most microservices should be wholly owned by a team and a team should ideally own only one microservice (but exceptions are allowed under special circumstances) Like microservices, I feel code abstractions should be thought in a similar way, mostly a thing we use in our team, not company wide In my own team I have to fight very hard to keep dependencies to external code down, the amount of entangling people are willing to put their code through is just crazy. An argument I often put is: "Why should we use lib X from team Y from my company if they don't even feel it is good enough to open source?". Any external code that my team imports into our project should be good enough it could be open sourced (given IP-rights allowing)
- oslac 3y agoHaving read through the old version I cannot recommend that one either.
- ericjmorey 3y agoWould you care to elaborate?
- ericjmorey 3y agoCould you share a few examples of what you consider outdated principles?
- favadi 3y ago> Abstractions lead to coupling and complexity. Without abstractions, we would still programming using punched cards.
- mumblemumble 3y ago> Abstractions lead to coupling and complexity. If you're in the habit of programming in anything other than machine language, I think you'll have to agree that the real story is more nuanced than that. I haven't actually read this book so I'm not prepared to defend it. But I would happily run my mouth and say that the truth is more that abstractions are a double-edged sword. They can be very effective in skilled hands, but they are dangerous in the hands of the untrained. Unfortunately, what makes a good abstraction (IMO it's algebras or GTFO) is not something in which most of us receive sufficient training.
- Joker_vD 3y agoIf an "abstraction" leads to coupling, then it's not an abstraction.
- kqr 3y agoRichard Gabriel coined a word for those things: compressed definitions. When a thing looks like reuse or abstraction because it implicitly pulls in something else in a coupling way, it's really about exploiting shared context in a way that allows the new definition to be much briefer than it otherwise would have been. However, it still relies on full knowledge of the context, so in terms of conceptual load, there's no difference. Just as with other types of compression, the shared context becomes the global coupling across definitions.
- kaba0 3y agoCould you give an example of that?
- kqr 3y agoI have come across a codebase where there was an "Import data from HTTP" functionality that extended the "Import data from file" functionality in such a way that the HTTP calls were grafted onto and around the file operations. This probably made the HTTP class quicker to write, but - Anyone wanting to make changes to the HTTP import functionality needed to also fully understand the file import functionality since basically all of it was used to import from HTTP, and - Many changes to the file import functionality also broke usages of the HTTP import functionality. (Fortunately these breakages were always revealed by automated tests before they made it into master.)
- qumpis 3y agoThis might not be a perspective of a programmer, but the code I've reviewed and tried to understand from academics is always easier to manage when it's not abstracted too deeply. Especially when reading the code is the main reason for trying to understand the underlying idea. Unless you have an extensive (visual?) representation of how the code flows, abstracted code for beginners might be a hindrance towards understanding what's happening at the lowest level while still maintaining the contours of the whole thing. Of course when everyone's on the same page and has similar understanding, this is no longer a concern.
- taeric 3y agoWould be nice to see at least a few of the principles called out. What makes them outdated? And coupling/complexity are a touch on the weasel word space for our domain. They can mean things, sure, but they are often used for the emotion attached more than anything else. Worse, as programs grow, they probably should be coupled heavily. Loser coupling is almost always more complex to maintain and of diminishing returns. Is why the tires on your car can't be used on another vehicle. We probably could engineer the "one true wheel", but it would be done at the expense of capability. Not in pursuit of it.