Designing Models in JavaScript
Tags: design, model, javascript, uml
Published: 2018-01-28 12:57:49

---
title: Designing Models in JavaScript
published: true
description: A new approach for designing models in JavaScript
tags: design, model, javascript, uml
cover_image: https://thepracticaldev.s3.amazonaws.com/i/2htoyter84unqx7yzrst.jpg
---

My grand-mother was a *brodeuse*, french name for embroiderer. She made beautiful [traditional clothes](https://en.wikipedia.org/wiki/Breton_costume) for my family that we keep preciously. Recently when cleaning her home, we found a treasure, the patterns she used for creating her clothes. She used to draw her patterns on big, large papers. We could clearly understand the kind of clothes she wanted to do by looking at the patterns.

I could stop myself making an analogy with our work. **We avoid too many times this fundamental step of design when developing**. We start coding before designing the model of our application just because we think the code is the model. And it is not. **The code is just the fabric of which the application is made**. By reading the code, we only could guess what model, patterns were used to create the application. Moreover, because we are human, because our way of thinking differ from one developer to another developer, we need also to understand the mental space organization that the developer had when she/he was coding. And it is not that easy.

##Separation of concerns

That is why no matter the frameworks you use and the code you write, the most important is the model that you define to create your application. And this **model do not have to be in the code**. **It has to be** somewhere else, **normalized in a human readable format**. But what format? We could use [UML](http://uml.org), it is quite common now and there are many design tools that use it. But the problem is that it is not a format, it is a language. It is quite complex and not so human friendly when you need to understand a diagram. I know that UML diagrams can be saved in [XMI](https://fr.wikipedia.org/wiki/XML_Metadata_Interchange) format but it is for machine not human.

##Create the schema of the model

Let’s find the format we need with an example. Lets say we want to create a model of a *Jedi*. A *Jedi* is defined by its *first name* and its *last name*, she/he has got a *mother* and a *father*, and can have children. Let’s say we **put all these informations related to this model into a JSON file**, we could have something like that:

```json
{
  "_name": "Jedi",
  "firstName": "property",
  "lastName": "property",
  "mother": "link",
  "father": "link",
  "children": "collection"
}
```

When reading this JSON, we easily understand that:

* a Jedi has two **properties**, *firstName* and *lastName*,
* a Jedi is **linked** to a *mother* and a *father* and
* a Jedi has a **collection** of *children*.

This JSON is in fact the **schema** of our model.

##Generate the model and extend it

It would be great to be able to define a model like that, right? Now we have this schema, let’s go further. And what if we could **generate UML class diagrams from the model** to get something like this:

![model](https://thepracticaldev.s3.amazonaws.com/i/a672irh1rrhifcsaf4jx.png)

In order to do that, we are missing some basic informations, like the type of the properties. How to do this with our file? By simply **generating a complete model with default values from the schema and then edit it**:

```json
{
  "_name": "Jedi",
  "firstName": {
    "type": "any",
    "readOnly": false,
    "mandatory": false,
    "default": ""
  },
  "lastName": {
    "type": "any",
    "readOnly": false,
    "mandatory": false,
    "default": ""
  },
  "mother": {
    "type": "Component",
    "readOnly": false,
    "mandatory": false,
    "default": ""
  },
  "father": {
    "type": "Component",
    "readOnly": false,
    "mandatory": false,
    "default": ""
  },
  "children": {
    "type": ["Component"],
    "readOnly": false,
    "mandatory": false,
    "default": []
  }
}
```

We have here all informations defined in the *schema* that we can edit in a human readable format. For example, for *firstName* we can set its *type* (that has for default value *any* which means that it can have any type) to *string*.

From this JSON it will be easy to generate a UML class diagram. We have a complete *model* to build the application.

##Use the model at runtime

Now what about the code? In [Model Driven Architecture approach](http://www.omg.org/mda/), we generate code from the model, generally from UML diagrams. It is great, but not perfect because the model we have defined has higher risk to be desynchronized from the code. So how to avoid this? By simply **using the model definition of the application at runtime**. **The application has to read the schema and the model that we defined to create the classes, methods and components of the model**.

Yes, seems pretty cool, but how do I do to implement the methods if it is generated at runtime? To do that **you need to [think in systems](https://dev.to/ecarriou/designing-systems-17po)**. **A method is just an action that the system does when reacting to an event**. 

In our case, let’s say we need to have in *Jedi* a method to get her/his full name. So we will edit the **schema** to have something like this:

```json
{
  "_name": "Jedi",
  "firstName": "property",
  "lastName": "property",
  "mother": "link",
  "father": "link",
  "children": "collection",
  "fullName": "method"
}
```

We have added *fullName* **method** in the *schema*. So we will have in the generated model:

```json
{
  "_name": "Jedi",
  "firstName": {
    "type": "any",
    "readOnly": false,
    "mandatory": false,
    "default": ""
  },
  "lastName": {
    "type": "any",
    "readOnly": false,
    "mandatory": false,
    "default": ""
  },
  "mother": {
    "type": "Component",
    "readOnly": false,
    "mandatory": false,
    "default": ""
  },
  "father": {
    "type": "Component",
    "readOnly": false,
    "mandatory": false,
    "default": ""
  },
  "children": {
    "type": ["Component"],
    "readOnly": false,
    "mandatory": false,
    "default": []
  },
  "fullName": {
    "params": [
      {
        "name": "param",
        "type": "any",
        "mandatory": false,
        "default": null
      }
    ],
    "result": "any"
  }
}
```

By default *fullName* takes one optional parameter and can return a value of *any* type. Now let’s say we want to implement the method. How to do that? By simply **adding a behavior when the fullName event is send**:

```js
// require the Jedi class
const Jedi = runtime.require('Jedi');
// add a behavior
Jedi.on('fullName', () => this.firstName() + ' ' + this.lastName());
```

And when this event is send? When *fullName* method is called in the code. In fact this method has been generated from the model, and when we invoke it, it just send a synchronous *fullName* event. The existing behavior related to that event will be then executed.

Now if we change the model of the method, it will never override its behavior.

##Conclusion

Here are the different steps to follow when designing a model:

![process](https://thepracticaldev.s3.amazonaws.com/i/fmqgmkkgpxelwpzq61xb.png)

* **Define your model at high level in a human readable format**.
* A model will be generated from that schema.
* **Edit the generated model** to specify the types, default values, … of your model.
* **Use this model to create at runtime classes, methods and components of your model**.
* **Architecture your application with an event-driven approach to add behaviors to the methods**.
* **Use your model to generate UML class diagrams**.

If you want to see a concrete use of this approach, you can have a look at two of my projects:

* [System Runtime](https://github.com/design-first/system-runtime), a JavaScript library to run and manage systems and
* [System Designer](https://github.com/design-first/system-designer), a web IDE to design systems

that use deeply this methodology. For that purpose I have created the [**MSON** format](https://designfirst.io/systemruntime/documentation/docs/en/design-your-model.html#defining-your-model) (for *Metamodel JavaScript Object Notation*) to define models in a human readable format. But it is not the only possible implementation of this methodology, find the one that matches your needs.

___

*Credits: cover image by [Christian Kaindl](https://unsplash.com/@christiankaindl).*