Building a digital watch using DSM: Part 2 – Putting it all together
Editor’s Note: Excerpted from their book Domain Specific modeling: Enabling Full Code Generation, the authors use a fictitious digital watch company to demonstrate the advantages of domain specific modeling by showing how to build a DSM model generator to create digital watch applications. In Part 2 they show the rules and notations necessary, various use scenarios, and a possible watch metamodel.
Having a language that could specify watch applications brought us back to our starting point at the beginning of Part 1 in this series: Secio wanted to compose a product family of watches out of watch applications. One part of each watch would thus clearly be a list of the applications it contained, for example, Time, Stopwatch, and Alarm.
A watch would not just be a jumble of applications though: the user would cycle through the applications in a certain order. At first, we thought this would be represented as a collection property, to which the modeler could add the desired watch applications. The idea of the cycle, however, gave us the idea of representing this graphically. Since we had already considered the possibility of having layered state machines for the watch application -- a 'state' in an application could decompose to a sub-application -- we hit on the idea of using the same watch application modeling language to specify application composition.
This approach brought several benefits. First, it reduced the number of concepts the modeler would have to learn. Second, it gave the modeler more freedom in deciding how many levels the models should be divided up into: if a watch had only one application, for example a stopwatch, the watch could point directly to the stopwatch, rather than having to specify an intermediate level with a single stopwatch application.
Similarly, if a given application became too large for a single graph, or if parts of an application could be reused in other applications, they could be separated out into their own sub-applications on as many levels as seemed appropriate. Third, it allowed the possibility of more freedom at the application composition level: rather than restricting all watches to always move between their applications in a fixed cycle, the choice of which application to go to next could be as complicated as the modeler desired. An example model is shown in Figure 4.
Figure 4: logical watch as a cycle of applications
While one part of a member of the product family of watches would thus specify the behavior of the watch, a second part was needed to specify the physical details of the watch. Mostly these would be the domain of an industrial designer, but the behavioral part would also need some of that information. In particular, if we wanted to generate a Java applet as a watch emulator, we would need to know three things: the buttons on the watch, the icons it had, and the number of digit pairs it could display.
The first two could in theory have been found by trawling through the set of applications and including all referenced buttons and icons, but this was not how we wanted things to work. We wanted a stopwatch application, say, that used 'up', 'down', and 'mode', to be usable in a watch without a mode button, for example one containing only the stopwatch application. Similarly, rather than have an error if an application tried to turn on an icon that was not present in the physical watch, we would simply do nothing at that point. This made the watch applications more reusable, and allowed the application modeler to concentrate on the application itself, without having to know beforehand the exact details of the physical watches in which it would be used.
We decided to call a member of the product family a watch 'model' -- 'model' being used in the sense of 'a Corvette is a car model', rather than 'a graphical model of a car'. Each watch model had a logical watch, which pointed to the graph showing the cycle through the watch’s applications, and a display corresponding to the relevant parts of the physical watch body: icons, digit pair zones, and buttons. The logical watches and displays would thus form components, and each might be used in more than one full watch model.
As these concepts were different from those used in the watch application modeling language, it was clear that we actually had a new modeling language here. We decided to make it graphically rather verbose, for pedagogical rather than practical reasons. Each watch model (rounded rectangles with a light green fill) showed the display and logical watch it used, and the sets of possible logical watches and displays were also shown in the same diagram (Figure 5).
Figure 5: Watch family diagram
Another possibility here would have been to use a matrix representation rather than a graphical diagram. In models shown as matrices, the axes contain objects and each cell contains the relationship (if any) between the corresponding objects. The logical watches could thus be listed down the left side of the matrix and the displays across the top. The cell at the intersection between a given logical watch and display would then represent a possible watch model composed of those parts. The relationship’s name would be the name of the watch model and would be shown in the cell. Figure 6 shows how this would provide a useful visual overview of which potential combinations of logical watches and displays had been used, how often each logical watch and each display had been used, and which potential combinations remained as possible openings for new products. The matrix format would also collect the watch models, logical watches, and displays together into their own areas, without the rather clumsy group symbol of the graphical diagram.
Figure 6: Watch family as a matrix