Hacker News new | past | comments | ask | show | jobs | submit login

This is so hard in practice.

I just had a junior dev rewrite some of my code so that: a builder calls a constructor which instantiates a builder factory which builds a builder then that second builder creates the object.

This whole system only builds one type of object. He thinks that his solution is better because it’s more extensible.

I can’t make him see why it’s bad.




> This whole system only builds one type of object. He thinks that his solution is better because it’s more extensible.

> I can’t make him see why it’s bad.

Schools teach OOP as though adding new types of objects is the norm—like every type of software construct is actually a GUI widget in disguise and we're going to be adding new interoperable subclasses every other week, so we may as well get the infrastructure set up to make that easy.

In most real world applications, the only type of object that behaves that way is, well, GUI widgets. Nearly every other type of construct in a typical system will have at most one implementation at a time (possibly two during a gradual transition). Factories, builders, and the whole design pattern menagerie aren't particularly useful when for the bulk of a system's life they're all just proxies to a single constructor.

I don't know if there's a good way to teach this out of someone besides just letting them experience it, but that's the insight that he needs—different types of code have different maintenance characteristics, and the tools he's been given were developed for a very specific type of code and don't apply here.


At least where I went to school, the teaching staff in university CS departments seem to be overrun by guys who haven't actually worked in the software industry since the 90s when OOP was the hot new thing. My theory is they were there when they got to build a bunch of new systems with OOP, but didn't have to stick around for the nightmare of trying to maintain those codebases.


Where I live (Tenth largest city in Spain, so not that big) I'm pretty sure I can track misconceptions about OOP to whoever taught that class in the only university that had a CS degree around here some 20 years ago. I've seen like half a dozen teachers saying the same stuff explained in the same way and I'm sure none of them understand OOP at all. Only one was able to explain why getters and setters ought to be used besides saying "it's the standard" and to provide an actual, reasonable use case for it rather than the tired examples of "Yeah OOP is cool because since both cats and dogs eat and have 4 legs you can keep a lot of the code together rather than duplicate it".

Software development is reliant on self-learning, but still, some education can be outright damaging.


Entities in game systems tend to behave like that too when the whole thing is under development - but then (a) arguably a monster chasing you around is just a special GUI widget with extra behaviour and hit points; and (b) when things get really complex it doesn't hurt to switch from OOP to ECS for games.


I don't have a lot of knowledge on ECS, are there any good articles out there that compare it to OOP?


I recommend reading this book on Data Oriented Design[0] since the underlying reason ECS has been widely adopted is because, written correctly, an ECS system can take full advantage of modern hardware. Most ECS vs OOP blogs come at it from a perspective that I personally find flawed. OOP has the tendency to have objects layed out poorly in memory which prevent programmers from utilizing SIMD instructions[1].

[0] https://www.dataorienteddesign.com/dodbook/

[1] For instance, objects in OOP are typically bundled with other data related to the object. As an example, in OOP a Door object could have float X,Y,Z coordinates, an enum for type of door it is, a bool for opened or close etc. This leads to inefficiencies in cpu cache usage when you are iterating through a list of doors and not using every field of the door object.

See this GDC talk for why this matters in the gaming world: https://www.gdcvault.com/play/1022248/SIMD-at-Insomniac-Game...


This tutorial: http://web.archive.org/web/20120314005352/https://www.richar... although now defunct, makes a good start. Around halfway through there's a heading "Abandoning good object-oriented practice" which gets to the point you're asking about.


Anything that argues composition versus inheritance.


We came up with a rule “no single use abstractions” so any abstraction with a single caller gets absorbed by its caller. We eventually had to say except across MVC boundaries (the project is MVC organized) or else we got some weird code organizations (controllers consume everything). It works pretty well though, in some cases we have some long methods, but really killed the premature abstraction “this will be useful in the future” discussions that eat a lot of time and energy. I think having a simple rule for everyone makes it easier to follow.


Every abstraction for extensible code implicitly assumes certain kinds of extensions and makes other kinds harder. Make him extend it in one of the harder directions :D


Good idea


Premature generalization is the root of all evil nowadays.


Experience will make him see this.

Experience did the same for me.

It just takes some time.


Not if he does the type of job hopping typical in silicon valley. There are plenty of programmers who only stay at a job ~2 years, and never have to maintain a program over a long period. You could imagine such a person saying 'this worked well at my last job' and just keep introducing that kind of pattern to new companies, eventually with '20 years of experience'.


Of course really it is 6 months of experience repeated 40 times.


Agreed. It's "fun" to start breaking your code down into small bits; more interchangeable "pieces" -- until you have to maintain it for 10 years (or worse yet, explain it to a new junior dev) and the extensibility you envisioned never came to fruition and now it's just a liability spread across 8 source files.


It's hard in practice because the industry values delivering something over everything else. I don't know how many times I've seen decent architectures turn to complete crap because leaders felt obligated to put their stamp on it.


Make him maintain one that someone else wrote.


Or... get them to maintain their own code 14 years in the future. Hard to do in practice, but once you've done it, you get a new perspective.

I got a call from a guy saying "hey, this broke". I had not touched this system in 13 years. I had to re-remember a bunch of stuff. Some of the code was still a joy to work with. The parts that were hard were... obvious, and even then, I remember cutting corners, not documenting stuff, and overcomplicating things "just in case" (which mostly never happened).

There's little amount of someone 'telling' me ahead of time how much difficulty I was leaving for the next person (or even myself). It really seems like the only way to get this experience is with time. That doesn't mean you can't follow some best practices that turn out to be beneficial. But until you've experienced the downsides, you won't really be able to internalize the why regarding something being good or bad.


That or make him try to maintain his own code a year later when it may as well have been written by someone else. This is really the only way to properly understand the problem with making all those abstractions. It all makes sense when you have the whole structure in your head but it's very hard to build that mental model back up later.


Your solution was also extensible, this is proven by the junior dev being able to easily refactor it into an overcomplicated mess.


There’s another heuristic that he broke.

If you can easily read and understand some code, then it’s good code and you should leave it alone.


What I do is make them test everything their code might do. "Oh you built a generic builder builder builder huh? I need at least 80% coverage for anything the builders might build." The code shrinkage you can achieve is remarkable.


Show him this discussion




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: