Document not found! Please try again

Domain-Specific Modeling For Full Code Generation

2 downloads 0 Views 3MB Size Report
Configuration scripts and parameters. 2. Phone switch services. CPL, Voice XML, 3 GL. 2, (4). eCommerce marketplaces. J2EE, XML. 2, (4). Automation network.
Creating Domain-Specific Modeling Languages that Work: Hands-on

Juha-Pekka Tolvanen

© MetaCase/JPT

1

Schedule  9:00 Introducing Domain-Specific Modelling – –

Where to apply – and why Real life examples from various domains

 9:40 Building modelling languages – –

Identifying language concepts Group work

(10:30-11:00 Coffee)

 12:30 Lunch  14:00 Group work continues –

Language rules, notation, model reuse

(16:00-16:30 Coffee)

 16:30 Building code generators – –

Patterns for generators by type of output Adding a Domain Framework

 17:40 Questions & discussion  18:00 End © MetaCase/JPT

2

What is Domain-Specific Modelling? Why do we need something new? Introducing Domain-Specific Modelling (DSM) Where to apply – and why Real life examples Industrial experience reports

© MetaCase/JPT

3

How has productivity improved?  "The entire history of software engineering is that of the rise in levels of abstraction" Grady Booch

 New general purpose programming languages have not increased productivity  UML and visualization of code have not increased productivity  Abstraction of development can be raised above current level...  ... and still generate full production code *Software Productivity Research & Capers Jones, 2002 © MetaCase/JPT

4

How do we use models? Separate model & code

CASE

Model

Model

Code

Code

?

Finished product

?

Finished product

Code Roundtrip visualization

MDA®

DSM

'Model'

'Model'

Model Model Model 2n

Model

Code

Code

Code

Code

Finished product

Finished product

Finished product

Finished product

 Model alone should be sufficient in most cases – No need to look at code © MetaCase/JPT

5

Domain Idea

Solve problem in domain terms

Modelling functionality vs. modelling code Map to code, implement

Map to code, implement

Finished Product

Code

Generate, Add bodies Map to UML

No need to map!

© MetaCase/JPT

Assembler

Model in DSM language

UML Model

Generate code

Domain Framework

6

Example: Digital wristwatch Domain Idea

 Product family – Models: His, Hers, Sport, Kid, Traveler, Diver…

Finished Product

 Reusable component applications – Time, Alarm, Timer, WorldTime, StopWatch…

 Hide complexity from modeller – Model-View-Controller separation – Separate thread for real-time display

 Implementation in Java – Also in MIDP and in C

No need to map!

© MetaCase/JPT

Model in DSM language

Generate code

Domain Framework

7

What is domain-specific modelling  Captures domain knowledge (as opposed to code) – – – –

Raise abstraction from implementation world Uses domain abstractions Applies domain concepts and rules as modelling constructs Narrow down the design space

 Leverages in-house expertise to build automation – Best developer defines modelling language and generators

 Lets developers design products using domain terms  Apply familiar terminology  Solve the RIGHT problems  Solve problems only ONCE! – directly in models, not again by writing code, round-trip etc.

© MetaCase/JPT

8

Why is the vision possible (now)?  Need to fit only one company’s requirements! – Focus on single range of products

 Modelling is Domain-Specific – Works for one application domain, framework, product family etc. – Language has concepts people are already familiar with – Models used to solve the problem, not to visualize code

 Generator is Domain-Specific – Generate just the code needed from models • Efficient full code • No manual coding afterwards • No reason for round-tripping

– Generator links to existing primitives/components/platform services etc. – Can generate 3GL, Assembler, object-oriented, XML, etc. © MetaCase/JPT

9

Where to apply?  Repetitive development tasks – Large portion of the work similar to earlier products (or several products made in parallel)

 Domain expertise needed – Non-programmers can participate

 These normally include: – – – – –

Product Family Platform-based development Configuration Business rule definitions Embedded devices

© MetaCase/JPT

10

What is Domain-Specific Modelling? Why do we need something new? Introducing Domain-Specific Modelling (DSM) Where to apply – and why Real life examples Industrial experience reports

© MetaCase/JPT

11

Case: Insurance products & eCommerce  Developing portal for insurances and financial products  Need to specify several hundred financial products  Insurance experts visually specify insurance products and generate code to the portal  Comparison to hand-writing Java after first 30 products = DSM at least 3 times faster, fewer errors

© MetaCase/JPT

12

© MetaCase/JPT

13

© MetaCase/JPT

14

Case: VoiceMenu for microcontroller  Home automation system to remote control lights, heating, alarms, etc.  VoiceMenus are programmed straight to the device with assembler-like language (8bit)  Modelling language to define overall menu structure and individual voice prompts  Code generator produces 100% of menu implementation  Development time for a feature from a week to a day!

© MetaCase/JPT

15

© MetaCase/JPT

16

© MetaCase/JPT

17

What is Domain-Specific Modelling? Why do we need something new? Introducing Domain-Specific Modelling (DSM) Where to apply – and why Real life examples Industrial experience reports

© MetaCase/JPT

18

Let’s look at industry experience: Some reported cases  Nokia; Mobile Phone product line  Bell Labs / AT&T / Lucent; 5ESS telecommunications switch,  EADS: Tetra terminals  Panasonic: embedded UI  Honeywell; embedded software architectures  Polar Electro: heart rate monitors  ORGA; SIM toolkit & JavaCard  Pecunet; B2B E-Business: insurance  LexiFi; mlFi, financial contracts  DuPont; Activity Modelling  NASA; Architecture Definition Language  NASA ASE group; Amphion  NASA JPL; embedded measurement systems  USAF; Message Transformation and Validation  …  See reported cases at www.DSMForum.org © MetaCase/JPT

19

Experiences from practice "5-fold productivity increase when compared to standard development methods" "A module that was expected to take 2 weeks now took 1 day from the start of the design to the finished product" "The quality of the generated code is clearly better, simply because the modelling language rules out errors, eliminating them already in the design stage" "Eliminated our need to software development activities" © MetaCase/JPT

outsource

20

Productivity increase from DSM

* Productivity proportional to earlier practice © MetaCase/JPT

21

Detailed comparison studies  Panasonic (Safa, 2007) Creating DSM solution

Coding

Product 1 Product 2 DSM

Product 3 Product 4 0

5

10

15

20

 Polar (Kärnä et al., 2009)

25

DSM

5

10

15

20

35

Product 5

Days

Coding

0

30

25 Days

Creating DSM solution Product 1 Product 2 Product 3 Product 4 Product 5 Product 6 Product 7

 Language workbenches make moving to DSM feasible – Can focus on language design, not on creating tooling © MetaCase/JPT

22

What engineers say: DSM solution development time "I could define a domain-specific language in about six hours - design, testing and one failed trial included," Laurent Safa "Creation of the DSM solution took 60 hours, covering the development of the modeling language and the code generator", Juha Kärnä "It's easy to make modifications when the AUTOSAR version is changed--implementation and testing requirements are both reduced," Yohsuke Satoh "Implementing a DSM language is not a timeconsuming process. After a few man-weeks from the expert, all other developers can develop like experts too," Antti Raunio © MetaCase/JPT

23

DSM Solution Development Time 63 language concepts XML generator

60 language concepts C, HTML, build script generators

36 language concepts Assembler generator

77 language concepts Python generator

Java generator for simulation

143 language concepts J2EE generator

Man days

© MetaCase/JPT

24

DSM Pros & Cons + Fundamental productivity and quality improvements + 300% faster in academic study, 1000% reported by companies + 50% less errors in academic study

+ Gives full control to the company + Experienced developers are sitting in the driver’s seat

– Requires expertise and resources from the company + Minimal vendor lock + Metamodel-driven tools are open + You can translate & transform models to other tools and formats

– Only few industry strength tools available – Scalability to a larger number of developers – Do not handle evolution and maintenance

© MetaCase/JPT

25

Building your modelling language Overview Identifying language concepts Metamodelling Medical Mixin Machine example Language rules Language notations © MetaCase/JPT

26

Domain Idea

Solve problem in domain terms

Modelling domain vs. modelling code Map to code, implement

Map to code, implement

Finished Product

Code

Generate, Add bodies Map to UML

Model in DSM to map! Language

No need

© MetaCase/JPT

Assembler

UML Model

Generate code

Domain Framework

27

How to implement DSM Done a few times before!

Domain Idea

Expert (few)

Normal (many)

Easy!

© MetaCase/JPT

DSM language

Code generator

Framework code

Model in DSM language

Generate code

Domain Framework

Finished Product

28

The steps of defining a DSM solution 1. Identify abstractions – Concepts and how they work together

2. Specify the metamodel – Language concepts and their rules

3. Create the notation – Representation of models

4. Define the generators – Various outputs and analysis of the models

 Apply and refine existing components and libraries  The process is iterative: try solution with examples – Define part of the metamodel, model with it, define generator, extend the metamodel, model some more, ... © MetaCase/JPT

29

Implementing modelling languages  The most important asset of a DSM environment – Application engineers use it – Generator and framework largely invisible

 Often includes elements of familiar modelling paradigms – State machine – Flow model – Data structure, etc.

DSM environment DOMAINSPECIFIC Modelling LANGUAGE

DOMAINSPECIFIC CODE GENERATOR

 Language specified as a metamodel – Apply a suitable metamodelling language that helps to identify various constructs (metatypes) in languages © MetaCase/JPT

DOMAIN FRAMEWORK

30

Approaches to identify concepts  “How do I start to do DSM?” – Hard problem for DSM beginners – Analyzed over 20 cases to find good toolbox of approaches

 Initial analysis suggested five approaches: 1. 2. 3. 4. 5.

Domain expert’s or developer’s concepts Generation output Physical structure Look and feel of the system built Variability space

© MetaCase/JPT

31

Problem domain

Solution domain/ generation target

Approach

Telecom services

Configuration scripts

1

Insurance products

J2EE

1

Business processes

Rule engine language

1

Industrial automation

3 GL

1, (2)

Platform installation

XML

1, (2)

Medical device configuration

XML

1, (2)

Machine control

3 GL

1, 2

Call processing

CPL

2, (1)

Geographic Information System

3 GL, propriety rule language, data structures

2

SIM card profiles

Configuration scripts and parameters

2

Phone switch services

CPL, Voice XML, 3 GL

2, (4)

eCommerce marketplaces

J2EE, XML

2, (4)

Automation network

C

3, 4

Crane operations

C/C++

3, (5)

SIM card applications

3 GL

4

Applications in microcontroller

8-bit assembler

4

Household appliance features

3 GL

4

Smartphone UI applications

Scripting language

4

ERP configuration

3 GL

4, 5

ERP configuration

3 GL

4, 5

Handheld device applications

3 GL

4, 5

Phone UI applications

C

5, (4)

C++

5, (4)

Phone UI applications © MetaCase/JPT

32

1. Domain expert’s concepts      

Concepts from domain Mostly made without help Simple MoC Simple code generation OK in established domain Usable by non-coders

Insurance products/J2EE

© MetaCase/JPT

33

2. Generation output  Modelling constructs come from code artefacts  Static parts are easy – Data structures – Core XML elements

 Dynamic behaviour hard – Full programming language? – Need domain framework

 Danger: low level of abstraction – Little productivity gain

 But works well with DSL or XML

Internet telephony/CPL

– As opposed to generic 3GL

© MetaCase/JPT

34

3. Physical structure  Best for physical systems – Networks, logistic systems, HW architecture, train control, factory automation, etc.

 Often static data model MoC – Also describes connections and dependencies – May include behavioural elements

 Visible domain concepts – Easy to identify – High level of abstraction

 Usually linked to other models (and DSLs) to achieve more comprehensive code generation

© MetaCase/JPT

Automotive HW architecture 35

4. Look and feel of the system  Best for physical end product – UI on PC, embedded, speech

 Often state machine MoC – Also data & control flow – Power of relationships

 Visible domain concepts – Easy to identify – High level of abstraction

 Domain framework hides code – Don’t write code in models… – …unless you really have to!

 Generators considered easy

© MetaCase/JPT

Smartphone apps/Python

36

5. Variability space  Language concepts capture variability space  Modeller makes variant choices – Composition, relationships, values

 Infinite variability space (Czarnecki) – Not just feature tree: unbounded product family

 Used to create hardest DSM languages – Handled most complex domains, kept modelling simple

 Static variance easy, dynamic harder  Consultant should be good coder  Customer expert in his domain and code – Consultant should also be able to program

 Predict future variability  high level of abstraction © MetaCase/JPT

37

Evaluation of the Approaches  Only certain pairs of approaches occurred  Hierarchy of approaches –

From less to more experienced DSM practitioners

1. Domain expert’s concepts – "we just did it" 2. Generation output – –

Generic/ad hoc language not so good Established DSL good

3. Physical structure –

To support specifications in other DSM languages

4. Look and feel: common, easy, true DSM 5. Variability space: adds power to handle complexity –

Found in very different domains

 Best results combined 4 (L&F) and 5 (Variability) –

4 gives objects, 5 gives relationships and properties

© MetaCase/JPT

38

Defining the concepts with metamodelling  Enrich chosen computational models with domainspecific concepts and rules – look at the type of design languages already used

 Investigate various alternatives for describing domain with the chosen models, e.g. – – – – –

model element(s) element properties certain collection of elements relationships between elements model organization structures

 Specify as a metamodel in some format – – – –

draft samples with pen & paper document early as a metamodel implement in some metamodel-based tool test it with real models

© MetaCase/JPT

39

Rules [1/2]  The domain concepts of a modelling language are bound together with rules  Putting the rules into the language: – prevents creation of illegal models – informs about missing data – ensures model consistency

 Prefer having rules as part of metamodel to having separate checker – Support early error prevention and provide guidance – But going overboard can hinder flow of modeller

© MetaCase/JPT

40

Rules [2/2]  How rules are visible to modellers – – – –

During modelling action Inform when illegal design is made In a separate model check window By highlighting element(s) with errors or missing data

 When to run a separate model check – – – – –

On demand After certain model editing actions Before code generation Show in produced review documentation Before versioning etc.

© MetaCase/JPT

41

Example: Medical mixing machine

© MetaCase/JPT

42

Example: Medical mixing machine    

Single fixed physical machine Product variability in software: how to mix Platform has 11 cups, syringe to transfer between Problems in hand-coded software quality: – Syringe broken, operator died, patient treatment error

© MetaCase/JPT

43

Exercise  Getting started with the tool & language  Version 0: Unityped Modelling Language – Based on generic code concepts

 Version 1: Domain-specific concepts – Entirely new metamodel, notation, semantics – Code generator

 Version 2: Add logical grouping  Version 3: Add model reuse  Version 4: Higher-level concepts – Entirely new metamodel – Code generator

 Summary and what next?

© MetaCase/JPT

44

Getting started with the tool  On the CD/USB, locate the folder for your platform – Windows, Mac OS X, Linux

 Copy the whole folder to your desktop  Open the folder from the desktop – You can now pass the CD/USB on

 Folder contents: – Installer (.exe in Windows, .dmg in Mac OS X, .tar.gx in Linux) – Hands-on.pdf = this slide set – GOPRR.mxt = the metamodelling language definitions – *.svg = pre-defined graphical symbols in SVG format

© MetaCase/JPT

45

Getting started with the tool  Windows – Run the installer and accept defaults – After installation you will have: MetaEdit+ app → C:\Program Files\MetaEdit+ 4.5 Evaluation User files & repositories → ...\My Documents\MetaEdit+ 4.5

– MetaEdit+ starts automatically after installation • Can also start it from the Start Menu

 Mac OS X – Open the distribution .dmg and drag the MetaEdit+ application into the Applications folder – Execute MetaEdit+ by clicking its icon in Applications • First execution of MetaEdit+ will create required folders and files under your Documents folder – takes about 20 seconds

© MetaCase/JPT

46

Getting started with the tool  Linux – Execute the following set of commands from shell (requires root privileges or sudo): cd /usr/local sudo mkdir mep45eval cd mep45eval sudo tar -xzvf ~/Desktop/Linux/MetaEdit+EVAL-4.5-1.i386.tar.gz export PATH=$PATH:/usr/local/mep45eval cd ~ mesetup

– Executing mesetup will create ~/metaedit and place user files and repositories there – Start MetaEdit+ by executing: cd ~/metaedit metaedit

© MetaCase/JPT

47

Getting started with the tool  Creating and logging into the repository 1. Choose File | Create Repository...

2. Enter: • Database name: ECMFA2011 • Database root directory: ECMFA2011 • Your name: user • Your password: user

3. Confirm the password 4. Allow creation of new ’ECMFA2011’ directory 5. Enter evaluation code qfntd to activate the 31day evaluation period © MetaCase/JPT

48

Getting started with the tool  Create new project 1. In Projects list popup menu choose New... 2. Answer Yes when prompted for committing current transaction 3. Enter Mixing as name for the new project 4. Accept all prompts 5. Press Commit ( )

 Import the graphical metamodelling language 1. Press Import ( ) 2. Select and open GOPRR.mxt from the file dialog 3. Press Commit ( ) again © MetaCase/JPT

49

Getting started with the language  The assignment: Medical Mixing Machine

“take from the second cup 5 units with filter A and put 2 units to cup 6 and 3 units to cup 7 and then clean the needle” © MetaCase/JPT

01 02 03 04 05

move(-3); filt(1); suck(5); move(4); filt(0); blow(2); move(1); blow(3); move(-3); suck(30); move(1); blow(30); 50

Version 0: Unitype Modelling Language  Creating the version 0 language – Have a box representing a command – Show execution flow with relationships move(-3); filt(1); suck(5); move(4); filt(0); blow(2); move(1); blow(3); move(-3); suck(30); move(1); blow(30); © MetaCase/JPT

51

GOPRR concepts  A Graph is one individual model – often shown as a diagram

 Objects are the main elements of graphs – often shown as boxes or circles

 A Property is an attribute characterizing another element – often shown as a label

 A Relationship connects objects together, – often shown as a label over the connection

 A Role connects an object into a relationship, – often shown as a line and arrow-head – A Binding connects a Relationship, Roles and Objects Property Role

Relationship

Property

Role Object

Object

Binding © MetaCase/JPT

52

Graphical GOPRR in MetaEdit+ Graph

Object

Property

Role

Relationship

Binding

© MetaCase/JPT

53

Initial target metamodel  Command objects represent Function calls (move, filter, suck, etc.) with their Parameters  Transition relationships and From and To roles define the procedural order of commands

© MetaCase/JPT

54

Creating a Graph type 1. Press Create Graph in toolbar ( ) → Create Graph dialog opens 2. Select Metamodel [GOPRR] from the list 3. Press Ok → graph definition dialog opens

1

2

3

continues... © MetaCase/JPT

55

Creating a Graph type 4

4. Enter Mixing 0 as Graph Name 5. In Properties list popup menu choose Add Element... → Property definition dialog opens 6. Enter Name as Property name 7. Press OK in property definition dialog 8. Press OK in graph definition dialog → a Diagram Editor for new GOPRR metamodel opens

5

8

6

7

© MetaCase/JPT

56

Diagram Editor  Graphical metamodels are defined in Diagram Editor

Action toolbar Types toolbar Tree view Drawing area Property sheet

© MetaCase/JPT

57

Creating an Object type 1. Click Object on types toolbar to select it 2. Click on drawing area → object definition dialog opens 3. Enter Command as Object name 3 1

2 CLICK

© MetaCase/JPT

continues... 58

Defining Property types 1. In Properties list popup menu, Add Element... → property definition dialog opens 2. Enter Function as Property name 3. Press OK → the new Property appears in object definition dialog’s Properties list 2

1

3

© MetaCase/JPT

continues...

59

Completing the Object type 1. Create another property called Parameter for Command object 2. Press OK in object definition dialog 3. New Command object will appear in Diagram Editor 1

3 2

© MetaCase/JPT

60

Creating a Binding 1. Click Binding on types toolbar to select it 2. Click on the Command object, then click for two breakpoints outside it 3. Double-click Command → binding definition dialog opens

1CLICK

CLICK

CLICK

2

DOUBLE CLICK

3 CLICK

continues... © MetaCase/JPT

61

Creating Relationship type 1. In Relationship field popup menu, Attach New Object... → relationship definition dialog opens 2. Enter Transition as Relationship name 3. Press OK → the Transition relationship will now appear as part of the binding definition –

Don’t press All OK yet! 2 1

3

continues... © MetaCase/JPT

62

Creating first Role type 1. Activate the First role tab 2. In Role field popup menu, Attach New Object... → role definition dialog opens 3. Enter From as Role name 4. Press OK → the From role appears as part of the Binding definition 3 1 2

4

continues... © MetaCase/JPT

63

Creating last Role type 1. 2. 3. 4.

Activate the Last role tab In Role field popup menu, Attach New Object... In role definition dialog, enter To as Role name Press OK → the To role appears as part of the binding definition 3 1 2 4

continues... © MetaCase/JPT

64

Finalizing Binding type 1. Press All OK in binding dialog → new Binding will appear in Diagram Editor

1

© MetaCase/JPT

65

Complete initial metamodel  Command objects represent Function calls (move, filter, suck, etc.) with their Parameters  Transition relationships and From and To roles define the procedural order of commands

© MetaCase/JPT

66

Metamodel build 1. Save the current metamodel by pressing Commit in the main MetaEdit+ window 2. In the Diagram Editor, press the Build button in the action toolbar 3. MetaEdit+ will build the metamodel automatically 4. Close the Generated Files info dialog that appears

1

© MetaCase/JPT

2

67

Creating a new Graph 1. In the main MetaEdit+ window, press Create Graph in toolbar 2. Select Mixing 0 graph type from graph creation dialog and press Ok 3. Enter Test 0 as name for the new graph 4. Press OK → Diagram Editor for the new model opens 1 2

3 © MetaCase/JPT

4

68

Diagram Editor revisited  Basic behaviour the same as with graphical GOPRR  Types toolbar now contains the types of the new language (i.e. Command and Transition)

© MetaCase/JPT

69

Creating Objects 1. Ctrl-click Command in types toolbar to enable sticky creation mode 2. Click on drawing area to start creating a Command 3. Enter Function name and Parameter value in property dialog 4. Press OK → new object will appear on drawing area

1

CLICK

3

2

4 © MetaCase/JPT

continues... 70

Creating Objects 5. Click again on drawing area to create another Command 6. Enter Function name and Parameter value in property dialog and press OK –

Parameter values to enter are shown below in red

7. Repeat 5 – 6 to create all required objects 8. Press right mouse button to end sticky creation

© MetaCase/JPT

71

Creating Bindings 1. Ctrl-click Transition in types toolbar to enable sticky creation mode 2. Click and hold on top of the first object 3. Drag on top of the other object and release the mouse button → new binding is placed between the objects

1 2

© MetaCase/JPT

3

continues... 72

Creating Bindings 4. Click and hold on top of an object 5. Drag on top of the next object and release the mouse button to create a binding 6. Repeat 4 – 5 to create all required bindings 7. Press right mouse button to end sticky creation 8. Press Commit in main MetaEdit+ window to save your work

© MetaCase/JPT

73

Creating symbols for objects 1. Select one Command object in diagram 2. In property sheet, shift-double-click Object type row, → Symbol Editor for roles opens

1

continues... © MetaCase/JPT

74

Symbol Editor: drawing rectangle 1. Toggle on grid’s Snap and Show in status bar 2. Click on Rectangle in toolbar 3. Click and hold on drawing area to place rectangle’s top-left corner 4. Drag for the bottom-right corner and release

2 CLICK + HOLD

3

4 RELEASE

1 © MetaCase/JPT

continues... 75

Symbol Editor: adding text 1. Click on Text in toolbar 2. Click and hold on drawing area to place text box’s top-left corner 3. Drag for the bottom-right corner and release → format dialog for text source and other properties opens 1 2 CLICK + HOLD

3

RELEASE

continues... © MetaCase/JPT

76

Symbol Editor: text properties To make the text show the Function property: 1. On the Content page, select Property radio button and select Function from the pulldown list 2. Go to Text Settings page and set alignment centered 3. Press OK → the Function text box will appear

1 2

3 © MetaCase/JPT

continues... 77

Symbol Editor: text properties 4. Set both line colour and fill as transparent for the new text element

4

continues... © MetaCase/JPT

78

Symbol Editor: saving symbol 1. Create another text element for Parameter property (use centered text and bold font type) 2. Press Save on toolbar → the symbols in Diagram Editor update automatically 3. Close Symbol Editor

2

1

© MetaCase/JPT

79

Creating symbols for roles 1. Select one To role in diagram 2. In property sheet, shift-double-click Role type row, → Symbol Editor for roles opens  In Symbol Editor for roles a fixed line segment represents the role line, ending at the object’s edge

1

2

© MetaCase/JPT

continues... 80

Symbol Editor: roles 1. Set grid as 5-by-5 (View | Choose Grid...) 2. Draw two short diagonal lines (2 squares by 1) back from the line end to get the arrow head 3. Press Save → role symbols update in Diagram Editor 4. Close Symbol Editor 3

2

© MetaCase/JPT

81

That’s it!  Diagram Editor provides normal editing features... – – – – – –

Undo/redo Cut/Copy/Paste/Paste special... Replace for refactoring Info for tracing Grid operations: snap, align, etc. Import/export, autolayout...

 ... integrated with generators – – – –

Code generator Document generators Model checking and analysis Metrics etc.

 Along with other tools for browsing, importing and exporting, programmatic API etc.

© MetaCase/JPT

82

Version 1: Domain-specific concepts  Make each command into its own type – Cf. Object-oriented approach, e.g. Command pattern

 Create a new metamodel, Mixing 1, as shown here move(-3); filt(1); suck(5); move(4); filt(0); blow(2); move(1); blow(3); move(-3); suck(30); move(1); blow(30); © MetaCase/JPT

83

Version 1: Type-specific parameters  Different types have different parameter lists – E.g. filter values are different from move values – Filter {0,1,2}, move -10..10, suck/blow 0..30 move(-3); filt(1); suck(5); move(4); filt(0); blow(2); move(1); blow(3); move(-3); suck(30); move(1); blow(30); © MetaCase/JPT

84

Creating second metamodel 1. In MetaEdit+ main window, press Create Graph... in toolbar 2. Select Metamodel [GOPRR] from Graph type list and press Ok 3. Enter Mixing 1 as Graph name

continues... © MetaCase/JPT

85

Creating second metamodel Reuse existing Name property 4. Choose Add Existing... from Properties list popup menu → component tool opens 5. Double-click on Name on Selection list → Name will appear on Already selected list 6. Press OK to accept Already selected list → Name is now reused as a property for the new graph 7. Press OK in graph definition dialog

4

5

6 © MetaCase/JPT

7

86

Creating abstract object 1. 2. 3. 4. 5. 6.

Hint: Set grid as 75-by-50 Click on Object in types toolbar Click on drawing area → object definition dialog opens Enter Abstract as Object name Set Occurrence as 0 (this defines the object as abstract) Press OK → new Abstract object appears

4

2 5 3

CLICK

6 © MetaCase/JPT

87

More objects and properties 1. Create Move object and define Distance property for it 2. Create Filter object and define Filter property – Select Radio Button Set as datatype for property – Enter 0, 1 and 2 as Default values, one per line

3. Create Suck object and define Amount property 4. Create Blow object and reuse Amount property created in previous step (Add Existing...)

3

© MetaCase/JPT

88

Using inheritance  Move, Filter, Suck and Blow are descendants of Abstract → use Inheritance relationship  N-ary binding = binding with more than 2 roles

© MetaCase/JPT

89

Using inheritance 1. Click Inheritance on types toolbar 2. Click on drawing area to place the inheritance join-point 3. Click on Move, Filter, Suck and Blow to connect them –

Choosing them first makes them the descendants

4. Double-click on Abstract to connect it and finish creation –

Since it is the last one, it becomes the ancestor

1 CLICK DOUBLE CLICK

4

CLICK

CLICK

3 CLICK

© MetaCase/JPT

CLICK

2

CLICK

CLICK

90

Finalizing second metamodel 1. Finalize the n-ary binding for inheritance visually –

Click role line then drag a point on it to add breakpoint

2. Add Transition binding (as in version 0)  Reuse existing Transition relationship and From and To role types (Add Existing... in binding definition dialog) 2

1

© MetaCase/JPT

91

Testing Version 1  Press Build to generate the new metamodel  Test the language in a new Mixing 1 graph, Test 1 – Create the model structure below, with grid 100x100 – You’ll just see default symbols, without ’move’ etc.

© MetaCase/JPT

92

Version 1: Distinct meaningful symbols  Cf. intention-revealing names, syntax colouring

© MetaCase/JPT

93

Version 1: Code generator  Writes out command for an object  Follow relationship to recurse to next object move(-3); filt(1); suck(5); move(4); filt(0); blow(2); move(1); blow(3); move(-3); suck(30); move(1); blow(30); © MetaCase/JPT

94

Opening Generator Editor  Choose Graph | Edit Generators... in Diagram Editor → Generator Editor opens

© MetaCase/JPT

95

Generator Editor Categories

Concepts/ commands

Generators

Editing area

Errors © MetaCase/JPT

96

Creating a new generator 1. Choose Generator | New... 2. Enter Code as name for new generator and accept → new empty generator script appears on editing area 1

2

© MetaCase/JPT

97

Creating a new generator 1. Enter generator definition in editing area  For generator script content, see next slide

2. Press Save in toolbar → Code will appear on generator list 3. Similarly, create another generator called _next 2

1

© MetaCase/JPT

3

98

The generator scripts  The Code generator script Report 'Code' foreach .() where not ~To { subreport '_next' run } endreport

 The _next script Report '_next' type '(' id ');' newline do ~From~To.() { subreport '_next' run } endreport © MetaCase/JPT

99

Testing generators 1. Select Code from the generator list 2. Press Generate... in toolbar 3. Select Test 1 from the list → the generator output will open in Generator Output window 2 1

3

© MetaCase/JPT

100

Generators explained  The Code generator script Report 'Code' foreach .() where not ~To { subreport '_next' run

For each object that does not have a To role (= start from the first command)... ..execute ’_next’ subgenerator

} endreport

© MetaCase/JPT

101

Generators explained  The _next generator script Report '_next' type '(' id ');' newline;

do ~From~To.() { subreport '_next' run

Output current object’s type (e.g. Move) and id (first property, i.e. parameter) and newline

Navigate through From and To roles to the next object in sequence Execute ’_next’ subgenerator recursively

}

endreport

© MetaCase/JPT

102

Version 2: Logical grouping  Collect logical groups of code into visual blocks or chunks – Enclosing boxes (cf. commented code regions) – Boxes + relationships (cf. goto) move(-3); filt(1); suck(5); move(4); filt(0); blow(2); move(1); blow(3); move(-3); suck(30); move(1); blow(30); © MetaCase/JPT

} } }

} 103

Version 2: Add ’Step’ objects  Update the metamodel by adding Step subtype  Use ”Add Existing” for Name property  Add one more role into the inheritance relationship: 1. 2. 3. 4.

Click Inheritance on toolbar Click on existing Inheritance relationship join point Click for breakpoint Finalize by clicking Step object

 Press Build to update the metamodel

CLICK CLICK

2

3 DOUBLE CLICK

4 © MetaCase/JPT

104

Version 2: Refactor into Steps  Add a Step object  Shift-double click Object type row to edit symbol – Make a wide rectangle with transparent fill, plus small text

 Add rest of steps – Drag edges with ctrl to scale

 Connect Steps with Transitions  Delete old diagonal Transitions

© MetaCase/JPT

105

Version 3: Support model reuse  Enable model hierarchies with Steps – Support reuse of models

© MetaCase/JPT

106

Version 3: Allow subgraphs  Create metamodel showing modelling language hierarchy – Create Graph... from Graphs list popup menu – Select Metamodel for multiple graphs [GOPRR] from the list – Enter the same metamodel name, Mixing 1

 Add Graph element to the diagram – – – – –

Click Graph button in toolbar Click in diagram to create Graph box Scale resulting Graph box bigger Right-click Graph box, Decompositions... Choose the current metamodel, Mixing 1, and press OK

© MetaCase/JPT

107

Version 3: Allow subgraphs  Add model hierarchy – Copy Step from the existing metamodel and paste it inside the newly created Mixing 1 Graph box – Draw a Decomposition relationship from Step to Mixing 1 – A Step in a Mixing 1 graph can decompose to another Mixing 1 graph

 Press Build to generate the new metamodel © MetaCase/JPT

108

Version 3: Refactor to subgraphs  Go back to the Test 1 model  Refactor the model hierarchy: for each Step – Select the objects in the Step and Cut them – Select Step, choose Decompositions... in pop-up menu – Select Create a new graph... – Enter name of Step as graph name and press OK – Paste cut content into the graph

© MetaCase/JPT

109

Version 4: Higher level domain concepts  Make reusable chunks into types – Give types properties to parameterize reuse

 From:

 To:

Take

Put

Clean

 Note: the Move commands are now handled with a new property in the relationship between operations © MetaCase/JPT

110

Version 4: New metamodel  Create new Metamodel [GOPRR] graph, Mixing 4  Add new objects Take, Put, Clean as shown below – Reuse Amount, but make new Using Filter {None, A, B} – Add Abstract and make it their ancestor

 Add new relationship Move reusing Distance  Reuse From & To  Don’t Build yet!

© MetaCase/JPT

111

Version 4: Add rules  Add Start object, Occurrence 1 (singleton for 1st move)  Analysing domain further: – Take can follow anything (Abstract) – Put can follow Take or Put • Add new supertype Needle for Take & Put. Cut&Paste Amount.

– Clean can only follow Put

© MetaCase/JPT

112

Version 4: symbol for relationship 1. Select relationship on Diagram Editor 2. Shift-double-click on property sheet’s Relationship row to open Symbol Editor 3. Place textbox for Distance property on drawing area 4. Select Point Connectable from toolbar and place it in the middle of the textbox 5. Press Save and close Symbol Editor 4 3 1 2

© MetaCase/JPT

113

Version 4: Reqs  Model  Code “take from the second cup 5 units with filter A

01 02 03 04 05 © MetaCase/JPT

put 2 units to cup 6

put 3 units to cup 7

then clean the needle”

move(-3); filt(1); suck(5); move(4); filt(0); blow(2); move(1); blow(3); move(-3); suck(30); move(1); blow(30); 114

Modeling effort?

   

12 objects 11 relationships 12 properties 35 elements in total

© MetaCase/JPT

   

5 objects 4 relationship 7 properties 16 elements in total 115

Where are the concepts?

“take from the second cup 5 units with filter A and put 2 units to cup 6 and 3 units to cup 7 and then clean the needle” © MetaCase/JPT

01 02 03 04 05

move(-3); filt(1); suck(5); move(4); filt(0); blow(2); move(1); blow(3); move(-3); suck(30); move(1); blow(30); 116

Modeling effort?

   

12 objects 11 relationships 12 properties 35 elements in total

© MetaCase/JPT

   

2 objects 1 relationship 5 properties 8 elements in total 117

Plan model structures for reuse  Deeper commonality / variability analysis – What is in several applications but not all?

 Normal aims for high cohesion, low coupling – Remember parameter passing, interfaces

 How does your tool allow model sharing?  Will models be shared between: – multiple developers? – multiple applications? – multiple versions?

 Often, these questions are too hard for an early stage – Only build support for a single clearly needed reuse case – Let later use show you where more reuse is needed © MetaCase/JPT

118

Defining notation [1/2]  Vital for acceptance and usability  Symbols can vary from boxes to photorealism – Best to resemble closely the actual domain representation – Worst is having everything a box and special text to show the difference (cf. stereotypes) – Design information needs space: compromise

 Don’t create notation from scratch – Use known/existing elements (and, or, start, stop etc)

 Hint: ask users to define the notation – It is much easier to introduce their own language than something you created – Remember also model readers • managers, test engineers, customers, deployment, configuration, packaging and even sales © MetaCase/JPT

119

Defining notation [2/2]  Consider also other representational styles – Matrices focus on relationships, avoid line-crossings, help identify high cohesion and low coupling – Tables and forms show details and support sorting, categorization, comparison – Diagrams good in finding patterns and organizing model elements into non-linear structures

 Multiple representations possible for the same data – E.g. as a relationship line and as an object – Can also make symbols and texts retrieve others' info – Changes in one representation update the others

 Use common symbol elements to improve readability – Show if concept is reused, has a submodel etc.

 Use symbols to indicate the state of the model – Missing information, errors, default value is not used etc. © MetaCase/JPT

120

Visual variables  Symbols should use full range of visual variables

© MetaCase/JPT

121

© MetaCase/JPT

«Person»

«Laptop»

«Output»

«Input»

122

«Person»

«Laptop»

«Output»

«Input»

pictogram > geometric > photo

© MetaCase/JPT

123

Case: Automotive infotainment

© MetaCase/JPT

124

Case: Track control of railway systems

© MetaCase/JPT

125

Case: Sports computer

© MetaCase/JPT

126

Building a Generator

© MetaCase/JPT

127

Generator DSM environment



Generator translates the models into the required output 1. crawls through the models  navigation according to metamodel

DOMAINSPECIFIC Modelling LANGUAGE

2. extracts required information  access data in models

3. translates it into the code

 translation semantics and rules

4. using some output format

DOMAINSPECIFIC CODE GENERATOR

 possibility to define output format DOMAIN FRAMEWORK

© MetaCase/JPT

128

How to design a generator, 1  Make generator for your situation only • Trying to make general purpose generator often fails

 Make generation process complete, target 100% output – Never modify the generated code • Do you want to edit Assembler after compiling?

– Correct the generator or framework instead • No round-trip-related problems • Do you want to edit Assembler and keep C in synch with it?

 Use modelling languages to raise abstraction • Don’t visualize code • Generating a class from a diagram to a class in code helps very little, if at all…

 Put domain rules up-front to the language • Generator definition becomes easier when the input is correct • Models should be impossible to draw wrongly for generation © MetaCase/JPT

129

How to design a generator, 2  Try to generate as little code as possible – Glue code only, rest in domain framework or platform

 Keep generator as simple as possible – Raise variation to the specification language – Push low-level common implementation issues to the framework

 Keep generator modular to reflect changes – e.g. structure generator based on modelling languages, generated files, modelling concepts – e.g. use common generator subroutines for common needs

 Make generated code readable (“good looking”) – To be used later while debugging the code, executing it in a simulator, and while implementing the generator – Follow good coding standards, include comments, have data to link back to models (e.g. in comment or via e.g. simulator) © MetaCase/JPT

130

Generator degrees of freedom  Different levels of generators: modular / tree structure 1. Generator per file to be generated 2. Generator per section in a file 3. Generator per metamodel element

 Different Model of Computation implementations – – – –

Sequential Function calls Switch-case structure Transition tables, etc.

 Different levels of code that generated code can call or subclass – Other generated code – Domain framework components – Platform functions

 Different generation options for different runs – Different top-level generators – Top-level graph for generation options © MetaCase/JPT

131

"Here's one I made earlier"  Write some good, working code by hand – Can only automate what can be done well by hand – Aim for simplicity, what you would teach, not cleverness

 Build the model that represents the same system – Aim for one instance each of 3-4 main object types

 Analyse the code from the viewpoint of the generator  Simplest parts of generator are the extreme cases: – Fixed text, always output the same – Values directly from the model, e.g. names

 Between the extremes is the meat of the generator: – Conditional sections, inclusion depends on model values – Repeated sections, e.g. once per model element

© MetaCase/JPT

132

Code + model  generator 1. Paste output code as entire content of generator 2. Reduce repeated sections  One occurrence for each  Generator loop visits each model structure for section

3. Collect sections with two or more alternative forms  Surround them with generator conditional  Condition gets its input from model

4. Replace output that comes from property values  Navigate to and read value from model  Massage value as necessary, e.g. space to underscore

 In practice, 2-4 normally occur in parallel

© MetaCase/JPT

133

Types of generator facilities  Programming language accessing model through API – Direct access, but low level, high coupling with tool – Need something better, designed just for generation

 Model visitor – Map each model structure to a code structure – Limited to simple one-to-one mappings

 Output template – Single file, code + escaped

 Crawler: Model navigation and output streams – Multi-file, code quoted, native generator commands

 Generator generators – Tempting, alluring, mostly unnecessary © MetaCase/JPT

134

Patterns for Generators by Type of Output Simple text Model checking Documentation XML Flow machine State machine © MetaCase/JPT

135

Generating simple text  Simple text tends to fall into three categories – Largely boilerplate – Configuration and settings files – Simple script files

 Configuration files can be tricky – Reader of file has no intelligence, expects exact format – E.g. model specifies value in decimal, but file uses hex – DSL generator may not have conversion: postprocess

 Script files easier – Reader of file has intelligence, leave conversion to it

© MetaCase/JPT

136

Model checking by generators  Most rules should be in modelling language – Easiest for modeller, guarantees good generator input

 Model checking output different from other output: – Read by modeller, not a program – Read at design time, not compile or run-time

 Favours integrated generator facilities, "live" output – E.g. results displayed in model symbol – If results elsewhere, hyperlink to model element useful

 Bespoke tools exist for more complex checks – E.g. for state machines: output in required format

© MetaCase/JPT

137

Generating documentation  Models in the tool are the best documentation: – High-level, precise, always up-to-date – Tool offers best environment for reading docs

 Access and familiarity motivate traditional formats – Everyone can use Word, HTML browser

 Include model images as vectors or bitmaps – SVG >= PNG > GIF > JPEG

 Separate formatting from content – Make fixed CSS or Word template with generator

 Use macros or scripts to make generation easier – E.g. Word AutoOpen macro for ToC, .rtf->.doc

© MetaCase/JPT

138

Generating XML  Generating simple, first-cut XML is easy '' newline foreach .() { ' ' newline } '' newline

 Generating watertight XML is an ugly mess – – – –

Element names: letter, underscore or colon, not xml* Attribute values: quoted, "  ", white space Text elements: CDATA allows all except CR Encoding: use UTF-8 or platform native • In platform native, beware smart quotes

© MetaCase/JPT

139

Generating flow machines (1) A

B

C

A; B; C;

 Chain of model elements  sequential instructions – Simplest case: no cycles, forks or joins

 Requires some thought, often recursion in generator: Report "handleObject" :Command /* output for this object */ do ~From~To.() /* traverse to next object(s) */ { subreport "handleObject" run /* recurse */ }

 API-based generators can iterate: do { System.out.println(currObj.Command()); currObj = currObj.nextObject(); } while (currObj != null) © MetaCase/JPT

140

Mixin machine version 4:  Implement generator with Generator Editor – Diagram Editor: Graph | Edit Generators... – Generator | New... Report 'Code' Begin from Start element foreach .Start and execute ’_MoveAndDo’ { subreport '_MoveAndDo' run subgenerator for it } endreport Navigate through From role to the relationship Output Distance property Navigate through To role to the object and execute subgenerator named ’_Do’ + object type (e.g. ’_DoTake’) © MetaCase/JPT

Report '_MoveAndDo' do ~From>() { 'move(' :Distance ');' newline do ~To.() { subreport '_Do' type run } } endreport 141

Mixin machine version 4:  Add rest of generators – one for each object type – Below a generator for ’Take’ object If filter is used output filter code Translate filter value given in a model to a legal value for code (A->1, B->2) Output amount If filter is used remove filter by outputting ’filt(0)’ Execute ’_MoveAndDo’ subgenerator © MetaCase/JPT

Report '_DoTake' if :Using Filter; 'None' then 'filt(' to 'AB 12' translate :Using Filter; endto ');' newline endif 'suck(' :Amount ');' newline if :Using Filter; 'None' then 'filt(0);' newline endif subreport '_MoveAndDo' run endreport

142

Mixin machine version 4:  Add rest of generators – one for each object type – Below a generator for ’Put’ and ’Clean’ objects Output amount Execute ’_MoveAndDo’ subgenerator

Output fixed code for cleaning the needle Execute ’_MoveAndDo’ subgenerator

© MetaCase/JPT

Report '_DoPut' 'blow(' :Amount ');' newline subreport '_MoveAndDo' run endreport Report '_DoClean' 'suck(30); move(1); blow(30);' newline subreport '_MoveAndDo' run endreport

143

Generating flow machines (2)  Real programs need more – Sequence + IF + GOTO

 Conditions and jumps hard – Naive generator will duplicate all from Mail on – In more complex cases, even visited list is no help

 So change DSM language: – IF's successor after ENDIF – THEN & ELSE subordinate

 GOTO OK in models – Can see flow of control – Spaghetti instantly visible

© MetaCase/JPT

144

Assembler for 8-bit microcontroller  VoiceMenu for home automation systems  Language concepts deal with – basic operations like accessing memory addresses, calculation, comparison and jump – menu specific operations like speaking out menu items – flow of execution and conditional jumps appear as relationships

 100% code generation – No framework code to support generation, all code from models

© MetaCase/JPT

145

Assembler for 8-bit microcontroller  Generator follows the flow of execution via relationships, generating out chunks of operations related to each design element 01 Speak 0x01 (Pause for 0.5 sec) 02 Speak 0x02 (the...) 03 Speak 0x03 (...current...) 04 Speak 0x04 (...lifestyle...) 05 Speak 0x05 (...is...) 06 GetLifeStyle 07 Speaks Lifestyle 08 Speak 0x06 (Pause 0.3 sec) 09 Speak 0x07 (select...) 10 Speak 0x08 (...another...) 11 Speak 0x04 (...lifestyle...) 12 FillMemB 00 13 :3_844 14 Add to MemB 01 15 Speak 0x09 (for...) 16 Speaks Lifestyle 17 Speak 0x10 (...press...) 18 Speak number MemB 19 Is MemB >= 0F 20 IFNot 21 Goto 3_844

© MetaCase/JPT

146

Assembler for 8-bit microcontroller  Generator follows the flow of execution via relationships, generating out chunks of operations related to each design element 01 Speak 0x01 (Pause for 0.5 sec) 02 Speak 0x02 (the...) 03 Speak 0x03 (...current...) 04 Speak 0x04 (...lifestyle...) 05 Speak 0x05 (...is...) 06 GetLifeStyle 07 Speaks Lifestyle 08 Speak 0x06 (Pause 0.3 sec) 09 Speak 0x07 (select...) 10 Speak 0x08 (...another...) 11 Speak 0x04 (...lifestyle...) 12 FillMemB 00 13 :3_844 14 Add to MemB 01 15 Speak 0x09 (for...) 16 Speaks Lifestyle 17 Speak 0x10 (...press...) 18 Speak number MemB 19 Is MemB >= 0F 20 IFNot 21 Goto 3_844

© MetaCase/JPT

147

Assembler for 8-bit microcontroller  Generator follows the flow of execution via relationships, generating out chunks of operations related to each design element

The lifestyle voice sample is reused to save the memory space

© MetaCase/JPT

01 Speak 0x01 (Pause for 0.5 sec) 02 Speak 0x02 (the...) 03 Speak 0x03 (...current...) 04 Speak 0x04 (...lifestyle...) 05 Speak 0x05 (...is...) 06 GetLifeStyle 07 Speaks Lifestyle 08 Speak 0x06 (Pause 0.3 sec) 09 Speak 0x07 (select...) 10 Speak 0x08 (...another...) 11 Speak 0x04 (...lifestyle...) 12 FillMemB 00 13 :3_844 14 Add to MemB 01 15 Speak 0x09 (for...) 16 Speaks Lifestyle 17 Speak 0x10 (...press...) 18 Speak number MemB 19 Is MemB >= 0F 20 IFNot 21 Goto 3_844

148

Assembler for 8-bit microcontroller  Generator follows the flow of execution via relationships, generating out chunks of operations related to each design element 01 Speak 0x01 (Pause for 0.5 sec) 02 Speak 0x02 (the...) 03 Speak 0x03 (...current...) 04 Speak 0x04 (...lifestyle...) 05 Speak 0x05 (...is...) 06 GetLifeStyle 07 Speaks Lifestyle 08 Speak 0x06 (Pause 0.3 sec) 09 Speak 0x07 (select...) 10 Speak 0x08 (...another...) 11 Speak 0x04 (...lifestyle...) 12 FillMemB 00 13 :3_844 14 Add to MemB 01 15 Speak 0x09 (for...) 16 Speaks Lifestyle 17 Speak 0x10 (...press...) 18 Speak number MemB 19 Is MemB >= 0F 20 IFNot 21 Goto 3_844

© MetaCase/JPT

149

Assembler for 8-bit microcontroller  Generator follows the flow of execution via relationships, generating out chunks of operations related to each design element 01 Speak 0x01 (Pause for 0.5 sec) 02 Speak 0x02 (the...) 03 Speak 0x03 (...current...) 04 Speak 0x04 (...lifestyle...) 05 Speak 0x05 (...is...) 06 GetLifeStyle 07 Speaks Lifestyle 08 Speak 0x06 (Pause 0.3 sec) 09 Speak 0x07 (select...) 10 Speak 0x08 (...another...) 11 Speak 0x04 (...lifestyle...) 12 FillMemB 00 13 :3_844 14 Add to MemB 01 15 Speak 0x09 (for...) 16 Speaks Lifestyle 17 Speak 0x10 (...press...) 18 Speak number MemB 19 Is MemB >= 0F 20 IFNot 21 Goto 3_844

© MetaCase/JPT

150

Generating flow machines (3)  Higher level constructs: GOTO  GOSUB  Functions  Map each object to its own function – Actual action • Will normally be more than a line or two

– Specification of next function(s) to call • Conditions to pick which to call

 Simplest implementation: function calls next directly – Stack depth problems

 Better: return pointer to next function – Requires language support: easy in C, Smalltalk, LISP – Java: invoke() – C#: Type.InvokeMember() © MetaCase/JPT

151

Python for smartphones  Modeling language based on phone widgets and services  Enforces the UI programming model and phone framework rules, e.g. – SMS sending – Notification handling – View management

© MetaCase/JPT

152

Function calls – Series 60/Python

Generator definition

Generator output

Report '_Note' /* Produces Note code */ 'def ' type;oid '():' ‘ appuifw.note(u"‘ :Text or code; '", ''' :Note type ''')' subreport '_next element' run endreport

def Note3_2227(): appuifw.note(u"Registration made", 'conf') return Stop3_983

Report '_next element' /* reports next flow element*/ do ~From>Flow { do :Function used {' ' :Function name;} '(' :Code ')' do ~To.() {‘ return ' subreport '_Internal name' run} } endreport

def Note3_2543(): appuifw.note(u“Conference registration: Welcome", ‘info') return Popup_menu3_2520

© MetaCase/JPT

def Note3_6109(): appuifw.note(u“Registration cancelled", ‘info') return Stop3_983

def Stop3_983(): # This applications stops here return appuifw.app.set_exit

...

153

Generating state machines (1)  Can generate as double switch case, e.g. in C: switch (state) { case : switch (event) { Transition %> case : if () { ; ; ; state = ; } break; default: break; } default: break; }

© MetaCase/JPT

154

C for wristwatch applications  Typical for embedded devices – e.g. medical devices, diving instruments, car infotainment  Modeling language to define application logic using basic domain concepts, using extended state machine  Uses services from the domain-specific platform – e.g. in case of digital wristwatch: time, display, button etc

 Code generator produces 100% of variant implementation

© MetaCase/JPT

155

Switch-Case – Watch/C  C from the extended state machine; Watch

Generator ouput void handleEvent() int = Start; typedef enum { Start, EditHours, EditMinutes, Show, Stop } States; { state int switch button = {None; pseudo-button for following buttonless transitions */ typedef enum(state) None,/*Mode, Set } Buttons; { void runWatch() case EditHours: { switch (button) while (state != Stop) { { case Set: handleEvent(); state = EditHours; button = getButton(); /* waits for and returns increment_and_roll(tempOffset, HOURS, next UP); button press */ } break; } case Mode: icon (editHours, OFF); icon (editMinutes, ON); state = EditMinutes; break; default: break; }

© MetaCase/JPT

156

Generating state machines (2)  Can represent as data not code, e.g. in OO languages – Transition table: {State  {Event  (Action, State)}} – State names, decompositions

 Behaviour of state machine in abstract superclass – Domain-specific, good for any state machine in domain

 Each model is a concrete subclass of abstract class – Initialisers for tables

 Each kind of action has its own type in DSM language – Own sub-generator per action type – Generates "real" code from model data – Actions can be specified in many ways • closures, blocks, inner classes, functions invoked by name, cases switched by id, if..elseif by id etc.

© MetaCase/JPT

157

Java for wristwatch applications  The same design language as in case of C implementation  Uses OO capabilities – subclass abstract state machine – class initialization and data from the model • State machine treated as data

 Based on domain framework – Framework can have different implementations • E.g. plain Java, micro Java, MIDP Java

© MetaCase/JPT

158

Code generator structure  Modular implementation to manage complexity

Report '_Roll’ Report 'Autobuild' /* Create compilation script, HTML files etc. */ subreport '_create make for ' :Generation target platform; run /* Create static shared Java components */ subreport '_JavaComponents' run

'get' do ~Set.() {id} '().' 'roll(METime.' :Time unit; ', ' if :Up? = 'T’ then 'true' else 'false' endif ', displayTime());' endreport

/* Create Java code for Watch models */ subreport '_Models' run /* Compile and execute */ filename subreport '_default directory' run 'alldone.txt' write close subreport '_compile and execute for ' :Generation target platform; run

endreport

© MetaCase/JPT

159

Code generator example [2/3]  Generating watch applications

Generator ouput public SimpleTime(Master master) { super(master); addTransition addTransition addTransition addTransition addTransition addTransition

("Start [Watch]", "", 0, "Show"); ("Show", "Mode", 0, "EditHours"); ("EditHours", "Set", a22_2926, "EditHours"); ("EditHours", "Mode", 0, "EditMinutes"); ("EditMinutes", "Set", a22_1405, "EditMinutes"); ("EditMinutes", "Mode", 0, "Show");

addStateDisplay("Show", -1, METime.MINUTE, d22_977); addStateDisplay("EditHours", METime.HOUR_OF_DAY, METime.MINUTE, d22_977); addStateDisplay("EditMinutes", METime.MINUTE, METime.MINUTE, d22_977); };

© MetaCase/JPT

160

Code generator example [2/3]  Generating watch applications

Generator ouput public SimpleTime(Master master) { super(master); addTransition addTransition addTransition addTransition addTransition addTransition

("Start [Watch]", "", 0, "Show"); ("Show", "Mode", 0, "EditHours"); ("EditHours", "Set", a22_2926, "EditHours"); ("EditHours", "Mode", 0, "EditMinutes"); ("EditMinutes", "Set", a22_1405, "EditMinutes"); ("EditMinutes", "Mode", 0, "Show");

addStateDisplay("Show", -1, METime.MINUTE, d22_977); addStateDisplay("EditHours", METime.HOUR_OF_DAY, METime.MINUTE, d22_977); addStateDisplay("EditMinutes", METime.MINUTE, METime.MINUTE, d22_977); };

© MetaCase/JPT

161

Code generator example [2/3]  Generating watch applications

Generator ouput public SimpleTime(Master master) { super(master); addTransition addTransition addTransition addTransition addTransition addTransition

("Start [Watch]", "", 0, "Show"); ("Show", "Mode", 0, "EditHours"); ("EditHours", "Set", a22_2926, "EditHours"); ("EditHours", "Mode", 0, "EditMinutes"); ("EditMinutes", "Set", a22_1405, "EditMinutes"); ("EditMinutes", "Mode", 0, "Show");

addStateDisplay("Show", -1, METime.MINUTE, d22_977); addStateDisplay("EditHours", METime.HOUR_OF_DAY, METime.MINUTE, d22_977); addStateDisplay("EditMinutes", METime.MINUTE, METime.MINUTE, d22_977); };

© MetaCase/JPT

162

Code generator example [3/3]  Generating watch applications

Generator output public Object perform(int methodId) { switch (methodId) { case a22_2926: getclockOffset().roll(METime.HOUR_OF_DAY, true, displayTime()); return null; case a22_1405: getclockOffset().roll(METime.MINUTE, true, displayTime()); return null; case d22_977: return getclockTime(); } return null; }

© MetaCase/JPT

163

Code generator example [3/3]  Generating watch applications

Generator output public Object perform(int methodId) { switch (methodId) { case a22_2926: getclockOffset().roll(METime.HOUR_OF_DAY, true, displayTime()); return null; case a22_1405: getclockOffset().roll(METime.MINUTE, true, displayTime()); return null; case d22_977: return getclockTime(); } return null; }

© MetaCase/JPT

164

Code generator example [3/3]  Generating watch applications

Generator output public Object perform(int methodId) { switch (methodId) { case a22_2926: getclockOffset().roll(METime.HOUR_OF_DAY, true, displayTime()); return null; case a22_1405: getclockOffset().roll(METime.MINUTE, true, displayTime()); return null; case d22_977: return getclockTime(); } return null; }

© MetaCase/JPT

165

Code generator example [3/3]  Generating watch applications

Generator output public Object perform(int methodId) { switch (methodId) { case a22_2926: getclockOffset().roll(METime.HOUR_OF_DAY, true, displayTime()); return null; case a22_1405: getclockOffset().roll(METime.MINUTE, true, displayTime()); return null; case d22_977: return getclockTime(); } return null; }

© MetaCase/JPT

166

Code generator example [3/3]  Generating watch applications

Generator output public Object perform(int methodId) { switch (methodId) { case a22_2926: getclockOffset().roll(METime.HOUR_OF_DAY, true, displayTime()); return null; case a22_1405: getclockOffset().roll(METime.MINUTE, true, displayTime()); return null; case d22_977: return getclockTime(); } return null; }

© MetaCase/JPT

167

Code generator example [3/3]  Generating watch applications

Generator output public Object perform(int methodId) { switch (methodId) { case a22_2926: getclockOffset().roll(METime.HOUR_OF_DAY, true, displayTime()); return null; case a22_1405: getclockOffset().roll(METime.MINUTE, true, displayTime()); return null; case d22_977: return getclockTime(); } return null; }

© MetaCase/JPT

168

The importance of autobuild  Autobuild = move straight from model to live testing 1. Generate all files from models and submodels 2. Run compiler on files 3. Start resulting application • In emulator if necessary • With execution visually traced back in model if possible

 Saves time, avoids manual errors, keeps consistency  Most importantly, saves brain from context switching – Models describe application on high level – Never need to think about code

 Autobuild via batch or makefile – Good reference for batch and shell scripts: www.ss64.com

© MetaCase/JPT

169

Domain Framework

© MetaCase/JPT

170

Domain framework DSM environment

 Provides an interface for the target platform and programming language  Raise the level of abstraction on the platform side  Achieved by atomic implementations of commonalities and variabilities – especially for behaviour – implementation as templates and components

 Include interface for the code to be generated – often the only needed part for static variation (e.g. for XML schema)

© MetaCase/JPT

DOMAINSPECIFIC Modelling LANGUAGE

DOMAINSPECIFIC CODE GENERATOR

DOMAIN FRAMEWORK

171

Manual coding vs Wizards vs DSM

HandWritten Code

Wizard

Model

Generated & HandWritten Code

Generated Code

Domain Framework Component Framework

Component Framework

Component Framework

Platform

Platform

Platform

© MetaCase/JPT

172

Why have a domain framework?  Removing duplication from generated code – Automates reuse, cf. duplication in hand-written code – Edit long sections of static code in IDE, not generator

 DSM takes broader + longer view  bigger framework – Code:1 developer writes 2 file dialog calls per application • Not worth writing a framework function  copy & paste

– DSM: 1 developer writes 1 generator for 100 applications • Big payback from framework function: size, simplicity

 Hiding platform details – Bypassing bugs and platform evolution – Extending a framework from one platform to many • Model, generators and generated code remain the same • Interface to framework remains the same • Just switch in a different framework version © MetaCase/JPT

173

Combining generated code and other code  Different levels of code to integrate – Other generated code – Domain framework, components, platform functions – Hand-made code

 Separation of generated and non-generated code – Best to keep them in separate files (or sections in files)

 Generated code… – – – –

can can can can

call existing code, instantiate data structures be called from existing code be subclassed from existing code form base classes

Model

Generated code

Non-generated © MetaCase/JPT

174

Tools for DSM creation and use 

6 ways to get the tools we need for DSM 1. 2. 3. 4. 5. 6.



Good tools minimize resource use (few man-weeks) – – –



Write own modelling tool from scratch Write own modelling tool based on frameworks Metamodel, generate modelling tool skeleton, add code Metamodel, generate full modelling tool over a framework Metamodel, output configuration for generic modelling tool Integrated modelling and metamodelling environment creating modelling tools and generators data-like, not code guide in DSM creation allow you to test DSM throughout domain design process

Good tools allow DSML to change and reflect changes – –

to modelling tools to design models already made

© MetaCase/JPT

175

Summary  Domain-specific modelling radically improves productivity (5-10x)  DSM leverages expert developers’ abilities to empower other developers in a team  Good language workbenches provide a costeffective way to create DSM infrastructure  Anything you can write & model, you can generate – If you can’t write it yet, you can’t generate it yet

 Building DSM solutions is great fun – The ultimate refactoring!

 More info: – www.DSMforum.org – www.DSMbook.com © MetaCase/JPT

176

Thank you! Questions?

Contact: Juha-Pekka Tolvanen [email protected] www.metacase.com/blogs/jpt © MetaCase/JPT

177

Further reading  Kelly, S., Pohjonen, R., Worst Practices for DomainSpecific Modeling, IEEE Software, July/Aug, 2009.  Kärnä et al. Evaluating the use of DSM in practice, OOPSLA workshop on Domain-Specific Modeling, 2009  Kelly, S., Tolvanen, J.-P., Domain-Specific Modeling: Enabling Full Code Generation, Wiley, 2008. http://dsmbook.com  Kieburtz, R. et al., A Software Engineering Experiment in Software Component Generation, Proceedings of 18th International Conference on Software Engineering, Berlin, IEEE Computer Society Press, 1996.  Pohjonen, R., Kelly, S., Domain-Specific Modeling, Dr. Dobb's, 8, 2002.  Safa, The Making Of User-Interface Designer: A Proprietary DSM Tool, OOPSLA workshop on Domain-Specific Modeling, 2007  Weiss, D., Lai, C. T. R., Software Product-line Engineering, Addison Wesley Longman, 1999. © MetaCase/JPT

178

Suggest Documents