{"id":40,"date":"2009-10-26T11:21:28","date_gmt":"2009-10-25T22:21:28","guid":{"rendered":"http:\/\/www.paradicesoftware.com\/blog\/?p=40"},"modified":"2009-10-30T18:31:19","modified_gmt":"2009-10-30T05:31:19","slug":"object-oriented-programming","status":"publish","type":"post","link":"http:\/\/www.paradicesoftware.com\/blog\/2009\/10\/object-oriented-programming\/","title":{"rendered":"Object-oriented programming"},"content":{"rendered":"<p>Like almost everything else these days, Icefall is designed around object-oriented programming (OOP) principles. Specifically, Icefall uses Classes instead of objects, although the <a title=\"Freepascal: Classes\" href=\"http:\/\/www.freepascal.org\/docs-html\/ref\/refch6.html\" target=\"_blank\">difference<\/a> is not relevant for this discussion.<\/p>\n<p>At any given time, the game will be operating dozens of different classes and hundreds of instances of those classes, with the majority of them representing either individual game objects (an item, a monster, the player) or a piece of the user interface (a button, an animation, etc). As you&#8217;d expect, many of these classes inherit from other classes (e.g. the button class is inherited from the generic UI class) but the question of exactly how much inheritance to use is something that confuses many people &#8211; and if you get it wrong, your code will suffer. So let&#8217;s take a closer look.<\/p>\n<h3>Inheritance vs Composition<\/h3>\n<p>Turning a program&#8217;s logic into a group of classes seems easy (hmm, my game has items, let&#8217;s make a <em>TItem<\/em> class!), but choosing the right combination of classes is harder than it looks. Like everything else, the more complex your application is, the harder and more important these choices will be.<\/p>\n<p>One common choice is to do everything via inheritance. You make some ancestor classes which contain <strong>only<\/strong> the logic that will be common to all descendents, and you create inherited classes to cover all exceptions or additions to that logic. This style is called<em><strong> <\/strong><\/em><strong>inheritance<\/strong> for obvious reasons, and lots of newcomers to OOP start like this. Let&#8217;s create an example that shows this in action:<\/p>\n<p>Icefall needs to know an item&#8217;s worth (in gold) to a shopkeeper to allow the player to buy\/sell it. As items in Icefall can have randomly generated properties, we can&#8217;t define the worth of everything at compile time (and even if we could, there will be hundreds of different items in Icefall. Don&#8217;t specify things you could calculate. I&#8217;ll talk about this another time). So we need a method in the <em>TItem<\/em> class to calculate the item&#8217;s worth for us.<\/p>\n<h3>Inheritance<\/h3>\n<p>The inheritance solution might look like like this:<\/p>\n<blockquote>\n<pre>TItem = class\r\n   function Worth: Integer; virtual;\r\nend;\r\n\r\nfunction TItem.Worth: Integer;\r\nbegin\r\n   result := ILevel * 20; \/\/ ILevel is another property.\r\nend;<\/pre>\n<\/blockquote>\n<p>Nice and easy so far. The item&#8217;s worth is calculated as being 20 times it&#8217;s <em>ILevel<\/em> (item-level). But what happens when we want to make some items (let&#8217;s say weapons) more valuable than others? The inheritance solution is to build on the existing code and do this:<\/p>\n<blockquote>\n<pre>TWeapon = class (TItem)\r\n   function Worth: Integer; override;\r\nend;\r\n\r\nfunction TWeapon.Worth: Integer;\r\nbegin\r\n   result := 100 + ILevel * 50; \/\/ Weapons are worth more\r\nend;<\/pre>\n<\/blockquote>\n<p>We have overridden <em>TItem<\/em>&#8216;s <em>Worth<\/em> function with a new one just for <em>TWeapon<\/em>. We just have to remember that when we&#8217;re creating items, if it&#8217;s a weapon we need to construct a <em>TWeapon<\/em> class instead of a <em>TItem<\/em> class to hold it, and the right <em>Worth<\/em> function will be called automatically.<\/p>\n<h3>Composition<\/h3>\n<p>Meanwhile, another style, often referred to as <strong>composition<\/strong>, says to group similar functionality together, and use members or properties to determine the appropriate behaviour for each instance:<\/p>\n<blockquote>\n<pre>TItemType = (ITEMTYPE_NORMAL,ITEMTYPE_WEAPON);\r\n\r\nTItem = class\r\n   function Worth: Integer;\r\n   property ItemType: TItemType;\r\nend;\r\n\r\nfunction TItem.Worth: Integer;\r\nbegin\r\n   case ItemType of\r\n      ITEMTYPE_WEAPON :\r\n         result := 100 + ILevel * 50;\r\n   else\r\n      result := ILevel * 20;\r\n   end;\r\nend;<\/pre>\n<\/blockquote>\n<p>Already, for our tiny example, the two implementations are looking considerably different. The composited version defines a class property called <em>ItemType<\/em> that stores what type of item this instance represents, and the <em>Worth<\/em> function contains all the functionality for both item types (I used a <em>case<\/em> statement instead of a simple <em>if<\/em>, because I suspect I will end up with more than two item types).<\/p>\n<p>p.s. Icefall, of course, takes much more into account to determine an item&#8217;s worth: it&#8217;s rarity, any enchantments, whether the shopkeeper likes the player, etc etc. But that wasn&#8217;t relevant for this discussion \ud83d\ude00<\/p>\n<h3>Conclusion<\/h3>\n<p>So which is better? What are the pros and cons of each style? Tune in next time to find out!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Like almost everything else these days, Icefall is designed around object-oriented programming (OOP) principles. Specifically, Icefall uses Classes instead of objects, although the difference is not relevant for this discussion. At any given time, the game will be operating dozens of different classes and hundreds of instances of those classes, with the majority of them<\/p>\n","protected":false},"author":2722,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6,3],"tags":[77,4,76,8],"class_list":["post-40","post","type-post","status-publish","format-standard","hentry","category-code","category-icefall","tag-code","tag-freepascal","tag-icefall","tag-oop"],"_links":{"self":[{"href":"http:\/\/www.paradicesoftware.com\/blog\/wp-json\/wp\/v2\/posts\/40","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/www.paradicesoftware.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.paradicesoftware.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.paradicesoftware.com\/blog\/wp-json\/wp\/v2\/users\/2722"}],"replies":[{"embeddable":true,"href":"http:\/\/www.paradicesoftware.com\/blog\/wp-json\/wp\/v2\/comments?post=40"}],"version-history":[{"count":22,"href":"http:\/\/www.paradicesoftware.com\/blog\/wp-json\/wp\/v2\/posts\/40\/revisions"}],"predecessor-version":[{"id":55,"href":"http:\/\/www.paradicesoftware.com\/blog\/wp-json\/wp\/v2\/posts\/40\/revisions\/55"}],"wp:attachment":[{"href":"http:\/\/www.paradicesoftware.com\/blog\/wp-json\/wp\/v2\/media?parent=40"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.paradicesoftware.com\/blog\/wp-json\/wp\/v2\/categories?post=40"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.paradicesoftware.com\/blog\/wp-json\/wp\/v2\/tags?post=40"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}