6 ms·
I spend a lot of time thinking about these sorts of topics (actually, I just taught a 4 hour session yesterday that used most of the terms in this article), wor
by adamkl 6y ago
I spend a lot of time thinking about these sorts of topics (actually, I just taught a 4 hour session yesterday that used most of the terms in this article), working with newer, less experienced developers, and trying to figure how to distill the essence of "architecture" down to something simple that everyone can start with.
This is what I’ve started telling people:
Use mostly functions, try to make most of them pure.
I think that can get people (even new devs) 80% of the benefits (testability, composability, loose coupling, and the ability to reason about code) of more complicated, prescriptive architectures (Hexagonal, Onion, Ports & Adapters, Clean, etc) with a minimal amount of ramp up.
Of course, this isn't the solution to every problem (it obviously depends on the domain you are working in, for me its webDev and backends), but I think maybe its a good way for people to start.
Edit: Here is a great talk demonstrating that by following a simple functional approach, your code can naturally fall into a “pit of success”: https://youtu.be/US8QG9I1XW0 https://youtu.be/US8QG9I1XW0
- jhardy54 6y ago> Use mostly functions, try to make most of them pure. This reminds me of: > Eat food, not too much, mostly plants > > -- Michael Pollan My new mantra: Write software, not too much, mostly functions.
- AnimalMuppet 6y ago"Not too much" is interesting. If I understand you correctly, you can write "too much software". I can think of at least three ways - bad architecture, too little abstraction forcing repetition, and just bad writing. Did you have something else in mind here?
- adamkl 6y agoI believe “Not too much” is a simple reminder that more code equals more bugs. So, try to write less code whenever possible.
- asimpletune 6y agoI think more likely is to actually have too much abstraction.
- AnimalMuppet 6y agoEither can be a problem. Too much abstraction and you're writing FooFactoryFactoryFactory. Too little, and you're repeating yourself. Somewhere between the extremes is a sweet spot. The problem is that, as the project continues over time, the sweet spot moves...
- RangerScience 6y agoNah. It's always about 4 layers. Hardware/services/data stores/etc, wrappers/models/components, business logic / application, ops/deploy. If you nest your models/components deep enough that they're forming new abstraction layers, you're nesting them too deep. Backup and use mixin-style stuff instead. If your business logic or application are nesting pretty much at all, then you haven't succeeded at making good choices in your models/components.
- asimpletune 6y agoAgreed, and I’d add that code duplication is hardly a big problem. It’s kind of like if I legitimately see a lot of code duplication, then I have enough data points to do the right thing. On the other hand, abstracting early to avoid code duplication is worse.
- RangerScience 6y agoHmm... I think you might be right. Or, at least, that the problem that is and the problems that go with code duplication are easier to resolve than those that show up with shit abstraction. Maybe... Duplication is a code smell, but shit abstraction is a code problem...?
- rsanheim 6y agoI think "Too much software" comes from product and engineers not being willing to say 'no' to feature requests and product bloat, rather than any sort of strictly technical thing. If your product or tool lacks a clear focus and goal, then the code base will reflect that, and will grow and sprawl endlessly.
- bluGill 6y agoI have been net negative lines of code for the month more than once, while productively adding more features and fixing bugs. There is a lot of code out there that need not exist at all.
- klenwell 6y agoNIH or Resume-Driven Development might be another way. From personal experience, I worked with a team years ago where product owners wanted a datetime picker or parser for an app we had built. Senior dev on team decided it would be cool if it included some lite NLP. When product owners heard from him how easy it would be to add, they were on board. He started with a popular existing Python library. But there was a bug with one corner case that was causing problems. So he took the initiative to spend a few extra days on the story to write his own simple NLP date parser. A couple months later, early on Jan 1st, the new feature wished our ops team Happy New Year by taking down our application. I happened to open an issue for the library's bug on Github after learning about it from the other dev. The owner there promptly responded to share a simple workaround for the issue. But by that time we already had too much software on our hands.
- RangerScience 6y agoI would definitely add "too many features". You can do a really good job building something way too large and you've built too much.
- wadkar 6y agoIn a similar vein, I look forward to adding less lines and removing more in my git commits.
- lmilcin 6y agoI am sort of in a similar situation meaning, I try to transfer to the team what I have learned over decades of development and now it is intuitive for me. I think the most important principle is to "keep it simple". I mean, even if you have absolutely no idea how to put things together, just trying to limit LoC and trying to not do anything fancy is probably going to get you into better spot than any other principle alone. "Keep it simple" has the advantage that it in itself is quite simple. Even if you are just starting you can pretty much tell simple from complicated code. You might not yet be able to make your code simple but if you honestly try you are also equipped to judge your results in an intuitive way which is essential to improve. The only way to improve is to be dissatisfied with your product and the only way to do that is to be able to judge it at least in some way. Usually the way you are dissatisfied is going to shape the direction in which you are likely to improve. That is not the case with other principles, which oftentimes are easy to state and sometimes easy to show on a small scale of a very simple example, but give not much guidance on how to use and combine with other principles on a large scale. For example, principle of using patterns to structure your code (we are talking GoF, PoEAA, etc.) which is frequently taught to people is right in itself (ie. whenever possible we may want to use established ideas on how to solve particular problems) but is frequently misrepresented by adepts who try to overload the application with constructs which even if correctly implemented, might have been replaced by a simpler construct. It frequently requires a lot of experience and good judgment to tell which pattern could be used in particular situation and it absolutely gives you no hint of how much is enough giving impression to novice developers that the more patterns you cram the better developer you are. I also think that if you put "keep it simple" as your main principle, in your search on how to "keep things simple" you are probably going to discover other principles and also understand why, in the process. I have many times seen codebase that has been thoroughly obfuscated by "pattern wannabees". I have also seen codebases made by teams that had very little knowledge of programming (like barely being able to program their way out of paper bag). Of the two, I very much prefer code written by people who don't try to be too fancy. It takes twice as intelligent person to read the code so if some intelligent people try to be smart with their code but are misguided, it freqeuntly results in a codebase that is very hard to untangle. With a code that is naively written, the problems tend to be simpler both to understand and to resolve. Couple of months ago I had a discussion with a dev who was supposed to implement circuit breaker on one of the services (dunno why on one service only) and the resulting was a dozen pages of Java code that was chock full of callbacks, suppliers, optionals and what not. But something did not sit right with me because I could not for the life of me see what the code actually is doing and given the problem it was supposed to do I did not expect so much code. So I sat down and over two hours I have simplified entire dozen pages to a single try / catch with an if in it.
- Fire-Dragon-DoL 6y agoInteresting. It aligns with my line of thinking. With OOP, the most interesting objects are always stateless and the only "state" present is used for dependency injection. It seems like in the industry the cost of having state has always been overlooked. Funny enough, in frontend software this pain surfaced a lot, but in the backend it keeps being unnoticed, at least in the world I live in (Ruby, Javascript).