3 ms·
Personally, I've found that heavy application of OO patterns leads to code that is very unclean, in terms of being "simple and direct". First developers apply
by stupidcar 10y ago
Personally, I've found that heavy application of OO patterns leads to code that is very unclean, in terms of being "simple and direct".
First developers apply the single-responsibility principle, and break down previously large but comprehendible classes in thousands of tiny components. While each component is trivial on its own, the truth of how they combine to produce a particular application feature is now hidden within an implicit object graph that cannot be understood by new developers, except through a torturous process of cross-checking and debugging until they have built a fragile mental model of what's going on.
Next developers get embarrassed by all the new-ing up of components they're doing, so they introduce dependency injection. But rather than just injecting those things that have a genuine need for varying implementations, suddenly everything gets to be a service. Abstractions proliferate, factory factories appear, everything is behind an interface (with a single "default" implementation), and navigating the codebase becomes a nightmare.
- noir_lord 10y agoNot convinced it's the application of OO patterns that leads to bad code but bad programmers (at least in the major part). I've seen clean code bases in OO/functional and pure procedural and bad code bases in those as well. I think it's tempting to blame bad code on things like bad languages and bad architectural patterns because they are externalities and can be blamed without mentioning the gorilla in the room, bad programmers write bad code. I'm not clever so I don't write 'clever' code, I actually find it hard to work on code bases where they tried to be clever or do too much in one function/class. Architecture is like salt, a little enhances, a lot ruins. I don't write simple clear code out of any sense of purity or attempt to be 'clean' but because I know that in six months when I open this file it'll be me fixing it and I won't understand what the hell $me-6mths was thinking.
- FranOntanaya 10y ago> Not convinced it's the application of OO patterns that leads to bad code but bad programmers There's one thing I would point at. When non OO code is bad you can usually point at the problem: bugs, performance, security issues, coupling, so on and so forth. OO code can be bad yet contain no debuggable issues. Once it's laid out, noone is going to "fix it" because it's not technically broken. It'll just rot due to lack of maintenance, until there's noone left with a good mental map of it and enough of the non-OO contents are broken enough that it gets replaced all at once.
- jomamaxx 10y agoI tend to agree. Too many classes can create obfuscation and confusion. I generally don't mind some overlapping function so long as my instinct tells me it makes sense. I used to make classes for everything. Often ahead of time. Now I make classes generally only as needed. Also - the title is a little misleading. At the OO level, this is not really even 'code' - it's 'design'. 'Code', I often think of as what's written, i.e. inside the functions etc.. As far as that goes, 'clean' is really important when it's exposed. Anything that is really tightly encapsulated within a function ... well, can be a little grimy so long as it's not so bad. Point being, it's uglyless cannot spread beyond the function. But some things - especially API's - it's really important that they make sense, because they represent the language of the application. I'll take clean, consistent API's with messy 'code' than crap API's with tight code any day. You can always fix the code. APIs ... create dependency problems, and bad ones spread problems.
- cgriswald 10y agoAgree in general. > Anything that is really tightly encapsulated within a function ... well, can be a little grimy so long as it's not so bad. Point being, it's uglyless cannot spread beyond the function. Of course, if you're in the position of having to debug that function, you might curse its griminess. I tend to only write really gnarly functions if I'm trying to heavily optimize them and it is only by virtue of those optimizations that they become grimy. And even then, I tend to do it only for those functions that can easily and quickly be rewritten entirely. (And I also try to write them one optimization at a time so I can always fall back to an older, less optimized one if a bug is introduced.) And, of course, there are always comments to help light the way and warn of dragons.
- jomamaxx 10y agoYes - but my point is, you're 'having to re-write' that function is not an existential problem for the product or company. It's just a shitty piece of work. Any individually poorly written but well encapsulated piece of shit is just a 'bathroom clean' away from being nice. Contrast that with bad design, bad APIs, or other things: they mess up other things. They can even create massive, ugly dependencies, and massively increase complexity, bugs etc. etc.. I've seen build-chains that involved 6 different scripting languages. Because we all had to use it, and almost nobody knew all 6 languages, it f*ed the whole company and caused huge pain.
- Benjammer 10y agoThis seems like more of a case of over-organization, and abstracting things before it becomes necessary (premature optimization etc...). There are ways to implement OO where you only add complexity when it reduces the size of the code base significantly, and things like that. Like, leave your monolith class in place, but then maybe move some boilerplate code into it's own class/function once you've copy-pasted it 2 or 3 times. If you find yourself using a dictionary and doing the same, somewhat-peculiar manipulation on the data structure more than once, maybe create a dictionary subclass. Wait until you see the obvious "bad code patterns" emerging and then use OO to fix them, don't just go ham and start arbitrarily "applying principles" until you get to Factory<factory> world.
- paulddraper 10y agoVery true. There's some law of software engineering...can't remember the name. It basically says that complexity can only be pushed around, not destroyed. If you make every class simple, the composition of classes will be complex.