Most HTML5 web applications are relatively small scale – they are maintained by a single team and contain relatively little JavaScript, CSS and HTML5 code.
At Caplin we build "thick client" replacement financial trading systems containing considerable business logic implemented by hundreds of thousands of lines of JavaScript code. The code is maintained by multiple development teams spread across multiple business units. The talk describes the problems faced and how they can be solved using componetization, loose coupling, services, event bus, design patterns, BDD, the best open source libraries, test by contract, and test automation etc.
2. What am I talking about ?
What is “enterprise” ?
We have replaced, functionally large diverse,
desktop thick client trading systems with
with “single page” web applications.
How we did it ?
Architectural patterns and technologies used.
Good news for web-devs
http://addyosmani.com/resources/essentialjsdesignpatterns/book/
5. Business Drivers
▶ Increase trade volumes
– Integrate pre-trade information
▶ Reduce cost of sale
▶ Direct channel to customer
– Enhanced user experience
– Branding
▶ Zero deployment: URL to customer
– Reduced onboarding time + cost
– Reduced maintenance
9. The application
▶ “A lot of code” 250k + LOC
▶ Single page “thick client” applications
– Different assumptions
– Runs all day, memory leaks
– UX of lazy loading
▶ Consistency: theming/skinning/UX
▶ Internationalisation
▶ Streaming financial tradable prices
– Screen update performance
– Trade on “displayed price”
– Graceful degradation
– Throttling, scheduling
10. Multiple teams
▶ 10-100’s of developers
▶ Multiple independent teams
– Independent versioned deployment lifecycle
– Share some code
– Rest Isolated
▶ Banks are notoriously silo’d by asset class
11. Different cultures
▶ UX/Graphic designers
▶ Web Developers (jQuery anyone)
▶ Product Owners, Product Managers,
Business Analysts
▶ Server-side developers
– Decouple dependencies
▶ QA’s (programming QA’s)
▶ Operations
– Deploy artifacts
– Same artifacts for TEST/UAT/PROD
– Directory services
Coolness
16. Split by feature, not technology
16
CSS
HTML
JS
config
i18n
images
tests
CSS
HTML
JS
config
tests
images
i18n
CSS
HTML
JS
config
tests
images
i18n
CSS
HTML
JS
config
tests
images
i18n
CSS
HTML
JS
config
tests
images
i18n
17. ▶ Independent business feature
▶ No direct dependencies to other components
▶ Minimal public interface
– Event bus (publish/subscribe)
– Component API
▶ Code sharing mechanism
– Libraries
– Modules
▶ Conforms to conventions/name-spacing
▶ Can be pre-built
What is a component
20. Conways’Law
“Organizations which design systems ...
are constrained to produce designs which
are copies of the communication structures
of these organizations"
22. Inheritance + Name-spacing
▶ CSS
– App defines common “theme”
– Components inherit theme
– Override with more specific CSS rules
• Need name-spacing
– Use CSS pre-processor (e.g. LESS,SASS)
– Define an ontology
▶ XML/HTML
– Name-spacing for unique ID’s
23. JavaScript Coding
▶ Fine grained OO
– We average about 100 LOC per class
▶ One class per file
▶ Design patterns
▶ SOLID (Uncle Bob)
▶ Coding standards
– Inheritance
– JsHint
▶ Common code in libraries
▶ Interpreted: so testing is more important
▶ JsLint /coverage
26. JavaScript Interfaces
▶ Defines the contract a component should
conform to.
– A set of method signatures
▶ Multiple classes “implement” the same interface
▶ Provides a hook for documentation
▶ Hook for IDE tooling
27. Service Registry
var service = new caplin.XhrXmlResourceServiceProvider(this.sXmlBundleUrl);
caplin.ServiceRegistry.register("caplin.XmlResourceService”, service);
var xmlResourceService = caplin.ServiceRegistry.getService("caplin.XmlResourceService");
var tradeModelNode = xmlResourceService.getXmlDocument("tradeModels");
Registration:
Usage:
28. Event Hub
▶ Publish/Subscribe inside the browser
– Many to many (or none)
▶ Defined by an interface (contract)
▶ Methods cannot return anything
▶ Classic example: logging
▶ Nice Article:
http://blog.caplin.com/2012/12/07/event-hub-pubsub-in-the-browser/
29. Component Interface
▶ Used by layout managers to manage GUI
components
▶ Defines GUI lifecycle events
– getElement(),
– onOpen(),
– onResize(),
– onSerialize() etc.
30. MVVM Pattern
ViewRendering to screen
Domain
Model
business semantic method callslistens
Reused across many
screens
View
Model
gestureslistens
Logical representation
of the view
(an adaptor)
31. <button class=‘..’
data-bind=‘click:buttonClicked’>
Execute Trade
</button>
HTML template with bindings
$(button).click(function(){
vm.buttonClicked()
});
jQuery Control
Our HTML5 MVVM
Domain
Model
executeTrade()complete()
Message
Service
send()receive()
View
Model
buttonClicked()tradeButtonEnabled
No DOM Access
XmlHttpRequest
binding framework
e.g. KnockoutJs
32. The Testing Triangle
Functional
GUI testing
ITs
Unit Tests
manual
Acceptance
Tests
Performance
Tests
Integration Tests
- Selenium -
(automated
manual tests)
Unit Tests
manual
Performance
Tests
34. Test by contract
MVVM and services
View
Model
Domain
Model
complete()
View
execute()
Given …
When …
Then …
Fixtures
executeTrade()
tradeButtonEnabled
Message
Service
Stub
send()
receive()
36. In summary:
divide + conquer
Natural fine grained OO coding
Components
Common code in libraries
Split GUI Code into
Dom interactions
View Model
Domain Model
Services for stubbing
GWT + Test by contract
37. We will soon be open-sourcing
our implementation of this
architecture
www.bladerunnerjs.org