{"id":72,"date":"2011-06-17T00:00:52","date_gmt":"2011-06-17T04:00:52","guid":{"rendered":"http:\/\/GetOffMyLawnEntertainment.com\/blog\/?p=72"},"modified":"2011-10-01T23:59:05","modified_gmt":"2011-10-02T03:59:05","slug":"my-view-on-views","status":"publish","type":"post","link":"http:\/\/GetOffMyLawnEntertainment.com\/blog\/2011\/06\/17\/my-view-on-views\/","title":{"rendered":"My View on Views"},"content":{"rendered":"<p>I was going over some GUI related code the other day and saw something I figured I could share with the world.  Don&#8217;t design your views through inheritance.  Design them through components instead.  Not that this is GUI specific, but I tend to see the same problem again and again when people think about designing GUI related code.<br \/>\n<!--more--><\/p>\n<p>The code usually looks something like this<\/p>\n<p><code><br \/>\nclass Foo {<br \/>\n...<br \/>\n&nbsp;&nbsp;virtual void setup() {<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;view.set(createBunchOfWidgetsLookAndFeel());<br \/>\n&nbsp;&nbsp;}<\/code><\/p>\n<p><code><br \/>\n&nbsp;&nbsp;Container createABunchOfWidgetsLookAndFeel() {<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;Container c = createContainer();<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;c.add(new Button(\"OK\"));<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;c.add(new Button(\"Cancel\"));<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;c.add(new Text(\"hi\"));<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;return c;<br \/>\n&nbsp;&nbsp;}<br \/>\n...<br \/>\n};<br \/>\n<\/code><br \/>\n&nbsp;<br \/>\n<code>class SubFoo : public Foo {<br \/>\n...<br \/>\n&nbsp;&nbsp;void setup() {<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;Container c = createABunchOfWidgetsLookAndFeel();<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;c.add(new OtherWidget());<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;view.set(c );<br \/>\n&nbsp;&nbsp;}<br \/>\n...<br \/>\n};<\/code><\/p>\n<p>Nothing really looks wrong here, and in fact you&#8217;re reusing code which is good right? Nope sorry you lose! You&#8217;ve just created a set of views which depend on each other and are now a pain to try to customize.<\/p>\n<p>Let&#8217;s work through this and go a bit deeper first so that we really understand the problem.  You&#8217;ve now got two separate views and you&#8217;re asked to change only one of them.  In particular let&#8217;s add a new &#8220;Donate&#8221; button in SubFoo in between the OK and Cancel.  At this point most people will create a virtual in Foo called getOtherButton().  The new method returns null in Foo, and the new Button in SubFoo, and then if not null, it adds the button into the middle of our container.  That&#8217;s kind of an odd bit of knowledge Foo now has about its children.  I&#8217;m also going to claim that it&#8217;s much harder to maintain the two views.  It&#8217;s harder because now when you change one, you have to think about the effects in the other.  In fact, before you change one, you should probably understand what the effects are for both.<\/p>\n<p>I think it&#8217;s our perception of a View and how we&#8217;re using it here that is the real problem, and that&#8217;s probably why I typically relate it to GUI design.  A View is a set of components that we can see and often a View is really just a component itself, but I ask you to think of a View and a set of components as slightly different.  A set of components is just that, a set of components arranged together and any one of those components is swappable with another.  Where as the View is that top level component that holds everything and you don&#8217;t usually swap between views in the same way as components.  I think most people usually consider the View in this scenario as the Controller as well.<\/p>\n<p>So what does it actually mean to subclass a View?  Can you really think of a View that should change polymorphically?  Is it really the View that should be changing polymorphically or is it one of the components within the View?  If it&#8217;s one of the components within, then yes I can definitely understand wanting to reuse code to do something that&#8217;s very similar.  And in fact we&#8217;re all taught that we should reuse code whenever possible.  Well in this case it&#8217;s bad\u2026 or at least there&#8217;s a better place to reuse the code.<\/p>\n<p>Look at what you&#8217;re trying to do.  You&#8217;re trying to create two separate views with a very similar sets of components.  So why not create a new MegaComponent that is the similar set of components?  Then you can create a MegaSubComponent that fills in the new Button in the middle, and each View creates the component it wants.  Yes, we&#8217;ve really only moved the code reuse to another spot, but now each of our views are separate, just like how we normally think about them from a high level.  The views are now being created through reusable components, you just happened to have created a new tree of components to use.<\/p>\n<p>No the code isn&#8217;t very different between the two cases, but I really want to stress that there is a huge difference in the design at this point.  And a huge difference in how things will get reused later on.  You can now reuse that bigger component in many different scenarios without pulling in some of the other code that might be related to the View.  People will also  be able to quickly jump into code based on the View they see and trace through things from a solid starting point, rather than having to know the intricacies of everything all up front.<\/p>\n<p>In most cases subclassing Views in order to inherit code means you&#8217;re creating hard to maintain dependencies.  Instead, code should be pulled out to a helper class or separate component etc. in order to allow the same reuse.  Remember design by inheritance is BAD! Design by components is GOOD!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I was going over some GUI related code the other day and saw something I figured I could share with the world. Don&#8217;t design your views through inheritance. Design them through components instead. Not that this is GUI specific, but I tend to see the same problem again and again when people think about designing [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-72","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"http:\/\/GetOffMyLawnEntertainment.com\/blog\/wp-json\/wp\/v2\/posts\/72","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/GetOffMyLawnEntertainment.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/GetOffMyLawnEntertainment.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/GetOffMyLawnEntertainment.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/GetOffMyLawnEntertainment.com\/blog\/wp-json\/wp\/v2\/comments?post=72"}],"version-history":[{"count":10,"href":"http:\/\/GetOffMyLawnEntertainment.com\/blog\/wp-json\/wp\/v2\/posts\/72\/revisions"}],"predecessor-version":[{"id":128,"href":"http:\/\/GetOffMyLawnEntertainment.com\/blog\/wp-json\/wp\/v2\/posts\/72\/revisions\/128"}],"wp:attachment":[{"href":"http:\/\/GetOffMyLawnEntertainment.com\/blog\/wp-json\/wp\/v2\/media?parent=72"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/GetOffMyLawnEntertainment.com\/blog\/wp-json\/wp\/v2\/categories?post=72"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/GetOffMyLawnEntertainment.com\/blog\/wp-json\/wp\/v2\/tags?post=72"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}