Skip to content

Instantly share code, notes, and snippets.

@beattyml1
Last active April 11, 2016 23:51
Show Gist options
  • Save beattyml1/97d451d870a5da874c63d2cfdccabe9d to your computer and use it in GitHub Desktop.
Save beattyml1/97d451d870a5da874c63d2cfdccabe9d to your computer and use it in GitHub Desktop.
N-Tier Principles

Rules of layers

  • Every layer must provide significant/mearusable value
  • Every layer should for every method provide auto-implementing defaults off of the lower layer or should add significant logic to that method, or should be a completely new method built from business logic functions and lower layer functions
  • Every layer must have any dependencies (if any) passed in or injected
  • Every layer should try as much as possible to assemble logic from dependency free/fully indpendent business modules rather than including business logic in layers
  • Every component in a layer should be as small as possible favoring co-services to additional layers

Smells of bad layers

  • You write the same code over and over
  • You have layers where you repeatedly write a layer calling the lower layer with no addtional logic (and thus value) added
  • You find yourself thinking "This isn't worth testing" because not being worth testing has a high correlation to not being worth writing

One way to possibly implment this as a simple rule

I will from this point on refer to the classes that do things in any layer simply as services or resources and am not just refering resource or service layer if such a thing exists.

I propose that one way to create better services/layers is to strictly enforce the idea of each service being a resource with no more than five or six methods

  • GetOne
  • GetMany (either queriable or parameterized)
  • Post/Create
  • Put/Update
  • Delete

This corresponds roughly with the idea of REST and thus fits neatly with that model. It also means that every service can default auto-implement off of the lower layer easily since there is a consistent interface.

People often object given that real things can do more than CRUD to which my response would be that resource services can can represent functions and procedures as well as records. For example in a medical billing system I may have a claim record that in addition to CRUD may also have an import function however we would instead model this as a Claim Import Resource Service with just a POST method.

This model since it tends toward many services highlights the point above about all business logic needing to be outside of the actual layers and in seperate dependency free business module so that they can be shared and combined. In the above example we may want to borrow some of the validations on create for the import but perhaps not all since biller will be expected to fill in or correct information before it is officially "posted". If they are in the layer it self this is highly problematic however if they are in neatly composed small dependency free functions in a business cross-cutting/shared area this becomes much easier.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment