Model concepts – a graphical design tool for our models

This project is also hosted on GitHub. To get a local copy open your Git bash terminal, go to the folder where you want to store the code and issue the following command:

git clone git://github.com/dzenanr/model_concepts.git

After a few seconds, the model_concepts folder is created. It contains the whole project. Open the folder in Dart Editor to get a feel of how it is constructed. It is a web app containing the script tag <script type="application/dart" src="model_concepts.dart"></script> and it starts the Dart VM with model_concepts.dart. When you run the app, the graphical designer appears in Chrome (Dartium). If you want to run it in another browser without Dart VM, first generate the JavaScript version through Tools | Generate JavaScript, and then paste the URL in the address window of your favorite browser (something like http://127.0.0.1:3030/F:/git/model_concepts/web/model_concepts.html). The web folder contains the HTML file and the startup script model_concepts.dart, which contains the following code snippet:

import 'dart:html';
import 'package:model_concepts/model_concepts.dart';          (1)

void main() {
  // Get a reference to the canvas.
  CanvasElement canvas = document.query('#canvas'),           (2)
  Board board = new Board(canvas);                            (3)
}

Line (1) loads in the model_concepts library from the packages folder; the original source code of the library resides in the lib directory. The library header file, also called model_concepts.dart, shows the dart libraries that we need (html, async, and convert) as well as all the part files:

library model_concepts;

import 'dart:html';
import 'dart:async';
import 'dart:convert';


part 'board.dart';
part 'box.dart';
part 'item.dart';
part 'json_panel.dart';
part 'line.dart';
part 'menu_bar.dart';
part 'png_panel.dart';
part 'tool_bar.dart';

This app uses canvas painting in HTML5 (we'll explore that bottom-up in the coming chapters). In line (2), the <canvas> tag with the ID canvas is bound to a canvas object of the CanvasElement class. Then in line (3), an object of the Board class (the file board.dart) is instantiated with a reference to this canvas, starting up the program.

Tip

We shall not provide further explanation of how the code works here. The app was built up in versions (called spirals, so far there are 14). On the On Dart blog (http://dzenanr.github.io/), under the Magic Boxes posts, you can find a detailed description of how the code evolved from Spiral s00 to the current app (magic boxes grew into model concepts), along with a summary of the development on http://goo.gl/DqF7d. This is a truly great way to learn Dart!

When the app starts up, we see the following screen:

Model concepts – a graphical design tool for our models

Model concepts start screen

Working with model concepts

The purpose of this tool is to graphically design a domain model of your app. Concepts or entities are drawn as rectangular boxes; these contain items that represent the attributes. The boxes are connected with lines that represent the relationships between the entities; their multiplicity (that is, how many entities of kind B are associated with an entity of kind A, for example, many employees working in one department) can be indicated with 0..N or 1..1. The tool itself contains a (tiny) user guide, which is revealed on scrolling down the screen.

Explaining the model

We will learn how to work with this tool by designing the model for our next app: the category-links application. This app is all about subjects (called categories here) such as HTML5, Dart, Apple, Google, Programming, the economic crisis, and hyperlinks (called links here) to web postings about these subjects. Here are some examples of links for HTML5: www.html5rocks.com, http://diveintohtml5.info/ and http://animateyourhtml5.appspot.com/. Clearly, a category can have multiple links but it may also have none; so, the relationship from category to link is 0..N.

Our app (that will be developed in Chapter 8, Developing Business Applications with Polymer Web Components) will show all categories and the corresponding links for each category. Furthermore, we will be able to edit, remove, and add categories as well as links. But first we will draw a model with two concepts (Category/Link) and one relationship (links). It will look like the following figure:

Explaining the model

The graphical model of category-links

The category concept has two attributes: a code (name) such as Dart and a description such as Web programming language, tools, and how to. The code attribute is drawn in italics because it is an identifier and in bold because its value is required. The link concept has the code identifier, the required URL attribute, and an optional description attribute. For example, the URL for Dart could be www.dartlang.org and the description could be Official Google site for Dart. In our model, a link has exactly one category, so a 1..1 relation is applied (this is, a simplification of a more realistic situation where a link could belong to many categories). A relationship between two concepts has two directions (neighbours). The category-link direction, where Link is a neighbor of Category, has a min cardinality of 0 (a category need not have any link) and a max cardinality of N (many). In addition, it has the link's name. The link-category direction has no name. Hence, it will not be represented explicitly in Dart; its min and max cardinalities are in bold and italics. Together with the code, it is the identifier of the link (note that 1..1 is in italics and bold). Within the same category, all links must have a unique code value. Category is the only entry (|| as a door) into the model. This means that the model will have a collection of categories and each category will have a collection of links.

Drawing the model

The steps to draw a model are given as follows:

  1. Click on the box tool icon in the tool bar (brown background, refer to the model concepts' start screen) and create a box for the category concept by clicking on an empty space in the board.
  2. Click on the box to select it (four squares appear in the corners) and click again to deselect it. The selected box is displayed in the tool bar and you can enter the name Category for it in the concept field of the tool bar. The name will not appear in the selected box until you use the Enter key.
  3. Check the entry checkbox; Category is marked with ||. To move a box, select it and keep the mouse down while moving it. If there are connecting lines, they will follow.

The size of selected boxes may be changed by menu items in the View menu. If you want to create several boxes, double-click on the box tool to stay active. To return to the select mode, double-click on the select tool.

A box item (an attribute of a concept) may be created by entering its name in the attribute field of the toolbar and by using the Enter key.

  1. Select the identifier from the drop-down list; the default type String is ok. Enter code and the item appears in the Category box. Repeat the steps for the item description, but select the attribute from the list.
  2. Now design the link concept with its attributes, and mark the URL attribute from the list as per your requirements.
  3. Click on the line tool to create a line between the last two clicked boxes by clicking on an empty space in the board.

The first box is a parent and the second box is a child. By default, the parent box has 0..N cardinalities. The min is 0 and the max is N. By default, the child box has 1..1 cardinalities. For more details, see the tiny user guide in the program screen beneath the brown toolbar.

  1. To make a PNG image from our model, scroll down to the To image button above the PNG panel and click on the button. The created image becomes visible in the panel; right-click to save it to a file (Save Image as) or copy (Copy Image) and paste it into another file (for example, as documentation).
  2. Name the current model in the Model menu as Category_Links and save it in the local storage of your browser (we will see how this works in Chapter 11, Local Data and Client-Server Communication). In a later session, simply enter the model name (it is case-sensitive!) and open it.

Exporting the model

Drawing the model clarifies our thoughts about it, but it won't be of much use if we can't get to code from it. We can export the semantics of a model (only the non-hidden boxes and lines) in the JSON format by clicking on the From model to json button above the JSON panel. After doing this, the JSON text appears in the JSON panel; copy it and save it into a local text file category_links.json. It also works the other way around: the JSON text may be used to recreate the graphical model in magic boxes. Paste the JSON text from a previous model into the JSON panel and click on the From json to model button to visualize the model. For a pretty JSON version of the model, click on the Pretty json button, but only after clicking on the From model to json button. Open the .json file in a text editor and see how the information about our model is contained in it:

{
    "width":990,
    "lines":[
        {
            "box2box1Max":"1",
            "box1Name":"Category",
            "box1box2Min":"0",
            "box2Name":"Link",
            "box1box2Id":false,
            "box2box1Id":false,
            "box2box1Name":"",
            "box1box2Max":"N",
            "box1box2Name":"",
            "box2box1Min":"1",
            "category":"relationship",
            "internal":true
        }
    ],
    "height":580,
    "boxes":[
        {
            "width":120,
            "entry":true,
            "name":"Category",
            "x":125,
            "height":80,
            "y":63,
            "items":[
                {
                    "sequence":10,
                    "name":"code",
                    "category":"identifier",
                    "type":"String",
                    "init":""
                },
                {
                    "sequence":20,
                    "name":"description",
                    "category":"attribute",
                    "type":"String",
                    "init":""
                }
            ]
        },
// omitted analogous entry for link
    ]
}

What is JSON?

JSON (JavaScript Object Notation) is a simple text format (easy to be read and written by humans and machines) for representing structured objects and collections, and exchanging data between applications or computers. For example, when a client sends data to or receives data from a server through a web service, this data is often in JSON format. It arose from the open source world, more or less as a competitor to the heavier XML format; but it is used everywhere now. Any production language has special functions (in library dart:convert) to make it easy to use, Dart being no exception. Let us examine a simple JSON example and see how it connects to list and map: look at the BankAccount object from banking_v3.dart (Chapter 2, Getting to Work with Dart):

var ba1 = new BankAccount("John Gates","075-0623456-72", 1000.0); 

It contains three data items: the owner, the number, and the balance of the account. The JSON representation of this data (object) is:

{
    "owner": "John Gates",
    "number": "075-0623456-72",
    "balance": 1000.0
}

In a Dart app, this could be typed as a multiline string (see line (1) in json.dart at codechapter_3). Looking at it from the Dart perspective, this is a map where the names of the object properties are the keys and the values are the map's values; there is a close relationship between objects and JSON (hence the name). This object notation can be nested (for example, the owner could be an object itself with a name, address, and telephone number). To express that there are many of these objects, you can use the [ ] notation, as in the following code snippet:

[
  {
      "owner": "John Gates",
      "number": "075-0623456-72",
      "balance": 1000.0
  },
  {
      "owner": "Bill O'Connor",
      "number": "081-0731645-91",
      "balance": 2500.0
  }
]

This effectively corresponds to a list of maps in Dart.

You can encode a Dart object into a JSON string with the JSON.encode() function from the dart:convert library, for example, the bankAccounts variable in line (2). The resulting JSON can be sent over the network, or it could be the return value of a call to a web service. The Dart object to encode needs to be of the type null, bool, int, double, String, List, or Map; any other object needs to have a toJson() method that is called when encoding. The other way around, decoding a JSON string into a Dart object is done with the JSON.decode method (see line (3) in json.dart):

import 'dart:convert';

var jsonStr1 = '''                                             (1)
{
    "owner": "John Gates",
    "number": "075-0623456-72",
    "balance": 1000.0
}
''';
var jsonStr2 = '''
[
  {
      "owner": "John Gates",
      "number": "075-0623456-72",
      "balance": 1000.0
  },
  {
      "owner": "Bill O'Connor",
      "number": "081-0731645-91",
      "balance": 2500.0
  }
]
''';
var bankAccounts = [{ "owner": "John Gates","number": "075-0623456-       72",
                      "balance": 1000.0 },
                    { "owner": "Bill O'Connor", "number": "081-       0731645-91",
                      "balance": 2500.0 }];
main() {
  // encoding a Dart object (here a List of Maps) to a JSON string:
  var jsonText = JSON.encode(bankAccounts);                    (2)
  print('$jsonText'), // all white space is removed
  // decoding a JSON string into a Dart object:
  var obj = JSON.decode(jsonText);                             (3)
  assert(obj is List);
  assert(obj[0] is Map);
  assert(obj[0]['number']=="075-0623456-72");

  var ba1 = new BankAccount("John Gates","075-0623456-72", 1000.0);   
  var json = JSON.encode(ba1);                                   
}

class BankAccount {
  // other properties and methods ...
  String toJson() {
    return '{"owner":"$owner", "number":"$number", "balance: "$balance"}';
}

In the previous section, data were exported from model concepts in the JSON format and this data can be imported in the domain model framework Dartling (see Chapter 9, Modeling More Complex Applications with Dartling) in order to generate the code for it. We will use JSON again as the format to store data in, or to send data to the server, in some of the forthcoming projects. In the dartlero_tasks project of Chapter 12, Data-driven Web Applications with MySQL and MongoDB, we will read and write the JSON files. For a more in-depth look, refer to http://en.wikipedia.org/wiki/JSON.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.141.7.240