6 ms·
Great series. He really gets to the major problem with OOP. It's not at all obvious what should be modeled or how and changing things once they're wrong is clos
by mnm1 9y ago
Great series. He really gets to the major problem with OOP. It's not at all obvious what should be modeled or how and changing things once they're wrong is close to impossible. No wonder so few beginners pick it up and do it well. In the last part, what he's describing reminds me of clojure. A language where both data and functions are first class citizens and where functions operating on data is the default paradigm. That's the huge difference I see: in a language oriented around data like clojure, the architecture he describes is almost obvious from the start to experienced programmers and it can be slowly built even if one starts on the wrong path. In OOP languages, there are so many wrong paths and the right path is almost never clear or obvious. Even when the right path is clear, getting there from the current state of the code might be impossible without starting over (think how one would get from an architecture based on his first examples to one based around rules without a rewrite). While the author defends his use of OOP, it's clear imo he's still using the wrong tool for the job. Why use an OOP language that makes data a second class citizen hidden in objects rather than a first class citizen that the language is designed around? As they say, show me your data structures and I will know your architecture. Show me your code/functions and I know nothing.
- cutler 9y agoSecond that for Clojure. OOP is a mental straightjacket. When I started back-end programming I was faced with a fork in the road signposted on one side "Java" and on the other "Perl". I spent a long time with Dietel and Dietel's Java tome but somehow OOP just felt wrong. In Perl you just seemed to get on with it. Data and functions. Yes, you could bless a hash to get your OOP if you really wanted to but it was only later that the community became obsessed with OOP and Moose. So, I travelled down the Perl road and consequently found functional programming, and Clojure in particular, to be natural and easy to learn. Listening to other programmers who followed the traditional OOP path, I get the impression that they will defend OOP even when it's glaring deficiencies are staring them in the face. What is it about OOP? I don't get it. Get rid of it and give yourself a chance to approach problems differently. Bottom-up programming, especially with Clojure and its REPL, make programming a real joy. OOP is Stockholm syndrome masochism.
- jimbokun 9y agoIf you look at modern Java web application code, there’s barely any object orientation to speak of. (Now it’s mostly Annotation Oriented Programming, especially with Spring. Which brings its own difficulties.)
- cutler 9y agoYou know you're in a world of OOP pain, especially with Java, when you have to employ all manner of scaffolding - annotations, dependency injection, presenters, service objects - before you begin the main task of solving your business problem.
- HumanDrivenDev 9y agoTalk is cheap, so are Rich Hickeys dime store musings on OOP. Show us some code, how would you solve it with functions and data?
- pinkythepig 9y agoIn Haskell, this would look something like: data Player = Player (Maybe Weapon) Class data Weapon = Sword | Staff | Dagger data Class = Warrior | Wizard type Error = String mkPlayer :: Maybe Weapon -> Class -> Either Error Player mkPlayer (Just Sword) Warrior = Right (Player (Just Sword) Warrior) mkPlayer (Just Dagger) Warrior = Right (Player (Just Dagger) Warrior) mkPlayer Nothing Warrior = Right (Player Nothing Warrior) mkPlayer (Just Staff) Warrior = Left "A Warrior cannot equip a Staff" mkPlayer (Just Staff) Wizard = Right (Player (Just Staff) Wizard) mkPlayer (Just Dagger) Wizard = Right (Player (Just Dagger) Wizard) mkPlayer Nothing Wizard = Right (Player Nothing Wizard) mkPlayer (Just Sword) Wizard = Left "A Wizard cannot equip a Sword" A player is always a defined class(wizard or warrior), but they may not have a weapon equipped. This solution is a bit wordy, but comes with the benefit that if you ever add a new weapon/class, the compiler will scream at you if you haven't handled the case for it properly. You would only export the mkPlayer function in the library and you could potentially have much fancier error handling, such as building a data structure that contains an 'invalid' player anyways (e.g. `Left (Player (Just Sword) Wizard)`) so you can custom build an error message at the call site ("A $class cannot equip a $weapon") or even completely ignore the error if that is a potential usecase (such as building an armor/weapon preview tool, where you don't care whether they can use the weapon/armor). Modifying it is pretty easy too. Say I wanted to allow for 2handed weapons, plus offhand weapons (shields, orbs, charms, etc.) I could encode that in a data type like: data EquippedWeapon = TwoHanded TwoHandWeapon | OneHanded (Maybe OneHandWeapon) (Maybe Offhand) | Unequipped and swap it into the Player definition: data Player = Player EquippedWeapon Class And now I wouldn't be able to compile until I fixed the mkPlayer function and any other place that uses a Player and is dependent upon the weapon portion of the data structure. e.g. This function wouldn't need to change areYouAWizardHarry :: Player -> Bool areYouAWizardHarry (Player _ Wizard) = True areYouAWizardHarry (Player _ _) = False
- lewisl9029 9y agoThis is exactly my impression after taking a quick glance through these articles as well. If anyone is curious and would like to see a practical demonstration of this data-oriented approach of modelling problems, I highly recommend this talk from Mark Bastian in Clojure/conj 2015: https://www.youtube.com/watch?v=Tb823aqgX_0 https://www.youtube.com/watch?v=Tb823aqgX_0 In it, he contrasts the data-oriented modelling approach with a traditional OOP approach for implementing a board game, and was able to come up with a complete implementation of the game with the former approach that was shorter than even the structural boilerplate for the OOP version. Another related talk that I loved was Chris Granger's 2013 talk on Light Table: https://www.youtube.com/watch?v=V1Eu9vZaDYw https://www.youtube.com/watch?v=V1Eu9vZaDYw Where he walks through his process of building a game in ClojureScript using an Entity-Component-System architecture, which is very well suited to this data oriented modeling approach.