{"id":2033,"date":"2015-07-14T23:12:20","date_gmt":"2015-07-14T13:12:20","guid":{"rendered":"http:\/\/www.malcolmgroves.com\/blog\/?p=2033"},"modified":"2015-07-15T13:57:09","modified_gmt":"2015-07-15T03:57:09","slug":"mvvm-and-menialtasks-why-did-i-use-tenumerablebindsourceadapter-instead-of-tlistbindsourceadapter","status":"publish","type":"post","link":"http:\/\/www.malcolmgroves.com\/blog\/?p=2033","title":{"rendered":"MVVM and MenialTasks : Why did I use TEnumerableBindSourceAdapter instead of TListBindSourceAdapter?"},"content":{"rendered":"<p>In the comments\u00a0over on my old <a href=\"http:\/\/www.malcolmgroves.com\/blog\/?p=1340\" target=\"_blank\">MVVM Resource List post<\/a>\u00a0Peter Rosario asked a great question. A question I thought I&#8217;d covered in <a href=\"http:\/\/www.embarcadero.com\/coderage\/coderage-7-delphi-sessions?session=Tuesday#Session11\" target=\"_blank\">my video<\/a> but I suspect I might have edited it out in an attempt to fit into the CodeRage time limits. So I thought I&#8217;d answer it here.<\/p>\n<p>The question was about my <a href=\"https:\/\/github.com\/malcolmgroves\/menialtasks\" target=\"_blank\">MenialTasks sample app<\/a>, and why I&#8217;d used <a href=\"https:\/\/github.com\/malcolmgroves\/menialtasks\/blob\/master\/src\/EnumerableAdapter.pas\" target=\"_blank\">TEnumerableBindSourceAdapter<\/a> to bind my collection of TTasks to the UI, rather than the more common <a href=\"http:\/\/docwiki.embarcadero.com\/Libraries\/en\/Data.Bind.ObjectScope.TListBindSourceAdapter\" target=\"_blank\">TListBindSourceAdapter<\/a>.<\/p>\n<p>TListBindSourceAdapter has a lot going for it. It comes &#8220;in the box&#8221;, would certainly have been easier, and would work just fine. Given that, why didn&#8217;t I use it?<!--more--><\/p>\n<p>The sticking point I had with TListBindSourceAdapter is\u00a0because it expects to be bound to a TList&lt;T&gt;, and my\u00a0<a href=\"https:\/\/github.com\/malcolmgroves\/menialtasks\/blob\/master\/src\/model\/Model.TaskList.pas\" target=\"_blank\">TTaskList<\/a>\u00a0is not a TList&lt;TTask&gt;. Rather, it is\u00a0a domain wrapper around TList&lt;TTask&gt; (actually a TObjectList&lt;TTask&gt;, but that&#8217;s beside the point).<\/p>\n<p>My TTaskList controls access to the underlying TList&lt;TTask&gt;, providing methods like AddNewTask, AddTask(Task : TTask), etc. These functions make sure that any View or ViewModel\u00a0code that wants to mess with the contents of my TTaskList has to go through my validation logic (or any other code I want).<\/p>\n<p>Using TListBindSourceAdapter would require\u00a0exposing my underlying TList&lt;TTask&gt; to client code, allowing them to Add, Delete and Insert as much as they like, and I&#8217;d be left having to try and react after the fact.<\/p>\n<p>On the other hand, using TEnumerableBindSourceAdapter meant I just had to expose a\u00a0<a href=\"http:\/\/docwiki.embarcadero.com\/Libraries\/en\/System.Generics.Collections.TEnumerable\" target=\"_blank\">TEnumerable<\/a>&lt;TTask&gt;, providing a much more limited set of capabilities to the client, and leaving my TTaskList in control of its contents.<\/p>\n<p>The follow-on question is: was this the right decision?<\/p>\n<p>If this were one of my own projects it would be an easy answer: Yes, totally. My own convictions on how I design my code, and the relative values I place on expediency vs purity mean I would\u00a0(and do) use\u00a0TEnumerableBindSourceAdapter in this situation.<\/p>\n<p>However this wasn&#8217;t strictly &#8220;my&#8221; code. Yes, I wrote it, but it&#8217;s for public consumption. Further, the aim of this code wasn&#8217;t to show someone how I like to design applications, but rather to serve as a minimal example of MVVM. Given that, maybe I was over-complicating things, or putting the emphasis on the wrong areas? Which option served the educational purposes better?<\/p>\n<p>This is what I went backwards and forwards on many times. The code actually existed both ways at various stages. In the end I decided the additional complexity introduced by\u00a0TEnumerableBindSourceAdapter stank less than exposing my TList&lt;TTask&gt; in my domain object.<\/p>\n<p>Someone much smarter than me once said &#8220;Design is Compromise&#8221;, and this is the key here. This decision may not be right for you, or even right for me in every situation. We develop in an imperfect world and often\u00a0you are left having to balance\u00a0two imperfect options.<\/p>\n<p>That balancing act is the source of some of the most educational parts of the job, in my view.<\/p>\n<p>Anyway, thank you Peter for the question. I hope that answered it ok.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In the comments\u00a0over on my old MVVM Resource List post\u00a0Peter Rosario asked a great question. A question I thought I&#8217;d covered in my video but I suspect I might have edited it out in an attempt to fit into the CodeRage time limits. So I thought I&#8217;d answer it here. The question was about my [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[97,116,90],"tags":[48],"class_list":["post-2033","post","type-post","status-publish","format-standard","hentry","category-architecture","category-livebindings","category-mvvm","tag-embarcadero"],"_links":{"self":[{"href":"http:\/\/www.malcolmgroves.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/2033","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/www.malcolmgroves.com\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.malcolmgroves.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.malcolmgroves.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/www.malcolmgroves.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2033"}],"version-history":[{"count":10,"href":"http:\/\/www.malcolmgroves.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/2033\/revisions"}],"predecessor-version":[{"id":2043,"href":"http:\/\/www.malcolmgroves.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/2033\/revisions\/2043"}],"wp:attachment":[{"href":"http:\/\/www.malcolmgroves.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2033"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.malcolmgroves.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2033"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.malcolmgroves.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2033"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}