8 ms·
Why Is Object-Oriented Programming Useful? With a Role-Playing Game Example
- lmm 12y agoI feel like a lot of the problems OOP solves are working around inadequate type systems. If you can make a distinction between Int @@ CharacterHP and Int @@ WeaponDamage such that you simply can't subtract one from the other without going via the appropriate function, then the argument for having private member variables and object methods to mutate them (which is the controversial part of OOP, I think everyone agrees with having data structures and some form of polymorphism) goes away, doesn't it?
- humanrebar 12y agoRight, but you should also include notions of immutability and ownership in your explanation. OOP is partly about managing complexity. If the mutation and sharing in your data is managed by the type system, private data is much less important. That being said, OOP is also about managing interfaces between the different parts of your code. Adding a little more type info to your variables doesn't help you if you need to drastically change how a variable is accessed and mutated (memoized, retrieved from a service, persistence layer, etc.) while avoiding a running a giant find/replace across your entire project.
- lmm 12y ago> Adding a little more type info to your variables doesn't help you if you need to drastically change how a variable is accessed and mutated (memoized, retrieved from a service, persistence layer, etc.) while avoiding a running a giant find/replace across your entire project. I feel like if you have a generic "context"-like notion then you can have a lot of this pass directly through. E.g. I recently changed where a Scala report gets most of its data, making it use an (async) web service rather than a database call, and I only really had to change the "top and bottom" - all the intermediate code handles any kind of context as a generic "F[_]", sometimes requiring particular typeclasses (Applicative, Comonad) depending on what it does with it.
- woah 12y agoSince this is aimed at new developers, I would encourage anyone who falls into that category and is reading this to also look at alternate programming methodologies. The key component of OOP is the mixture of code and data into "objects". This can be very useful for physical simulations such as games, etc., since the real physical world is actually made of objects. However, many feel that applying OOP to software that is not for physical simulation has led to a huge amount of wasted effort over the previous decades. The problem is with code reuse. The only real form of code reuse that OOP addresses is direct object inheritance. If you want to reuse a piece of code, the way to do it is to make an object that is a 'subclass' of an object that has the code that you want to use. The actual relationship of these objects is often not that simple, and people often create baroque inheritance trees to force their logic into the OOP pattern. Worse, is that OOP is built into many languages, which leaves you no choice. An alternate pattern is functional programming, where a program is modeled as a series of data transformations, instead of a universe of interacting 'objects'. To write the code, one looks at what data will go into the software, and what data will need to come out. After all, if the right data is coming out of the program at the right times, it works. Instead of breaking code into objects, you write functions that process the data correctly, and assemble them into larger structures, often resembling pipelines. The nice thing is that a lot of these functions are very reusable across projects and within a project. Avoiding the messy mixture of code and data allows you to identify the common patterns in your code, and refactor and reuse more easily. EDIT: Here are a couple of libraries which have really facilitated functional programming for me in node.js - http://ramda.github.io/ramdocs/docs/ http://ramda.github.io/ramdocs/docs/ - https://github.com/dominictarr/pull-stream https://github.com/dominictarr/pull-stream
- evanspa 12y agoTo build on what you're saying, one could argue that functional programming also is a way to model the world; that is, if you're model of the world is that of a series of snapshots of instants, as opposed to mutable stateful objects. Abelson from the SICP lectures argues this in this lecture: http://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-001-structure-and-interpretation-of-computer-programs-spring-2005/video-lectures/6a-streams-part-1/ http://ocw.mit.edu/courses/electrical-engineering-and-comput...
- Tehnix 12y agoThe author should really consider some proper way of displaying code, instead of a textbox. Also, for some reason, on safari the code is in one line, while on chrome it's in multiple lines, like it should be.
- DEinspanjer 12y agoThe highest priority rule is the in-line which specifies white-space: nowrap; which doesn't preserve multiple whitespace. Firefox and Safari does what he says. I'm not quite sure why Chrome is displaying it differently..
- rezistik 12y agoI was talking to a friend who started doing web development transitioning from game development. I came from a JavaScript background heavily based around Lodash and 'nearly' functional paradigm. I was discussing my interest in more purely functional languages like Haskell and Clojure. Kind of rattled of my distaste for OO programming and how it just doesn't make sense to me, it seems like a lot of fluff and boiler plate when our most common use case is moving data from a form to a data store. He made a lot of good points that with game development OO makes a ton of sense. I kind of agree. OO works amazingly with game development but with application development I'm really finding the functional paradigm so much more logical.
- vespakoen 12y agoFunctional programming in JS is possible, ramda / wu (others?) make it very easy to get started, of course it is not as great as with functional programming languages, but still, it allows you to do pretty cool stuff, it's like lodash but with the callback moved to the first argument, turning something like this: var isMultilanguage = function(field) { return field.multilanguage === true; }; var isNotMultilanguage = function(field) { return field.multilanguage !== true; }; var getMultilanguageFields = function (fields) { return _.filter(fields, isMultilanguage); }; var getNonMultilanguageFields = function (fields) { return _.filter(fields, isNotMultilanguage); }; into this var isMultilanguage = R.where({multilanguage: true}); var isNotMultilanguage = R.not(isMultilanguage); var getMultilanguageFields = R.filter(isMultilanguage); var getNonMultilanguageFields = R.filter(isNotMultilanguage); https://github.com/ramda/ramda https://github.com/ramda/ramda https://github.com/fitzgen/wu.js https://github.com/fitzgen/wu.js
- krebby 12y agoYou also have those in Underscore / Lo-Dash: _.filter(fields, {multilanguage: true}) _.where(fields, {multilanguage: false})
- jdd 12y agoThe current stable version of Lo-Dash supports _.curry. In 3.0 Lo-Dash will add support _.rearg, _.ary, & _.curryRight. Using a combo of them you can easily create auto-curried functions. var where = _.curry(_.rearg(_.where,1,0)); var isMultilang = where({multilanguage: true});
- jameskilton 12y agoUnfortunately for the OP, when it comes to game development, it's widely understood that OOP only ends up painting the developer in a corner eventually. Yes using Objects, Inheritance, and Polymorphism works well for a long time, but the more objects and deeper the inheritance tree grows, the more inflexible the system becomes. You also run into problems with reality. When the code hot path calls across multiple object types and a invokes a bunch of polymorphism every frame, the code is going to be slow and there's no obvious bottleneck. The code is slow because the CPU is constantly waiting for its cpu and data cache to catch up. Game development today is moving quickly towards components, composition over inheritance, and Data Driven Design techniques. Check out the myriad of posts on Entity/Component systems that have sprung up over the past 10 years. It can be harder to grasp at first but has huge wins over the traditional OOP model.
- adnzzzzZ 12y agoThis "huge win" depends heavily on what you're making. If you're making simple games where performance is not that much of a problem (like most indie games) then moving to entity/component systems makes no sense and tends to make everything more complex than it needs to be. A good middle ground in those cases is to just stick with normal OOP with shallow trees (no more than 2-3 levels) and favor simpler types of composition like mixins whenever needed.
- rrradical 12y agoAs someone who has made indie games with both traditional OOP and component systems-- I vastly prefer component systems. I disagree that they make things more complex. I found that they made things much simpler. Although, it does require learning about and possibly developing a component system. If you are talking about very very simple games, it would perhaps not be worth the effort, but at that level basically any architecture will work.
- seanmcdirmid 12y agoEntity component systems are just another form of OO that rely heavily on ontology and named object instances. Unless you mean OOP must be Java, then of course, it's not.
- cportela 12y ago<unrelated> Al, could you made the fonts on your site bigger, make styling via css not on each element and introduce some nicer Google fonts? Also, if you could use `<code>` and `<pre>` tags that'd be a solution where you could ignore the rest of what I said. Reason being that I save these articles for later to show people who I try to teach programming and my attempts to save this page were unsuccessful.
- Kiro 12y agoSo yeah, in games OOP makes perfect sense but I have a hard time applying it in other code. I mostly build applications that make some API calls, save the result to a database etc. What is an object in that context? The same goes for the classical Car and Animal OOP examples. Yeah, that makes sense but how often do you have such entities in a real code base?
- Puts 12y agoThe problem with object-oriented programing is that it makes objects the most important abstraction, which it's not. I'd say states are the most important abstraction of a program. I think I've grown so much as a programmer since I started thinking more about states and less about objects.
- mrev19 12y agoWow I haven't seen that character record sheet in 30 years. So mewhere I have a 10th level elf fighter with 18's for every trait (17 for charisma just to break it up.) Translation for non-D&Ders - I was so nerdy I made my own characters for my own games I was DM for with completely invented characteristics rather than rolling dice for traits like the rules say
- lsiebert 12y agoThe weird thing is, many if not all of the arguments apply to C with structures, unions, and function pointers... and I don't know that consider that properly object oriented.
- bsder 12y agoThe problem is that object oriented programming is a premature optimization that has outlived it's usefulness. Object oriented programming enshrines mutation. Mutation is a good optimization when memory is expensive and fast relative to computation. Memory is now cheap and slow relative to computation. You can execute 100's to 1000's of operations in the time it takes to chase a pointer that is not cached.
- Gurkenmaster 12y agoIf OOP encourages mutation can you explain to me why the String class in java is immutable?
- bsder 12y agoIt's a holdover from when Java was supposed to be a language for small machines. However, if you're being snide, let me retort "So why does everybody in Java immediately recommend that you use the StringBuilder class instead of String?"