System Components
sourceA Case For Use
In 1987 Ivar
Jacobson coined the phrase 'use case'. In its original form
this was a simple thing, not the behemoth moster that folk came to
believe and thus know it to be, how unfortunate a thing it is that
most now associate the use case
with this fallacy!

Where as reality would that a Jacobian use case
look
something more like this: A 'Create order' example, part of a
purchasing system.
Create Order
Data:
Primary Course:
- Order clerk issues "Create Order" command with above data.
- System validates all data.
- System creates order and determines order-id.
- System delivers order-id to clerk.
Exception Course: Validation Error
- System delivers error message to clerk
Notice that there is no detail here, it does not tell us what a thing looks like nor what the destination will resemble. The use case is no place for these kinds of detail. A simple list of the kinds of data that we will need to execute the case, along with the processing steps and any eventual error handling.
To summarise; A use case
is concise description at a
high level that depicting the input data, what the processing
steps will be, and the output data.
Interactor Objects
Jacobson stated in his book 'Object oriented software engineering', that if you have a use case of this form, then you can turn it into an object within which you can write your code, He called this a 'control object', however this name did not stick, due to 'Model View Controller'; For our current purpose, we will call this an 'Interactor'.
- When a requirement is of an appropriate form, it can be said to be an object, a use case.
- Core logic of a use case → Interactor Object
- There are two types of business rules:
- application specific, automation, the program, the rules that you apply because this is a computer. [interactor, use case]
- application independent, the business domain, the rules that you would execute even without a computer. [entities, domain specific objects]
These entities are controlled by the interactors. The entities execute the domain specific code, the interactors coordinate the entities.
Boundary interfaces
- Interactors guide or control entities.
- Data flows in and out over marked boundaries, interface IO.
- Methods upon boundaries permit IO.
What about MVC?
Decades before the book 'Design Patterns' was a thing, arguably the first design pattern to have been remarked was MVC. Created by Trygve Reenskaug whilst working on smalltalk-79 for Xerox Park.
The model understands business rules, suppose we are making a clock, the model will understand how to keep time, it does not know how the time is displayed, nor how the time is set nor how input comes into the clock; It only knows about time.
The controller knows all about input, it gathers and structure that input forming commands to run against the model.
The view knows how to display the model data, it knows how to present it, somehow and somewhere. The view, depicted with a thick arrow that denote the observer relationship and callback that it shares with the model, when the model changes, it signals or calls back to the view to tell it that it needs to update.
The MVC pattern, is a very simple input process output model, intended for use on small things, for individual buttons or form, not entire screens, a screen would have several MVC objects all dancing around to make the display coherent.
Modern MVC
Unfortunately modern MVC has evolved to be a mess of models for whose controllers and views are all intermingled, with no hard boundaries. The controllers know about the models and the views, business objects start to develop controller like functions, or worse, the controllers start to accumulate business rule like functions. We see that MVC when done at small scale is ok, but it starts to falter and fail when it scales up.
How MVC goes wrong as web architecture
Model View Presenter
The essence of this architecture is that all arrows, all dependencies, point in only one direction; Towards the business rules.
We can clearly see that all dependencies are pointing towards the interactor and business entities across the boundary by way of the purple lines and arrows.
In this instance of the applications runtime, the interactor has just created the response model, the response model is going to be passed back through the boundary to a presenter which resides on the other side of the boundary; The presenter implements the output boundary, and it lives firmly on the other side of the double black line. The job of the presenter is to reorganise the data so that it is ready to be displayed. The response model is a raw data structure, but it does not know how the data is going to be displayed.
If there is a date in the response model, it is a date object, if there is currency, it is a currency object; The presenter will transform these objects into strings. Dates with the correct formatting, and currency with the correct symbols commas or decimal. The presenter creates a view model, which is a data structure that contains properly formatted strings.
If there are menus on the display, the names on those menus will be loaded in the view model, if there are buttons on the screen, the names of those buttons will be placed in the view model by the presenter. If a button should be grey, because it is inactive, the presenter will set a boolean in the view model to tell the view to make that button grey. All decisions about the view are done in the presenter and put into this view model data structure, and then the view model data structure is handed to the view.
The view here has been drawn as a grey faded thing, all that it does is to take the data out of the view model and put it into the display. A major advantage to this design is that we can test the views without running any domain rules.
Model Presenter Controller
We can see the entire left side of the structure, the interactors on the right deal with requests, taking in request models and from them produce response models, receiving input data from the controllers who then call over the boundary to pass data into the interactors, by way of its interface, which in turn responds to the presenter such that it can produce the appropriate view.
What about the database?
sourceThis image depicts the database as the database vendors would have you believe things ought to be, with database at the centre of all your digital operations. However the reality of a well organised system is somewhat different from this, the database is basically an IO device, they were designed to be the software atop of the rotating disks of the disk drive. From the point of view of the application, the database is just a detail!
The Database is a Detail! ... Isolate it.
We want the database to be on the other side of another
architectural boundary, we do not want the domain rules to know
about the database at all, certainly no SQL nor database schema
should be here! This gateway is an interface that has a method in
it for every query that you need to perform. Supposing that you
would like to show a table of all employees employed after the year
2000, you would have a method EmployedAfter()
into
which you would pass in the date.
Here we have shown only one entity gateway but in reality there may be many. All of the code to implement these interfaces will be the other side of the boundary, for whichever type of IO device it is that you are using to store the data. If it is an SQL database, then all of the SQL will be written in here. There would be no SQL and no schema, crossing that boundary, not even rows should pass over that line.
If you are using ORM or object relational mapping, the ORM should not pass above the database separation line. Many people make the mistake of thinking that your domain objects are the things that the ORM builds, but that is most probably not the case. What the ORM builds is the business data that gets fed to the domain objects, and no necessarily by constructor, but through function arguments. The ORM in our model would be the gateway implementation.
Some major advantages of achieving this kind of separation is that you can test the domain code with greater ease and that the entire persistent storage mechanism can be readily changed.
System Components
We can now easily understand this graphic depicting our system by its components.
The interface at the top is the output boundary, we can tell this from the red arrow that points towards it, in UML that is a using relationship. The interactor uses the output boundary to send data out.
The boundary on the bottom is the input boundary, we can tell this because of the red inheritance arrow from the interactor, the interactor implements the input boundary interface and it uses the output boundary interface, the methods on these boundaries are the methods that allow data to come in and data to go out