{"id":636,"date":"2014-06-08T10:23:38","date_gmt":"2014-06-08T10:23:38","guid":{"rendered":"http:\/\/adriangrigoras.com\/blog\/?p=636"},"modified":"2015-06-08T10:24:19","modified_gmt":"2015-06-08T10:24:19","slug":"n-tier-architecture","status":"publish","type":"post","link":"https:\/\/adriangrigoras.com\/blog\/n-tier-architecture\/","title":{"rendered":"N-tier architecture"},"content":{"rendered":"<p>I was going over some\u00a0C# code that was written for a non-profit earlier this year.\u00a0 It was fairly typical code and that&#8217;s what disturbed me so.\u00a0 It consisted of a single ASP.NET Application with most of the work happening in the Page_Load.\u00a0 Although there was only one database, the connection string to that database appeared in at least a dozen places throughout the code.\u00a0 There were a few places where a SELECT * from WHATEVER occurred and they spun through a DataReader in order to set a boolean called &#8220;HasRows&#8221; to true.<\/p>\n<p>So, I had to do something.\u00a0 I understand that not everyone cares, and that not everyone had (or chose to have) any formal Computer Science or Software Engineering academic life (not that there&#8217;s anything wrong with that.)<\/p>\n<p><span style=\"color: #ff0000;\">Disclaimer: This post is just general advice.\u00a0 I know that reams of paper have been written on how to design software, layers, tiers, services, etc.\u00a0 This post is just to remind a few people that you can&#8217;t have multiple layers until you start thinking about the responsibility of each layer &#8211; the contract and binding.\u00a0 Life has hierarchies and layers and responsibility &#8211; and so should most software.<\/span><\/p>\n<p>That being said, here&#8217;s little reminder about layers of abstraction.\u00a0 They are typically a good thing.\u00a0 Remember though, that in &#8220;Scott World&#8221; (which is hopefully your world also \ud83d\ude42 ) a &#8220;Tier&#8221; is a unit of deployment, while a &#8220;Layer&#8221; is a logical separation of responsibility within code.\u00a0 You may say you have a &#8220;3-tier&#8221; system, but be running it on one laptop.\u00a0 You may say your have a &#8220;3-layer&#8221; system, but have only ASP.NET pages that talk to a database.\u00a0 There&#8217;s power in precision, friends.<\/p>\n<ul>\n<li><strong>The Presentation Layer: <\/strong>For the vast majority of programmers who are doing ASP.NET, your\u00a0pages live for one reason, to present an interface to the user.\u00a0 That is usually HTML\/XML. (<em>ya, ya, I know you might produce WML, CHTML, or GIFs with HttpHandlers but this whole post is a generalization<\/em>)\n<ul>\n<li><strong>Things your pages shouldn&#8217;t know about: <\/strong>Your pages shouldn&#8217;t know that a physical data store exists.\u00a0 DasBlog does a lovely job of abstracting away the data store and presenting only an object model to the user.\u00a0 Your ASP.NET pages shouldn&#8217;t know about connection strings, Connections, Commands, or anything like that.<\/li>\n<li><strong>Things your pages should know about: <\/strong>Your pages should know about your Domain Model.\u00a0 Your objects, your stuff.\u00a0 If you&#8217;re a librarian, I suspect you&#8217;ll have a Book object.\u00a0 Perhaps a Librarian Service that knows how to Get and CheckOut books.\u00a0 He\/She (the Service) no doubt knows how to Search for Books also.<\/li>\n<\/ul>\n<\/li>\n<li><strong>The Business Logic Layer:\u00a0<\/strong>\n<ul>\n<li><strong>Things your BizLogic Layer shouldn&#8217;t know about:\u00a0<\/strong>Ideally your business logic layer shouldn&#8217;t know there is a database.\u00a0 It shouldn&#8217;t know about connection strings or SQL.\u00a0 It shouldn&#8217;t know about much of anything except whatever format you choose to represent your objects in (preferably NOT DataSets.)<\/li>\n<li><strong>Things your BizLogic Layer should know about:\u00a0<\/strong>It should know about business rules (This payment will need 5 days of lead-time to be paid, or that book can&#8217;t be checked out by two people at once) but not the details of storage.\u00a0 It might present public methods like &#8220;GetBookByISBN&#8221; or &#8220;CheckOutBook(Book b)&#8221; or &#8220;ReturnBook(Book b).&#8221;<\/li>\n<\/ul>\n<\/li>\n<li><strong>The Data Access Layer: <\/strong>Depending on how &#8220;purist&#8221; you want to get, you can merge the DAL with the Business Layer.\u00a0 At a minimum you should be able to perform <a href=\"http:\/\/www.databasejournal.com\/features\/mssql\/article.php\/3082201\">CRUD<\/a> operations.\u00a0 Create, Read, Update, Delete.\u00a0 Fundamentally most apps are just GETS of stuff and PUTS of stuff.\u00a0 Keep it simple.\u00a0 If your backing data store is XML files, or a Web Service or a Database, it shouldn&#8217;t matter, and ideally your Business Layer (above) doesn&#8217;t even know!\u00a0 It knows there&#8217;s a DAL to talk to, but it&#8217;s all about responsibility.\u00a0 If you are designing a layer, know your in&#8217;s and out&#8217;s and for Goodness&#8217; Sake know your responsibility.\u00a0 If you don&#8217;t, back to the drawing board until you do.\n<ul>\n<li><strong>Things your Data Access Layer shouldn&#8217;t know about: <\/strong>It shouldn&#8217;t know about HTML, and it shouldn&#8217;t know about ASP.NET.\u00a0 It should avoid knowing about business rules that don&#8217;t related directly to how the data is stored (like <a href=\"http:\/\/whatis.techtarget.com\/definition\/0,,sid9_gci498885,00.html\">cardinality<\/a>.)<\/li>\n<li><strong>Things your Data Access Layer should know about: <\/strong>It should know about\u00a0<em>accessing data<\/em> in whatever form it&#8217;s stored.\u00a0 It\u00a0might have functions like &#8220;InsertBook(string name,\u00a0string isbn)&#8221; or &#8220;InsertBook(Book b)&#8221; if you don&#8217;t mind it knowing about your Business Objects (I usually don&#8217;t).\u00a0 It should act as an Adapter between your Data Access Layer and your Data Store.<\/li>\n<\/ul>\n<\/li>\n<li><strong>The Data Store: <\/strong>This might be a SQL Server; then you&#8217;ll need CRUD Stored Procedures to ReadBooks, UpdateBooks, etc.\n<ul>\n<li><strong>Things your Data Store shouldn&#8217;t know about: <\/strong>Your Data Store shouldn&#8217;t be generating messages in language.\u00a0 That means don&#8217;t have your Stored Procs generate English messages.\u00a0 Sounds silly, but I&#8217;ve seen it before in the wild, so it bears repeating.\u00a0 It&#8217;s your Data Store&#8217;s job to get data to the DAL, and little else.<\/li>\n<li><strong>Things your Data Store should know about: <\/strong>Storing stuff.\u00a0 &#8216;Nuff said.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>This may seem overkill, but believe me, once you&#8217;ve done it a few times, you&#8217;ll appreciate it when you come back to mess with the code in the future.\u00a0 Remember also that much of this CRUD stuff can be auto-generated by <a href=\"http:\/\/www.ericjsmith.net\/codesmith\/\"><strong>CodeSmith<\/strong><\/a> or by\u00a0<a href=\"http:\/\/www.deklarit.com\/Demo\/30\/deklaritdemo30.html\"><strong>Deklarit<\/strong><\/a>.\u00a0 Please, do resist the\u00a0urge to open up a SqlConnection\u00a0from your next ASP.NET page.<\/p>\n<p><img decoding=\"async\" src=\"http:\/\/www.hanselman.com\/blog\/content\/binary\/layeredarch.png\" alt=\"\" align=\"baseline\" border=\"0\" hspace=\"0\" \/><\/p>\n<p>Why should you do this?\u00a0 Because of the &#8216;ilities and because the <em>simplest even-slightly layered design hides complexity.\u00a0<\/em><\/p>\n<ul>\n<li><strong>Flexibility<\/strong>: &#8220;The ease with which a system or component can be modified for use in applications or environments other than those for which it was specifically designed.&#8221;<\/li>\n<li><strong>Maintainability<\/strong>: &#8220;The ease with which a software system or component can be modified to correct faults, improve performance, or other attributes, or adapt to a changed environment.&#8221;<\/li>\n<li><strong>Reusability<\/strong>: &#8220;The degree to which a software module or other work product can be used in more than one computing program or software system.&#8221;<\/li>\n<li><strong>Scalability<\/strong>: &#8220;The ease with which a system or component can adjust to changing load.&#8221;<br \/>\n<em>[All these definitions are from the\u00a0IEEE Standard Computer Dictionary.]<\/em><\/li>\n<\/ul>\n<p>Source:\u00a0hanselman.com<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I was going over some\u00a0C# code that was written for a non-profit earlier this year.\u00a0 It was fairly typical code and that&#8217;s what disturbed me so.\u00a0 It consisted of a single ASP.NET Application with most of the work happening in the Page_Load.\u00a0 Although there was only one database, the connection string to that database appeared\u2026 <span class=\"read-more\"><a href=\"https:\/\/adriangrigoras.com\/blog\/n-tier-architecture\/\">Read More &raquo;<\/a><\/span><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-636","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/adriangrigoras.com\/blog\/wp-json\/wp\/v2\/posts\/636","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/adriangrigoras.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/adriangrigoras.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/adriangrigoras.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/adriangrigoras.com\/blog\/wp-json\/wp\/v2\/comments?post=636"}],"version-history":[{"count":1,"href":"https:\/\/adriangrigoras.com\/blog\/wp-json\/wp\/v2\/posts\/636\/revisions"}],"predecessor-version":[{"id":637,"href":"https:\/\/adriangrigoras.com\/blog\/wp-json\/wp\/v2\/posts\/636\/revisions\/637"}],"wp:attachment":[{"href":"https:\/\/adriangrigoras.com\/blog\/wp-json\/wp\/v2\/media?parent=636"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/adriangrigoras.com\/blog\/wp-json\/wp\/v2\/categories?post=636"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/adriangrigoras.com\/blog\/wp-json\/wp\/v2\/tags?post=636"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}