Advancing Engineering with AI through the Next Generation of Strategic Projec...
A4 from rad to mvc
1. Software Architecture & Design
Architecture
From n-Tier to SOA
From SOAP to REST
Technical Debt
Design
From SQL to ORM, NoSQL and ODM
From RAD to MVC
SOLID principles
Domain Driven Design (DDD)
Applying patterns on Delphi code using mORMot
Software Architecture & Design
3. From RAD to MVC
RAD
MVC
MVVM
n-Tier / SOA
Web MVC with mORMot
From RAD to MVC
4. Rapid Application Development
Our beloved Delphi
WYSIWYG
Quick prototyping
Less typing
Component-based
Ownership to handle memory
Reusability
From RAD to MVC
5. Rapid Application Development
HTML# Web programing
# < 5
PHP template system
Run SQL from the template!
Huge included general purpose library
Lot of Open Source frameworks
Easy to setup (LAMP)
From RAD to MVC
6. Rapid Application Development
Big Ball of Mud
Mixes User Interface and logic
Mixes UI, logic and database
Modules did not help
Difficult to maintain and evolve
Manual testing
Platform specific (web application?)
Fat clients (SaaS?)
From RAD to MVC
7. Rapid Application Development
To be fair
Bad programmers write bad code;
Good programmers write good code.
RAD lets bad programmers write bad code faster;
RAD does NOT cause good programmers to
suddenly start writing badly.
From RAD to MVC
8. Model-View-Controller (MVC)
Architecture pattern which:
Isolates “Domain Logic”
Application logic for the end-user
Business logic e.g. for data persistence
From “User Interface”
Input and presentation
Permitting uncoupled
development, testing and maintenance
Separation of concerns
From RAD to MVC
9. Model-View-Controller (MVC)
Model What it is
Manages the behavior of the data
View What it looks like
Renders the model for interaction
Controller What it does
Receives User inputs
Instructs the Model and View
From RAD to MVC
10. Model-View-Controller (MVC)
The Model
Contains all business logic
Contains data for the application
Often linked to a database or REST
Contains state of the application
e.g. what orders a customer has
Notifies the View of state changes
If needed, e.g. not for stateless views
No knowledge of user interfaces
So it can be reused
From RAD to MVC
11. Model-View-Controller (MVC)
The View
Generates the user interface
which presents data to the user
Passive (doesn’t do any processing)
Many views can use
the same model for different reasons
From RAD to MVC
12. Model-View-Controller (MVC)
The Controller
Receives events from the outside world
Usually through views
Interacts with the model
Displays the appropriate view to the user
From RAD to MVC
14. MVC, MVVM, MVCVM
MVVM and MVCVM
Even more uncoupled
For better testing
The ViewModel
May (or not) replace the controller
Expose data and command objects for the view
Eases two-way communication
From RAD to MVC
15. MVVM, MVCVM
Model
Holds the actual data
(various context, store or other methods)
View
Displays a certain shape of data
Has no idea where the data comes from
ViewModel
Holds a certain shape of data and commands
Does not know where the data, or code, comes from or how it is displayed
Is re-usable for several views
Controller
Listens for, and publishes, events
Provides the logic to display the data
Provides the command code to the ViewModel
From RAD to MVC
17. MVVM UI in Delphi
LiveBindings
Effective since XE3
DSharp / Spring4D
Convention-Over-Configuration interfaces
MGM pattern used in hcOPF
Mediator component to bind the UI at design time
mORMot
Mustache Web, SOA app layer (preparing VCL/FMX)
From RAD to MVC
18. MVVM UI in Delphi
MVVM in Delphi
Architecting and Building Model View
ViewModel Applications
by Kouraklis, John
for the concepts – not really reusable
There is still some place for tools
VCL / FMX / LCL / HTML / AJAX compatible stuff
may be interface-based for the controller/VM definition
let’s see with other OpenSource authors…
From RAD to MVC
19. MVC and n-Tier / SOA
From RAD to MVC
Presentation Tier
Application Tier
Business Logic Tier
Data Tier
View
Controller
Model
Client 1 (Delphi) Client 2 (AJAX)
Application Server
DB Server
Presentation Tier
Application Tier
Presentation Tier
Business Logic Tier
Data Tier
22. MVC Web Apps
From RAD to MVC
mORMot MVC Web Apps
Model
View
Controller
RESTful SOA or ORM
SynMustache
IMVCApplication
23. SynMustache Views
From RAD to MVC
Mustache template system
Generates HTML, TXT, JSON, …
Data context as TDocVariant
UTF-8 JSON
With extensions
24. SynMustache Views
From RAD to MVC
Data Context
{
"header": "Colors",
"items": [
{"name": "red", "first": true, "url": "#Red"},
{"name": "green", "link": true, "url": "#Green"},
{"name": "blue", "link": true, "url": "#Blue"}
],
"empty": true
}
25. SynMustache Views
From RAD to MVC
Template
<h1>{{header}}</h1>
{{#items}}
{{#first}}
<li><strong>{{name}}</strong></li>
{{/first}}
{{#link}}
<li><a href="{{url}}">{{name}}</a></li>
{{/link}}
{{/items}}
{{#empty}}
<p>The list is empty.</p>
{{/empty}}
26. SynMustache Views
From RAD to MVC
Result
<h1>Colors</h1>
<li><strong>red</strong></li>
<li><a href="#Green">green</a></li>
<li><a href="#Blue">blue</a></li>
<p>The list is empty.</p>
27. SynMustache Views
From RAD to MVC
Data Context
{
"header": "Colors",
"items": [
{"name": "red", "first": true, "url": "#Red"},
{"name": "green", "link": true, "url": "#Green"},
{"name": "blue", "link": true, "url": "#Blue"}
],
"empty": true
}
28. SynMustache Views
From RAD to MVC
Template
<h1>{{header}}</h1>
{{#items}}
{{#first}}
<li><strong>{{name}}</strong></li>
{{/first}}
{{#link}}
<li><a href="{{url}}">{{name}}</a></li>
{{/link}}
{{/items}}
{{#empty}}
<p>The list is empty.</p>
{{/empty}}
29. SynMustache Views
From RAD to MVC
Result
<h1>Colors</h1>
<li><strong>red</strong></li>
<li><a href="#Green">green</a></li>
<li><a href="#Blue">blue</a></li>
<p>The list is empty.</p>
30. SynMustache Views
From RAD to MVC
Data Context
{
"header": "Colors",
"items": [
{"name": "red", "first": true, "url": "#Red"},
{"name": "green", "link": true, "url": "#Green"},
{"name": "blue", "link": true, "url": "#Blue"}
],
"empty": true
}
31. SynMustache Views
From RAD to MVC
Template
<h1>{{header}}</h1>
{{#items}}
{{#first}}
<li><strong>{{name}}</strong></li>
{{/first}}
{{#link}}
<li><a href="{{url}}">{{name}}</a></li>
{{/link}}
{{/items}}
{{#empty}}
<p>The list is empty.</p>
{{/empty}}
32. SynMustache Views
From RAD to MVC
Result
<h1>Colors</h1>
<li><strong>red</strong></li>
<li><a href="#Green">green</a></li>
<li><a href="#Blue">blue</a></li>
<p>The list is empty.</p>
33. SynMustache Views
From RAD to MVC
Data Context
{
"header": "Colors",
"items": [
{"name": "red", "first": true, "url": "#Red"},
{"name": "green", "link": true, "url": "#Green"},
{"name": "blue", "link": true, "url": "#Blue"}
],
"empty": true
}
34. SynMustache Views
From RAD to MVC
Template
<h1>{{header}}</h1>
{{#items}}
{{#first}}
<li><strong>{{name}}</strong></li>
{{/first}}
{{#link}}
<li><a href="{{url}}">{{name}}</a></li>
{{/link}}
{{/items}}
{{#empty}}
<p>The list is empty.</p>
{{/empty}}
35. SynMustache Views
From RAD to MVC
Result
<h1>Colors</h1>
<li><strong>red</strong></li>
<li><a href="#Green">green</a></li>
<li><a href="#Blue">blue</a></li>
<p>The list is empty.</p>
36. SynMustache Views
From RAD to MVC
Mustache template system benefits
No RAD, but MVC
Known and simple pattern
Rendered by any technology (even on client side)
Easy integration with responsive CSS (Bootsrap)
Delegate UI to CSS/HTML experts
Generates not only HTML but TXT, JSON, …
Data context allows automated testing
37. MVC Web Apps
From RAD to MVC
mORMot MVC Web Apps (n-tier)
Model
View
Controller
RESTful SOA or ORM
SynMustache
IMVCApplication
39. MVC Web Apps
From RAD to MVC
Blog MVC Sample
Model
View
Controller
RESTful ORM
SynMustache
IMVCApplication
40. MVC Web Apps
From RAD to MVC
Blog MVC Sample (3-Tier)
View
Controller
Model
SynMustache
IMVCApplication
RESTful ORM
(SOA for bigger projects)
Presentation Tier
Logic Tier
Data Tier
41. MVC Web Apps
From RAD to MVC
Blog MVC Sample
Following Convention Over Configuration pattern
Model
View
Controller
MVCModel.pas
*.html
MVCViewModel.pas
42. MVC Web Apps
From RAD to MVC
Define a Controller
IBlogApplication = interface(IMVCApplication)
['{73B27C06-9DB9-45A2-BEDD-2013CFB609D0}']
procedure ArticleView(ID: TID;
var WithComments: boolean; Direction: integer; var Scope: variant;
out Article: TSQLArticle; out Author: variant;
out Comments: TObjectList);
procedure AuthorView(
var ID: TID; out Author: TSQLAuthor; out Articles: variant);
function Login(
const LogonName,PlainPassword: RawUTF8): TMVCAction;
function Logout: TMVCAction;
function ArticleComment(ID: TID; const Title,Comment: RawUTF8): TMVCAction;
function ArticleMatch(const Match: RawUTF8): TMVCAction;
procedure ArticleEdit(var ID: TID; const Title,Content: RawUTF8;
const ValidationError: variant;
out Article: TSQLArticle);
function ArticleCommit(
ID: TID; const Title,Content: RawUTF8): TMVCAction;
end;
43. MVC Web Apps
From RAD to MVC
Implement a Controller
/// implements the ViewModel/Controller of this BLOG web site
TBlogApplication = class(TMVCApplication,IBlogApplication)
protected
...
public
procedure Default(var Scope: variant);
procedure ArticleView(ID: TID;
var WithComments: boolean; Direction: integer; var Scope: variant;
out Article: TSQLArticle; out Author: variant;
out Comments: TObjectList);
procedure AuthorView(
var ID: TID; out Author: TSQLAuthor; out Articles: variant);
...
44. MVC Web Apps
From RAD to MVC
Define a Controller
IBlogApplication = interface(IMVCApplication)
['{73B27C06-9DB9-45A2-BEDD-2013CFB609D0}']
...
procedure AuthorView(
var ID: TID; out Author: TSQLAuthor; out Articles: variant);
...
end;
45. MVC Web Apps
From RAD to MVC
Implement a Controller
procedure TBlogApplication.AuthorView(var ID: integer;
out Author: TSQLAuthor; out Articles: variant);
Method name identifies:
The input URI (with parameters)
/blog/AuthorView?ID=..[integer]..
The output template
AuthorView.html
46. MVC Web Apps
From RAD to MVC
Implement a Controller
procedure TBlogApplication.AuthorView(var ID: integer;
out Author: TSQLAuthor; out Articles: variant);
begin
RestModel.Retrieve(ID,Author);
Author.HashedPassword := ''; // no need to publish it
if Author.ID<>0 then
Articles := RestModel.RetrieveDocVariantArray(
TSQLArticle,'','Author=? order by RowId desc limit 50',[ID],ARTICLE_FIELDS) else
raise EMVCApplication.CreateGotoError(HTML_NOTFOUND);
end;
47. MVC Web Apps
From RAD to MVC
Implement a Controller
procedure TBlogApplication.AuthorView(var ID: integer;
out Author: TSQLAuthor; out Articles: variant);
const from web client to controller in
out from controller to view out
var from web client to controller, in and out
and from controller to view
48. MVC Web Apps
From RAD to MVC
Implement a Controller
/blog/AuthorView?ID=123
procedure TBlogApplication.AuthorView(var ID: integer;
out Author: TSQLAuthor; out Articles: variant);
begin
// here ID = 123
RestModel.Retrieve(ID,Author);
Author.HashedPassword := ''; // no need to publish it
Input parameters are taken from the URI
And transmitted to the Controller method
49. MVC Web Apps
From RAD to MVC
Implement a Controller
procedure TBlogApplication.AuthorView(var ID: integer;
out Author: TSQLAuthor; out Articles: variant);
begin
RestModel.Retrieve(ID,Author);
Author.HashedPassword := ''; // no need to publish it
if Author.ID<>0 then
Articles := RestModel.RetrieveDocVariantArray(
TSQLArticle,'','Author=? order by RowId desc limit 50',[ID],ARTICLE_FIELDS) else
raise EMVCApplication.CreateGotoError(HTML_NOTFOUND);
end;
{{ID}} {{Author}} {{Articles}}
in the Mustache Data Context
50. MVC Web Apps
From RAD to MVC
Implement a Controller
procedure TBlogApplication.AuthorView(var ID: integer;
out Author: TSQLAuthor; out Articles: variant);
http://localhost:8092/blog/mvc-info
→ /blog/AuthorView?ID=..[integer]..
{{Main}}: variant
{{ID}}: integer
{{Author}}: TSQLAuthor
{{Articles}}: variant
51. MVC Web Apps
From RAD to MVC
Sample 30 URIs
http://localhost:8092/blog/default
http://localhost:8092/blog/mvc-info
http://localhost:8092/blog/articleView?id=99
http://localhost:8092/blog/articleView/json?id=99
http://localhost:8092/blog/authorView?id=1