Rant about OO in a project
Dec. 22nd, 2024 12:28 pmOriginally posted on the fediverse. Doing some PESOD.
so i was looking through the codebase of a rather widely-used C++ FOSS project. one that's known for its simplicity and minimalism, in fact!
of the things:
- the button to change the sort mode gets handled with 2 layers of string-based indirection, the first to map events from the UI, the second because the application state object only communicates through a "setProperty" method. there's no hashmap or anything internally, the method directly accesses properties. but i guess string constants are more "dynamic" than
object.setSortMode
- i should note that all of these are user-created objects. they decided to do this.
- the second layer of indirection is through a
#define
constant, btw. because we want our indirection system to be kinda checked by the compiler. - the ui code directly contains the constants to set the sort order. i don't get why the extra layer of indirection is necessary at all.
- every single class that isn't part of an implementation of something has the class/class::Implementation pattern. every single one. including classes with no virtual methods, so what's the point. the class that stores the sort mode is patterned like you would do DI on it, but it's so tightly coupled to the UI that that would be impossible. what's the point.
- this includes other silly things like the main window class!
- there's this somewhat silly pattern where you have a
class Foo
with propertyFoo foo_
and methodinitMyFoo(Foo& foo)
. i don't get why the method doesn't just operate on the class itself, it would be basically impossible for it to be used on anything other thanthis->foo_
.
anyways, im not gonna name the actual software project, because i do think it's good and i dont want to publicly shit on FOSS devs unprompted. i just hate how aggressive the misapplication of patterns that could be useful is.
like, string indirection is handy! DI is handy! there are plenty of cases where "initialize this thing based on the state of this other thing" is necessary! but the overuse of these patterns where it's not necessary and likely never will be leads to an ostensibly simple program being utterly labyrinthine to get a foothold in. this is a simple program, that basically just runs a library and renders a list from it, whose code is written like it will ever do anything more than render that library's data. it's designed for "loose coupling" of things that are just never going to not be directly coupled.
it's not an underperformant application, it's not a memoryhog, it's just written to preempt a fundamental change in design and purpose that has yet to come in the last 2 decades of the software's existence. genuinely, what is the point?