{"id":357,"date":"2018-02-27T10:20:56","date_gmt":"2018-02-27T10:20:56","guid":{"rendered":"http:\/\/cppdepend.com\/blog\/?p=357"},"modified":"2023-05-31T16:32:27","modified_gmt":"2023-05-31T16:32:27","slug":"learn-design-patterns-from-rigsofrods-game-project","status":"publish","type":"post","link":"https:\/\/cppdepend.com\/blog\/learn-design-patterns-from-rigsofrods-game-project\/","title":{"rendered":"Learn Design Patterns from RigsOfRods Game Project"},"content":{"rendered":"<p>The majority of developers have already heard about the design patterns,\u00a0<a href=\"http:\/\/en.wikipedia.org\/wiki\/Design_Patterns\">GOF(Gang Of Four)<\/a>\u00a0patterns are the most popularized, and each developer has his way to learn them , we can enumerate:<\/p>\n<ul>\n<li>Reading a book.<\/li>\n<li>From web sites.<\/li>\n<li>From a collegue.<\/li>\n<li>Doing a training.<\/li>\n<\/ul>\n<p><span id=\"more-741\"><\/span>Regardless of the method chose, we can learn by heart the patterns and spent hours to memorize their UML diagrams, but sometimes when we need to use them in a real project, it becomes more problematic.<!--more--><span id=\"more-720\"><\/span><\/p>\n<p>What\u2019s very important is not to know exactly the pattern names and how to implement them as described in the documentation, but what\u2019s more relevant is the motivation\u00a0behind each pattern,\u00a0it\u2019s from the motivations that we invent the patterns.<\/p>\n<p>To master better the pattern motivations, an alternative way is to study them from a real project. It\u2019s the goal of this article, we will try to explore the source code of an open source project using them heavily.<\/p>\n<p><strong>Analysis of Rigs of Rods<\/strong><\/p>\n<p><a href=\"http:\/\/www.rigsofrods.com\/content\/\">Rigs of Rods (\u201cRoR\u201d)<\/a>\u00a0is an open source multi-simulation game which uses soft-body physics to simulate the motion and deformation of vehicles. The game is built using a specific soft-body physics engine called Beam, which simulates a network of interconnected nodes (forming the chassis and the wheels) and gives the ability to simulate deformable objects. With this engine, vehicles and their loads flex and deform as stresses are applied. Crashing into walls or terrain can permanently deform a vehicle.<br \/>\n<img decoding=\"async\" src=\"https:\/\/www.cppdepend.com\/img\/ror.jpg\" \/><\/p>\n<p>Here we go to discover some GOF design patterns used by RoR.<\/p>\n<p><strong>Singleton<\/strong><\/p>\n<p>The singleton is the most popular and the most used one. RoR uses a generic singleton to avoid repeating the same code for each singleton class, it defines two variants: a singleton that create new\u00a0instance and another where an already created\u00a0 instance is assigned.<\/p>\n<p><a href=\"http:\/\/cppdepend.files.wordpress.com\/2012\/10\/ror7.png\"><img decoding=\"async\" class=\"aligncenter size-full wp-image-753\" title=\"ror7\" src=\"http:\/\/cppdepend.files.wordpress.com\/2012\/10\/ror7.png?w=595\" alt=\"\" \/><\/a><\/p>\n<p>Let\u2019s search for all the RoR singletons, for that we can use\u00a0<a href=\"http:\/\/cppdepend.com\/cqlinq.aspx\">CQLinq<\/a>:<\/p>\n<pre>from\u00a0t\u00a0in\u00a0Types\u00a0where\u00a0t.DeriveFrom(\u201cRoRSingletonNoCreation\u201c) || t.DeriveFrom(\u201cRoRSingleton\u201c)\r\nselect\u00a0t<\/pre>\n<p><a href=\"http:\/\/cppdepend.files.wordpress.com\/2012\/10\/ror211.png\"><img decoding=\"async\" class=\"aligncenter size-full wp-image-802\" title=\"ror21\" src=\"http:\/\/cppdepend.files.wordpress.com\/2012\/10\/ror211.png?w=595\" alt=\"\" \/><\/a><\/p>\n<p><em>Motivation:<\/em><\/p>\n<p>Let\u2019s take the example of the InputEngine singleton, RoR needs to store data about keyboard, mouse, and joysticks, which are detected in the initialization by the InputEngine class, many classes needs the same data of the input devices, and no need to create more than one instance, so the primary motivation is to\u00a0<strong>\u201cCreate one instance of InputEngine class\u201c<\/strong>.<\/p>\n<p>However using singleton became controversial, and not all architects and designers recommend it, here\u2019s an\u00a0<a href=\"http:\/\/code.google.com\/p\/google-singleton-detector\/wiki\/WhySingletonsAreControversial\">article<\/a>\u00a0talking about the singleton controversy.<\/p>\n<p><strong>Factory Method<\/strong><\/p>\n<p>There is no mystery about factories, their goal is simple:\u00a0Create instances, and a simple factory containing a CreateInstance method could achieve this goal. However, RoR uses the Factory Method pattern for all its factories instead of using a simple factory.<\/p>\n<p><a href=\"http:\/\/cppdepend.files.wordpress.com\/2012\/10\/ror5.png\"><img decoding=\"async\" class=\"aligncenter size-full wp-image-751\" title=\"ror5\" src=\"http:\/\/cppdepend.files.wordpress.com\/2012\/10\/ror5.png?w=595\" alt=\"\" \/><\/a><\/p>\n<p><em>Motivation:<\/em><\/p>\n<p>To understand better this pattern let\u2019s describe the scenario where RoR uses this pattern:<\/p>\n<ul>\n<li>RoR uses the graphics engine\u00a0<a href=\"http:\/\/www.ogre3d.org\/\">OGRE<\/a>, which\u00a0needs to instantiate the classes of kind ParticleEmitter.<\/li>\n<li>RoR defines and uses its specific ParticleEmitter\u00a0class named BoxEmitter which\u00a0inherits from it, and wants that OGRE uses this new class as ParticleEmitter.<\/li>\n<li>OGRE doesn\u2019t know anything about RoR.<\/li>\n<\/ul>\n<p>The question is how OGRE will know how to instantiate this new class BowEmitter from RoR and uses it?\u00a0Here come the role of \u201cFactory Method\u201d pattern:<\/p>\n<p>OGRE has an abstract class named ParticleEmitterFactory which has the CreateEmitter method, and to achieve its job , OGRE needs to a concrete factory, RoR defines a new factory BoxEmitterFactory inheriting from ParticleEmitterFactory and overloads CreateEmitter method.<\/p>\n<p>RoR gives to OGRE this factory using ParticleSystemManager::addEmitterFactory (ParticleEmitterFactory * factory).\u00a0 And each time OGRE needs an instance of ParticleEmitter, the BoxEmitterFactory is invoked to create it.<\/p>\n<p>The most important motivation is the\u00a0<strong>low coupling<\/strong>, indeed OGRE doesn&#8217;t know anything about RoR and it can instantiate the classes from it.<\/p>\n<p>Another motivation is to enforces the\u00a0<strong>cohesion<\/strong>, and delegate the instantiation to a specific factory class.<\/p>\n<p>Using a simple factory is interesting to isolate the logic instantiation and enforces the cohesion , but using \u201cFactory Method\u201d is more suitable to enforces also the low coupling.<\/p>\n<p><strong>Template Method<\/strong><\/p>\n<p>Template method defines the skeleton of Algorithm in a method, differing some steps to subclasses. Template method lets subclasses redefine some steps of an algorithm without changing the algorithm\u2019s structure.<\/p>\n<p>The objective is to ensure that algorithm\u2019s structure stays unchanged, while subclasses provide some part of the implementation.<br \/>\n<img decoding=\"async\" src=\"http:\/\/cppdepend.com\/img\/Template_Method_Design_Pattern_UML.jpg\" \/><\/p>\n<p>Let\u2019s use\u00a0<a href=\"http:\/\/cppdepend.com\/cqlinq.aspx\">CQLinq<\/a>\u00a0to detect all the classes using the template method pattern, For that we can search for abstract classes ( Abstract class from the UML diagram below) where having one or more methods (templateMethod() from\u00a0 the diagram) which use\u00a0 some\u00a0 methods implemented\u00a0in \u00a0the subclass ( primitive1 and primitive2 from the diagram).<\/p>\n<pre>from\u00a0t\u00a0in\u00a0Types\u00a0where\u00a0t.IsAbstract &amp;&amp;\u00a0<span class=\"skimlinks-unlinked\">t.Methods.Where(a<\/span>=&gt; a.NbLinesOfCode&gt;0 &amp;&amp;\u00a0<span class=\"skimlinks-unlinked\">a.MethodsCalled.Where(b=&gt;b.IsPureVirtual &amp;&amp;<\/span>\u00a0b.ParentType==t).Count()&gt;0).Count()&gt;0\u00a0select\u00a0t<\/pre>\n<p><a href=\"http:\/\/cppdepend.files.wordpress.com\/2012\/10\/ror3.png\"><img decoding=\"async\" class=\"aligncenter size-full wp-image-747\" title=\"ror3\" src=\"http:\/\/cppdepend.files.wordpress.com\/2012\/10\/ror3.png?w=595\" alt=\"\" \/><\/a><\/p>\n<p><em>Motivation:<\/em><\/p>\n<p>Let\u2019s take as example the IRCWrapper class, \u00a0its\u00a0method \u201cprocess\u201d contains the\u00a0logic of processing IRC events received, here are the methods called by it:<\/p>\n<p><a href=\"http:\/\/cppdepend.files.wordpress.com\/2012\/10\/ror15.png\"><img decoding=\"async\" class=\"aligncenter size-full wp-image-791\" title=\"ror15\" src=\"http:\/\/cppdepend.files.wordpress.com\/2012\/10\/ror15.png?w=595\" alt=\"\" \/><\/a><\/p>\n<p>It invokes the pure virtual method processIRCEvent, which must be implemented by a an IRCWrapper derived class. LobbyGui is one of them and needs to treat the IRC events received, it\u00a0overloads the processIRCEvent method to implements its specific behavior.<\/p>\n<p>With this pattern, we can easily change the implementation of algorithms without changing the skeleton, it removes the boilerplate\u00a0code and make easy the maintenance of these classes.<\/p>\n<p>It also enforces the\u00a0<strong>low coupling<\/strong>, because the client could reference only the abstract class instead of the concrete ones.<\/p>\n<p><strong>Strategy<\/strong><\/p>\n<p>There are common situations when classes differ only in their behavior. For this cases is a good idea to isolate the algorithms in separate classes in order to have the ability to select different algorithms at runtime.<\/p>\n<p>Let\u2019s use CQLinq to detect all classes using strategy pattern, For this purpose we can search for abstract classes, having multiple derived classes, and where the client reference the abstract class instead of the concrete implementations.<\/p>\n<pre>from\u00a0t\u00a0in\u00a0Types\u00a0where\u00a0t.IsAbstract &amp;&amp;\u00a0<span class=\"skimlinks-unlinked\">t.DirectDerivedTypes.Count()&gt;1<\/span>\u00a0!t.IsThirdParty\r\nlet\u00a0tt=t.DirectDerivedTypes\r\nfrom\u00a0db\u00a0in\u00a0tt\u00a0where\u00a0<span class=\"skimlinks-unlinked\">db.Methods.Where(a=&gt;a.NbMethodsCallingMe!=0<\/span>\u00a0!a.IsStatic).Count()==0\r\nselect\u00a0new {db,t}\r\n<\/pre>\n<p><a href=\"http:\/\/cppdepend.files.wordpress.com\/2012\/10\/ror41.png\"><img decoding=\"async\" class=\"aligncenter size-full wp-image-807\" title=\"ror4\" src=\"http:\/\/cppdepend.files.wordpress.com\/2012\/10\/ror41.png?w=595\" alt=\"\" \/><\/a><\/p>\n<p><em>Motivation:<\/em><\/p>\n<p>The camera could have multiple behaviors: fixed, free, static or isometric, and this behavior could be changed dynamically. Also, other behaviors could be added in the future.<\/p>\n<p>The CameraManager uses the abstract behavior IBehavior and\u00a0 here are all the methods from CameraManager \u00a0using IBehavior class.<\/p>\n<p><a href=\"http:\/\/cppdepend.files.wordpress.com\/2012\/10\/ror17.png\"><img decoding=\"async\" class=\"aligncenter size-full wp-image-796\" title=\"ror17\" src=\"http:\/\/cppdepend.files.wordpress.com\/2012\/10\/ror17.png?w=595\" alt=\"\" \/><\/a><\/p>\n<p>As we can observe, there is a method named switchBehavior to change the behavior dynamically.<\/p>\n<p>This pattern enforces the\u00a0<strong>low coupling<\/strong>, Indeed, CameraManger doesn&#8217;t know the concrete behaviors, and also enforces the\u00a0<strong>high cohesion<\/strong>, because each specific behavior is implemented in a isolated class.<\/p>\n<p><strong>State<\/strong><\/p>\n<p>State pattern is similar to the Strategy Design Pattern from an architectural point of view, and for this reason for the previous CQLinq request when we searched for strategy pattern, we found also state classes.<\/p>\n<p>But the goal is different, the Strategy pattern represents an algorithm that uses one or more IStrategy\u00a0<span class=\"skimlinks-unlinked\">implementations.\u00a0T<\/span>here\u2019s no correlation between these different behavior, however for State pattern we pass from one state to another to acheive the final objective, so there\u2019s a cohesion between the different states.<\/p>\n<p>Here are all state classes inheriting from the abstract class AppState<\/p>\n<p><a href=\"http:\/\/cppdepend.files.wordpress.com\/2012\/10\/ror18.png\"><img decoding=\"async\" class=\"aligncenter size-full wp-image-797\" title=\"ror18\" src=\"http:\/\/cppdepend.files.wordpress.com\/2012\/10\/ror18.png?w=595\" alt=\"\" \/><\/a><\/p>\n<p>Like Strategy pattern, only the abstract class is referenced by the other classes, here are all the methods using AppState.<\/p>\n<p><a href=\"http:\/\/cppdepend.files.wordpress.com\/2012\/10\/ror19.png\"><img decoding=\"async\" class=\"aligncenter size-full wp-image-798\" title=\"ror19\" src=\"http:\/\/cppdepend.files.wordpress.com\/2012\/10\/ror19.png?w=595\" alt=\"\" \/><\/a><\/p>\n<p>As we can observe, AppStateManager contains many methods to manage the state lifecycle.<\/p>\n<p><em>Motivation:<\/em><\/p>\n<p>Like Strategy pattern, this pattern enforces the\u00a0<strong>low coupling<\/strong>, AppStateManger doesn&#8217;t know the concrete states and also enforces the\u00a0<strong>high cohesion,<\/strong>\u00a0because each treatment is isolated in its corresponding state.<\/p>\n<p><strong>Facade<\/strong><\/p>\n<p>A facade is an object that provides a simplified interface to a larger body of code, such as a class library. And to detected facades used the simple way is to search for external code used.<\/p>\n<p>Here\u2019s all namespaces used by ROR project:<\/p>\n<p><a href=\"http:\/\/cppdepend.files.wordpress.com\/2012\/10\/ror121.png\"><img decoding=\"async\" class=\"aligncenter size-full wp-image-761\" title=\"ror12\" src=\"http:\/\/cppdepend.files.wordpress.com\/2012\/10\/ror121.png?w=595\" alt=\"\" \/><\/a><\/p>\n<p>let\u2019s take as example the Caelum namespace and search for classes using it from ROR<\/p>\n<pre>from\u00a0m\u00a0in\u00a0Methods\u00a0where\u00a0m.IsUsing (\u201cCaelum\u201c)\r\nselect\u00a0new { m }<\/pre>\n<p><a href=\"http:\/\/cppdepend.files.wordpress.com\/2012\/10\/ror9.png\"><img decoding=\"async\" class=\"aligncenter size-full wp-image-756\" title=\"ror9\" src=\"http:\/\/cppdepend.files.wordpress.com\/2012\/10\/ror9.png?w=595\" alt=\"\" \/><\/a><\/p>\n<p>Only SkyManager use directly Caelum namespace, so it represent the Caelum facade.<\/p>\n<p><em>Motivation<\/em><\/p>\n<p>If we use an external library and its highly coupled with our code, i.e. many classes use directly this library, it will be very difficult to change this external library. However, if a facade is used, only its implementation will be changed if we want to change the external library.<\/p>\n<p>This pattern enforces the\u00a0<strong>low coupling<\/strong>\u00a0with external libraries.<\/p>\n<p><strong>Conclusion<\/strong><\/p>\n<p>After learning the GOF patterns, it&#8217;s interesting\u00a0 to know the motivations behind using them in your code. Discovering the implementation of patterns from known open source projects could help you to understand better the utility of the patterns.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The majority of developers have already heard about the design patterns,\u00a0GOF(Gang Of Four)\u00a0patterns are the most popularized, and each developer has his way to learn them , we can enumerate: Reading a book. From web sites. From a collegue. Doing a training. Regardless of the method chose, we can learn by heart the patterns and &hellip; <a href=\"https:\/\/cppdepend.com\/blog\/learn-design-patterns-from-rigsofrods-game-project\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Learn Design Patterns from RigsOfRods Game Project&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[67,210,209,208,137,207],"class_list":["post-357","post","type-post","status-publish","format-standard","hentry","category-uncategorized","tag-c-2","tag-design-patterns","tag-game","tag-gaming","tag-programming","tag-rigs-of-rods"],"_links":{"self":[{"href":"https:\/\/cppdepend.com\/blog\/wp-json\/wp\/v2\/posts\/357","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/cppdepend.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/cppdepend.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/cppdepend.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/cppdepend.com\/blog\/wp-json\/wp\/v2\/comments?post=357"}],"version-history":[{"count":8,"href":"https:\/\/cppdepend.com\/blog\/wp-json\/wp\/v2\/posts\/357\/revisions"}],"predecessor-version":[{"id":1496,"href":"https:\/\/cppdepend.com\/blog\/wp-json\/wp\/v2\/posts\/357\/revisions\/1496"}],"wp:attachment":[{"href":"https:\/\/cppdepend.com\/blog\/wp-json\/wp\/v2\/media?parent=357"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cppdepend.com\/blog\/wp-json\/wp\/v2\/categories?post=357"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cppdepend.com\/blog\/wp-json\/wp\/v2\/tags?post=357"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}