5 ms·
The same is so true for programming, in particular OOP. In my experience, code is much easier to change when a loosely coupled set of interfaces is built as opp
by sharpercoder 8y ago
The same is so true for programming, in particular OOP. In my experience, code is much easier to change when a loosely coupled set of interfaces is built as opposed to an hierarchy of classes.
- tabtab 8y agoIndeed. This is also why I think OOP is missing something to scale better in terms of flexibility and domain size. The ideal code structure for a particular need is rather arbitrary. OOP "prefers" things in a hierarchy, both in terms of inheritance, and in terms of an object being less powerful than a class (in most languages). You can force or use OOP outside of these, but it's unnatural in my opinion. For example, why is it not easy to add an "onClick" event handler method to a particular button in a Java GUI? One has to use lambdas instead. Attempts to reorg the GUI engine to remedy such create side-effects. Java's OOP model is simply not powerful enough to do GUI's naturally. Conway's Law seems to apply to domain structures as well. Fit matters. Something like Lisp allows one to create behavior-containing "structures" that are customized to a domain or need, but can get too confusing. Lisp can easily get too hard to read and follow for most mortals, and is why it never became mainstream despite being around for 60-ish years. We need something in between traditional OOP and "full meta".
- avinium 8y agoI think most ML-derived languages strike the right balance - functional languages that incorporate enough OOP principles to get things done in the real world. I increasingly advocate F#, and many people recommend Elixir for these purposes too (though I'm not familiar with it myself).
- tabtab 8y agoI've yet to see useful things F# can do in my domain that couldn't be easily done other ways. Most of the examples are in esoteric domains or "lab toys". I'm not saying it's not useful, it's just that it hasn't been presented in a way clearly useable to my domain, which is "typical" business applications. For example, much of the issues related multi-tasking and parallelism are typically farmed off to the RDBMS and A.C.I.D. transaction handling. It may be a boring domain to many, but it's important for commerce.
- twblalock 8y agoYou can do OOP without inheritance. I do it all the time, including in Java. It works extremely well alongside dependency injection. You still get all of the other parts of OOP, like encapsulation and polymorphism. The only real trick is to use delegation patterns instead of inheritance, i.e. dispatch requests to class members rather than super/subclasses. It doesn't feel awkward or unnatural.
- tabtab 8y agoIt does feel awkward to me. I tend to view it more like RDBMS design and queries where the structures fit the domain and one can query for subsets or dispatching using something as flexible and simple as SQL (relatively speaking). Then you could easily answer: A) Show me all the GUI event handling code for all buttons. B) Show me all the event handling code for Form X. C) Show me all the event handling code for all buttons within forms having at least one drop-down list. Similar goes for executing code (running business logic), not just code inspection. Then one doesn't have to crawl object graphs as often. Early databases did graph crawling, but then Dr. Codd showed a better way, and graph-DB's mostly withered. I'm waiting for the Dr. Codd of code and behavior dispatching management to come save the day. I'd like to explore using relational modelling for behavior, not just attributes (data). I used to do such in xBase (dBASE, FoxPro, etc.) because of its dynamic nature and ease of editing tables, including code in tables. I thought that direction was the future, it looked bright to me. Then OOP came along and killed the seeming birth of table-oriented programming. (It might seem like a security risk to put code in tables, but the difference between a file system and database are not different enough to say putting them in a database is "bad" while putting them in a file system is "good". I'd like to blur the distinction between a file system and database, but maybe that's a diff topic. Plus, one doesn't necessarily have to put code "in" the tables, just references to it in tables. One just needs a system/convention to track and map each to the other.)
- narag 8y agoFor example, why is it not easy to add an "onClick" event handler method to a particular button in a Java GUI? Lack of pointers. An event reference is a double pointer: to the method and to the object that is "self" or "this" for the execution of the event handler. Since they refused to have pointers in the language, they devised that convoluted solution.
- tabtab 8y agoWhen I try to design an "ideal" GUI system on paper, I start with a relational model. Relational is quite adept at dealing with "pointers" in terms of foreign keys. A given snippet of behavior (such as an event-handler method) can be easily associated with multiple things; something OOP has a hard time with. Thus, we don't have to go back to direct address pointers to solve this issue, but rather learn from relational modelling, as I hinted at in a nearby reply. (One problem with traditional RDBMS and GUI's is that different widgets need a variety of similar and often overlapping attributes {columns}. It's not realistic to have a table dedicated to each widget "type". Thus, I propose using "dynamic relational" instead, in which column existence is optionally situational.)
- brodo 8y agoI think avoiding deep class hirarchies is an accepted best practice nowadays. In academia, people still don’t know it (I left in 2017) but it is accepted by everyone I talk to nowadays. I do not use any implementation inheritance anymore, only interface inhertance.
- zozbot123 8y agoThe problems with implementation inheritance are quite a bit deeper than "ontology is overrated", though - even where ontologies are appropriate, it's still bad! It's "sold" as enabling extensibility and code reuse, but the only feature it adds to good old-fashioned composition is 'open recursion' a.k.a. late binding, which inherently leads to the "fragile base class" problem-- making behavior of base-class implementations dependent on preserving complex and generally unspecified invariants in the derived classes - so it's basically never what you actually want! Full-blown OOP (including implementation inheritance and polymorphism) doesn't work. It's a terrible idea that only ever became popular because we didn't quite grok its implications.