Hierarchical MVC
Transform your Monolith
WHO AM I?
• Luis Majano - Computer Engineer
• El Salvador
• Houston,Texas
• Computer Engineer
• CEO of Ortus Solutions
• Creator of many boxes
www.ortussolutions.com
@ortussolutions
@lmajano
AGENDA
• What is the problem?
• Monolithic Applications
• HMVC
• Modular Architecture
• ColdBox Modules
“Software is always bound
to change”
THE LEGACY PROBLEM
LEGACY PROBLEM
• Gives CFML a bad name
• Security Issues
• Performance Issues
• Employee Issues
• Development Issues
• Finding Developer Issues
LEGACY PROBLEM
•>35% No MVC
•>60% No DI
•>55% No Testing
FuseBox is NOT MVC
LIKE MY CFML APP?
• MVC Framework or spaghetti hell?
• OO or cfinclude hell?
• Automated Tests? Continuous Integration?
• Agile/Scrum Methodologies?
• Source Control? (Zip files don’t count!)
• Continuous Delivery? Container Strategy?
• Developer Automation?
Monolithic Apps
What do we do?
BACK TO THE SCHOOL OF ARCHITECTURE
1. COHESION - COUPLING
2. MVC
• Separates layers of concerns
• Helps enforce OO
• Specialized team members
• but
• Layers are still tightly coupled
• MVC Monoliths
3. N-TIER - MEXICAN CHALUPA
• Add more layers for organization
• Layers are still tightly coupled
• Still monolithic!
4. HMVC
4. HMVC
• Evolution of MVC
• No more lasagna
• Independent MVCTriads
• Benefits
• Higher Cohesion
• Lower Coupling
• Modularization
• Better Organization
• Reusability
• Extensibility
• Testability
5. MICROSERVICES
AN APPROACH TO DEVELOPING A SINGLE
APPLICATION AS A SUITE OF SMALL SERVICES,
EACH RUNNING IN ITS OWN PROCESS AND
COMMUNICATING WITH LIGHTWEIGHT
MECHANISMS.
Martin Fowler
5. MICROSERVICES
M C
V
M C
V
M C
V
• Make legacy code updates less intimidating
• Fewer resources required to maintain fault
tolerance
• Versionable & maintainable
• Short release cycles
• Monolithic apps can be evolved piece by piece
• Identify -> Break Out -> Scale
5. MICROSERVICES
HMVC Microservices
+
FORMULA FOR SUCCESS
A
FUNDAMENTAL
CHANGE IN
APPROACH OR
UNDERLYING
ASSUMPTIONS.
PARADIGM SHIFT:
MODERNIZE…
Monolithic)
App)
App#Security#
Billing#
Blog#
Cart#
User#
Admin#
EVOLVETO HMVC
MODULARITY
WHAT IS A MODULE?
"In structured design and data-driven design, a module is a
generic term used to describe a named and addressable
group of program statements” 

by Craig Borysowich (ChiefTechnologyTactician)
“A software module is a deployable, manageable, natively
reusable, composable, stateless unit of software that
provides a concise interface to consumers.” 

by Kirk Knoernschild
MODULAR ARCHITECTURE
• Break up a monolithic application
• Individual logical parts that work in unison
• Separation of concerns
• Reusability concerns
• Manageable dependencies
“As a system evolves, It’s complexity will increase unless work
is done to maintain or reduce it.” 

Lehman’s 2nd Law of software evolution
COLDBOX MODULES = SUPER POWERS
• Apply HMVC
• Module = MVCTriad (Self-Contained)
• Addressable
• Composed
• Dependencies
• Runtime Installed
• Reloaded
• Unloaded
Available since v3.0.0 (2011)
COLDBOX MODULES ARE OLD
Available since v3.0.0 (2011)
COLDBOX MODULETRIADS
Host%Application%
Security%
News%
RSS%
eStore%
Admin%
Users% Comments% Posts% Billing%
WHAT DOYOU GET?
• Full MVCTriad
• Automatic WireBox (DI) Mappings
• Automatic CFML Mappings
• Automatic Interceptors
• Overridable Settings
• Environment Detection
Anatomy of a Module
ModuleCong.cfc
handlers
layouts
models
modules
views
Module Name

(unique on disk)
box.json
{
"name":"cbSwagger-shell",
"version":"1.1.0",
"slug":"cbSwagger-shell",
"private":false,
"dependencies":{
"coldbox":"^4.3.0",
"workbench":"git+https://github.com/Ortus-Solutions/unified-workbench.git",
"cbjavaloader":">1.0.0",
"swagger-sdk":">0.0.9"
},
"devDependencies":{
"testbox":"^2.4.0"
},
"installPaths":{
"coldbox":"coldbox/",
"testbox":"testbox/",
"cbjavaloader":"modules/cbjavaloader/",
"swagger-sdk":"modules/swagger-sdk/",
"workbench":"workbench"
},
"testbox":{
"runner":"http://localhost:49616"
},
"scripts":{
"postVersion":"recipe workbench/bump.boxr"
}
}
box.json
MODULECONFIG.CFC
• Simple CFC
• Bootstraps your module
• Must exist in the root of your module folder
• Has public properties
• configure() for configuration
• 2 callback methods: onLoad(), onUnload()
• Tier-detection enabled
• It’s an interceptor too!
MODULECONFIG.CFC
MODULECONFIG.CFC PROPERTIES
// Module Properties
    this.title              = "cbswagger";
    this.author             = "Jon Clausen <jon_clausen@silowebworks.com>";
    this.webURL             = "https://github.com/coldbox-modules/cbSwagger";
    this.description        = "Swagger API documentation from your routes";
    this.version            = "@build.version@+@build.number@";
    // If true, looks for views in the parent first, if not found, then in the
module. Else vice-versa
    this.viewParentLookup   = true;
    // If true, looks for layouts in the parent first, if not found, then in module.
Else vice-versa
    this.layoutParentLookup = true;
    // Module Entry Point
    this.entryPoint         = "cbswagger";
    // Model Namespace
    this.modelNamespace     = "cbswagger";
    // CF Mapping
    this.cfmapping          = "cbswagger";
    // Auto-map models
    this.autoMapModels      = true;
    // Module Dependencies That Must Be Loaded First, use internal names or aliases
    this.dependencies       = [ "swagger-sdk" ];
MODULECONFIG.CFC METHODS
MODULECONFIG.CFCCONFIGURE
function configure(){
        settings = {
            caching = false,
            mailTo = "lmajano@ortussolutions.com"
        };
        layoutSettings = { defaultLayout = "relax.cfm" };
        i18n = {
            resourceBundles = {
                "cbcore" = "#moduleMapping#/i18n/cbcore"
            },
            defaultLocale = "en_US",
            localeStorage = "cookie"
        };
        interceptorSettings = {
            // ContentBox Custom Events
            customInterceptionPoints = arrayToList( [
                // Code Rendering
                "cb_onContentRendering", "cb_onContentStoreRendering"
            ] )
        };
        routes = [
            //Module Root Requests
            { pattern="", handler="Main", action="index" },
            // Convention Route
            { pattern=":handler/:action?" }
        ];
    }
Bonus:
ModuleCong is also an interceptor
box install cors
EXECUTION
FROM URL
Event=[module:][package.]handler[.action]

SES=/module/package/handler/action
Internally
#runEvent( ‘module:users.dashboard' )#
LEVERAGING WIREBOX
• this.autoMapModels = true

• Automatically maps all your models to
• {modelName}@{moduleName}

• property name=“builder” inject=“builder@qb”;
MODULE
Module
Module
Module
Module
Bundle
Module
Module
Module
Module Bundles
Thanks!
Go Modularize!

ColdBox Hierarchical MVC - Transform Your Monolith