Organising Your Code

BladeRunnerJS allows you to construct apps as independent modules called blades.  This page helps you understand how the modular structure works, as well as when and how to share resources between blades.

Note: In some cases, there are no absolute right and wrong ways to do things; it's up to use your judgment and design skills to invent the best solution for your requirements.

General Guidelines

You can put your code in one of four places: a library, an aspect, a bladeset or a blade. Your aim should be to have as much code as possible inside the blade. If you find that you need to share code between blades, then move the shared code into their parent bladeset. Bladesets are designed to be independent of the app in which they run, so if you want to share code between bladesets, you’ll have to put it in a library.

Code within an aspect can only be used from inside that aspect, so you couldn’t  access it from another aspect, bladeset, or blade. Because of this, code in an aspect is generally limited to bootstrapping and configuring the aspect’s behaviour. It will reference blades, create service implementations used by the blades, initialise the layout manager and define global UI skins and themes.

The bulk of your code should be in blades and bladesets, with only a small percentage in aspects.

Shared Resources

Resources are shared through the service architecture. For example: imagine an app in which several blades need access to a remote server that provides product data. First, define an interface with the appropriate method signatures. If all the blades that need to use it are from the same bladeset, put the interface code in that bladeset.  If not, you’ll have to put it in a library.

In the aspect, the code that bootstraps the application will create an instance of the code that implements the interface. Note that the code in the blade doesn’t dependent on the implementation, only the interface definition. The service implementation can then exist in one of the following locations, depending on where it will be used:

  • An aspect: If the code is only going to be used by one aspect, it can be housed in that aspect.
  • A bladeset: If the code is only to be used by blades within a single bladeset, house it in the bladeset.
  • A library: If code needs to be globally available, house it in a library.

Inter-blade communication

Although blades are intended to be as independent as possible, they do sometimes need to talk to each other, when an event in one blade needs a response from another.  For example, clicking a row in a grid might cause a trade-ticket to pop up.  This communication is provided by the Event Hub.  As far as the Event Hub is concerned, blades can be either event sources (which is to say that they publish events to the Hub), or event sinks (i.e. they subscribe to events from the hub, and receive them).  As described in the event hub documentation, events are defined using interfaces. You just define the interface and put it in the appropriate place, using the same rules as for service interfaces.

What should go in a blade?

This is rather like the object orientated programming conundrum, “how big should an object be?”, which has a certain amount in common with “how long is a piece of string?”. There is no hard and fast answer. You’re trying to find a balance between blades that are too small, and which end up with a morass of dependencies; and blades that are too big to be easily re-used, and which don’t have a clearly defined purpose.

The way to approach it is to try to divide your app into individual features; discrete pieces of functionality that an end user could readily identify.  We usually try to implement each component as a single blade.

Having divided it up, you should try to make sure that each module is as self-contained as possible, with dependencies kept to a minimum.  This way, blades can be re-used elsewhere, without having to drag lots of excess code with them.

Themes and styles

The basic styling for an app (the CSS for fonts, background colour, highlighting and so forth), should be provided in the aspect, and blades should be written so that they inherit that styling. CSS from the aspect is included after the CSS from the blades themselves, so the aspect-level CSS take precedence. If you wish to make sure a style from the blade is applied, then use a more specific CSS selector.

For example: at the aspect level, you could define the general background colour in a stylesheet.

body { background-color: white; }

In the blade, you would then create an HTML element with a class attribute of myblade, and define another background colour in the stylesheet.

.myblade { background-color: red; }