Randori design goals and justification

Post on 20-Jan-2015

2.036 views 1 download

description

Problem statement and architectural ideas for approaching large JavaScript projects

Transcript of Randori design goals and justification

WORLDWARECONFERENCE

Randori Design Goals and Justification

Michael Labriola

Page 0 of 59

WORLDWARECONFERENCE

Terminology

In our parlance, the client side of an application looks like this:

Page 3 of 59

Σ

WORLDWARECONFERENCE

Traditional UI Model

The model followed by Flex, Silverlight, GWT, ExtJS and others goes something like this:

Ultimately, it is the developers job to create the user interface through code.

Page 3 of 59

WORLDWARECONFERENCE

Problem 1

The problems with this method were numerous. Most importantly, each time a design change needs to occur, our most expensive resources, developers, needed to be involved.

Page 3 of 59

WORLDWARECONFERENCE

Problem 2

In a world of inconsistent rendering of the user interface, the problem compounds dramatically.

Page 3 of 59

WORLDWARECONFERENCE

Proposed Solution

Many organizations have tried to solve this problem through abstraction and encapsulation

Page 3 of 59

WORLDWARECONFERENCE

Problem 3

This abstraction layer is destined to grow larger over time and you generally pay for the compatibility even if you are not using it

Page 3 of 59

WORLDWARECONFERENCE

Problem 4

There is an inherent lag in the maintenance of the abstraction layer. When a new feature is released, you rarely have immediate access and if there is a bug, you are waiting for an API revision.

Page 3 of 59

WORLDWARECONFERENCE

UI Round Up

Our most expensive resources are involved in the most time consuming process, that requires the most iteration and is the most likely to grow in scope as browsers continue to add features.

Translates to : Death Spiral

Page 3 of 59

WORLDWARECONFERENCE

Business Logic Expectations

In our experience, developers of business logic have different expectations of a language and environment than do UI designers. They expect things like:

– Strong Types– Refactoring Support– Code Completion / Type Assist– Object Oriented– Unit Testing

In general, these developers are used to more mature languages and tools.

Page 3 of 59

WORLDWARECONFERENCE

Contrasted With

From Wikipedia:JavaScript (sometimes abbreviated JS) is a prototype-based scripting language that is dynamic, weakly typed and has first-class functions. It is a multi-paradigm language, supporting object-oriented, imperative, and functional programming styles.

Moock Quote:“The interesting thing about JavaScript is that you can have an apple and a cat.. and you can decide the apple should be able to meow, or that a cat no longer should at any point in the system.. and regardless of who is using the ‘objects’”

Page 3 of 59

WORLDWARECONFERENCE

Proposed Solution

There have been multiple attempts at giving users the ability to cross-compile projects to JavaScript to retain these features. Some have been moderately successful, but all retain the original fatal flaw:

Additionally, cross-compilation techniques that attempt to address UI lengthen the lag between new browser features and/or bug fixes and their use in a project.

Page 3 of 59

WORLDWARECONFERENCE

Cross Compliation

We don’t however believe that cross-compilation is inherently flawed. Its the cross-compilation of UI that causes the problems noted previously.

Cross-compilation of business logic can work quite well, providing for the needs of the business logic developer but allowing for the needed deployment model.

Page 3 of 59

WORLDWARECONFERENCE

Separation of Concerns

The interesting issue is that all of these solutions attempt to solve the problem at the expense of good separation of concerns.

HTML/JavaScript actually natively has a reasonably good separation between visual design and code.

We believe an adequate solution only comes from embracing that ability instead of side-stepping it

Page 3 of 59

WORLDWARECONFERENCE

A Project

This is our view of the time required on any given project, per type of work, adjusted for dealing with multiple rendering targets

Page 3 of 59

WORLDWARECONFERENCE

Tech Choices

Therefore we see the technology choices breaking down into the follow selections.

Page 3 of 59

WORLDWARECONFERENCE

HTML/CSS Justification

HTML/CSS is the native way that browsers use to create and display user interfaces.

There are some complexities which need to be address, including technical challenges such as global ids.

HTML/CSS folks are generally less expensive than core developers and hence there is a significant economy for allowing these resources to handle the most time consuming portion of the process

Page 3 of 59

WORLDWARECONFERENCE

JavaScript Justification

There are some tasks which require understanding of the browser and deep knowledge of the virtual machine in which the code is executing.

JavaScript is the native languages of this environment. Like an assembly language, it should be used for tasks that are ‘close to the metal’ and require this level of interaction.

Attempting to cross-compile this logic, causes the same concerns addressed previously.

Page 3 of 59

WORLDWARECONFERENCE

Business Logic Justification

The business logic of the system should not need to know much about the environment in which it is executing.

If the business logic does have this deep knowledge, we have a problem with separation of concerns.

Business logic can be written in a higher level language, assuming we can abstract away the implementation details through the use of various APIs.

Page 3 of 59

WORLDWARECONFERENCE

Ultimate Design Goal

What we effectively need is appropriate plumbing to allow the business logic, JavaScript and HTML/CSS to work together seamlessly, but allow enough separation that these tasks can be accomplished via separate roles.

Doing so is the primary goal of this design.

Page 3 of 59

WORLDWARECONFERENCE

Primary Concerns

• The system must be extensible• The system must allow dynamic code loading• The system must be able to resolve dependencies

dynamically without manual maintenance• The system must allow large teams to work simultaneously• The system must allow for unit testing• The system must work on both mobile and desktop• The system must be deployable in multiple containers• The system must be able to reuse existing JavaScript

libraries• The system must be fully capable of internationalization

and localization

Page 3 of 59

WORLDWARECONFERENCE

Secondary Concerns

• The system should allow for code coverage analysis• The system should allow for refactoring support• The system should allow for testing with mock objects• The system should allow for 100% business logic test

coverage• The components created for an application should be

reusable to allow for the construction and reusable of libraries

• The system must allow for responsive designs• The core system must be functional on IE7 and greater

Page 3 of 59

WORLDWARECONFERENCE

Use the correct technology for the correct function and use a framework to enforce strict separation of concerns

Proposed Solution

Page 3 of 59

Σ

WORLDWARECONFERENCE

Randori – Seizing Chaos

We just need a safe way to bring them together. We call that way the Randori Enterprise Framework.

It is effectively the lines of the pie chart, rather than the pie chart itself.

Page 3 of 59

WORLDWARECONFERENCE

HTML Pages

The first key to this approach is HTML Pages.

•An HTML page is the visual component of the View•Each HTML page is a complete HTML document, not a fragment

– The HTML page may define style sheets or even scripts which can be used during testing

– When the page is loaded, these elements are stripped so they do not impact the runtime

– Only the body is used at runtime

Page 3 of 59

WORLDWARECONFERENCE

Mediator

Each HTML page can define a mediator. A mediator contains the business logic that runs the view.

•A mediator is written in C#•Like all dependencies, it can be loaded dynamically•Mediators can be associated with an HTML page in two ways

Page 3 of 59

WORLDWARECONFERENCE

Mediator Defined

Mediators can be defined in line via a data-mediator attribute. This attribute causes the appropriate mediator to be loaded (if needed) and instantiated.

Page 3 of 59

HTML Document

package.MyMediator

<!DOCTYPE html><html> <head> <title>My View</title> </head> <body data-mediator="package.MyMediator"> <div id="someContainer"> </div> </body></html>

WORLDWARECONFERENCE

Mediator CSS

Mediators can also be defined in CSS, which has the advantages of cleaner HTML and reconfiguration via CSS

Page 3 of 59

HTML Document

package.MyMediator

<!DOCTYPE html><html> <head> <title>My View</title> </head> <body class="someClass"> <div id="someContainer"> </div> </body></html>

.someClass { -randori-mediator: package.MyMediator;}

CSS Document

WORLDWARECONFERENCE

Mediator View Injection

Mediators gain access to parts of the view by asking for references to be injected. In this way, the layout of the view is separate from the logic of the mediator.

Page 3 of 59

HTML Document

package.MyMediator

<!DOCTYPE html><html> <head> <title>My View</title> </head> <body class="someClass"> <div id="someContainer"> </div> </body></html>

public class MyMediator : AbstractMediator {

[View(required = true)] public jQuery someContainer;

}

WORLDWARECONFERENCE

Mediator Injection

Mediators, like other classes written in C#, can indicate that they require additional classes that need to be injected as properties, methods or via the constructor.

Page 3 of 59

public class MyMediator : AbstractMediator {

[View(required = true)] public jQuery someContainer; [Inject] public UserService service;

}

WORLDWARECONFERENCE

Dependencies

As the C# is compiled, we are able to observe and note dependencies. As such, when MyMediator is requested, we can know that UserService must be load first. This can occur recursively to any depth.

We can do this automatically, without requiring dependencies to be manually noted or maintained.

Page 3 of 59

public class MyMediator : AbstractMediator {

[View(required = true)] public jQuery someContainer; [Inject] public UserService service;

}

WORLDWARECONFERENCE

View/Business Separation

Raw HTML nodes can be injected into the View. When this occurs, you are provided a reference to the node wrapped in jQuery.

However, this leads to bad coupling wherein the mediator does too much visual manipulation. The mediator should be about business logic and only communicate via fully mockable APIs.

Page 3 of 59

WORLDWARECONFERENCE

Behavior

To help enforce this separation, there is a concept of a behavior. A behavior is reusable functionality that manipulates or works within a given HTML node.

•Can be written in C# or JavaScript directly•Intended to provide a clean, ‘close to the metal’ approach where JS devs can work on complex behavior, but expose it to the C# business logic via a known public interface•Any page can have (n) behaviors

Page 3 of 59

WORLDWARECONFERENCE

Behavior Defined

Behaviors can be defined in line via a data-mediator attribute. This attribute causes the appropriate behavior to be loaded (if needed) and instantiated.

Page 3 of 59

HTML Document

package.MyBehavior

<!DOCTYPE html><html> <head> <title>My View</title> </head> <body data-mediator="package.MyMediator"> <div id="someContainer" data-behavior="package.MyBehavior"> </div> </body></html>

WORLDWARECONFERENCE

Behavior CSS

Behaviors can also be defined in CSS, which has the advantages of cleaner HTML and reconfiguration via CSS

Page 3 of 59

HTML Document

package.MyBehavior

<!DOCTYPE html><html> <head> <title>My View</title> </head> <body class="someClass"> <div id="someContainer“ class=“otherClass”> </div> </body></html>

.someClass { -randori-mediator: package.MyMediator;}

.otherClass { -randori-behavior: package.MyBehavior;}

CSS Document

WORLDWARECONFERENCE

JS/C# Mapping

On the C# side, we can create compile-time constructs that define the contents of an external library.

For example, here is a snippet of code that defines part of the Google Crypto library

Page 3 of 59

[JsType(JsMode.Prototype, Name = "CryptoJS", Export=false)] public class CryptoJS {

public static Encodings enc;

public static Hash SHA256(JsString message, JsObject options = null) { return null; }

public static Hash MD5(JsString message, JsObject options = null) { return null; }

WORLDWARECONFERENCE

JS/C# Mapping

This code is only used during development to ensure static type checking, provide code hinting, etc. It simply provides a definition for a class that will be available at runtime.

The actual Crypto library is written in JavaScript. Through this technique, we can use any existing library written in JavaScript, but use it from our C# code… and mock it during testing.

Page 3 of 59

WORLDWARECONFERENCE

Some Existing Libraries

• jQuery• KnockoutJS• KendoUI• PhoneGap• Sencha-Touch• jQueryMobile• jQTouch

• ExtJS• TinyMCE• QUnit• jQueryUI• Raphael• KineticJS• SignalR

Page 3 of 59

WORLDWARECONFERENCE

Behaviors

This same capability allows our behaviors to be written completely in JS where performance and/or code reuse benefits us, however, each of these interfaces is then available to the mediator.

Page 3 of 59

WORLDWARECONFERENCE

Behavior/Mediator Injection

When a behavior is defined for a node, the Mediator is given access to the behavior instead of the node. Through this model, we keep the mediators focused on logic.

Page 3 of 59

HTML Document

package.MyMediator

<!DOCTYPE html><html> <head> <title>My View</title> </head> <body data-mediator="package.MyMediator"> <div id="someContainer" data-behavior="package.MyBehavior"> </div> </body></html>

public class MyMediator : AbstractMediator {

[View(required = true)] public MyBehavior someContainer;}

package.MyBehavior

WORLDWARECONFERENCE

Randori Enterprise Framework

This begins to build the core of the page based model

Page 3 of 59

HTML/CSS View

Mediator

Model

Notifications

Services

Behavior

JQuery

User Defined Objects

WORLDWARECONFERENCE

Randori Provides

• A dependency injection model for dealing with business dependencies

• A injection model for accessing view components• A mediator pattern to act upon HTML views• A strongly typed environment for all business logic

construction• Dynamic loading and dynamic resolution of dependencies• A defined behavior pattern for augmenting and creating ad-

hoc components• CSS Parsing and decoration for responsive design• G11n support• Templating Engine• Templates capable of WYSIWIG editing

Page 3 of 59

WORLDWARECONFERENCE

Randori Stack

• Randori has compile time and runtime dependencies.

Page 3 of 59