martin fowler dsl-intro
TRANSCRIPT
-
7/30/2019 Martin Fowler Dsl-Intro
1/24
IntroducingDomain Specific
LanguagesMARTIN FOWLER
http://martinfowler.com
1Tuesday, April 7, 2009
http://martinfowler.com/http://martinfowler.com/http://martinfowler.com/ -
7/30/2019 Martin Fowler Dsl-Intro
2/24
DSLs are everywhere
graphviz
ant
rakeLINQ
Hibernate Query Language
regular expressions
FITSQL
struts-config.xmlJMock expectations
rails validationsmake
CSS
2Tuesday, April 7, 2009
-
7/30/2019 Martin Fowler Dsl-Intro
3/24
Should they be used more often?
Can they be done better?
3Tuesday, April 7, 2009
-
7/30/2019 Martin Fowler Dsl-Intro
4/24
Close the door
Open the seconddraw down
Turn on thebedside light
Opening the door resets thesystem and locks the panel
Opening my Secret Panel
4Tuesday, April 7, 2009
-
7/30/2019 Martin Fowler Dsl-Intro
5/24
5Tuesday, April 7, 2009
-
7/30/2019 Martin Fowler Dsl-Intro
6/24
State
Machine
Transition
name
State
1 1source target
namecode
Abstract Event
Command
Event
!
action
! !
!
1
trigger!
1 start
!
!reset events
6Tuesday, April 7, 2009
-
7/30/2019 Martin Fowler Dsl-Intro
7/24
Event doorClosed = new Event("doorClosed", "D1CL");
Event drawOpened = new Event("drawOpened", "D2OP");Event lightOn = new Event("lightOn", "L1ON");
Event doorOpened = new Event("doorOpened", "D1OP");Event panelClosed = new Event("panelClosed", "PNCL");
Command unlockPanelCmd = new Command("unlockPanel", "PNUL");Command lockPanelCmd = new Command("lockPanel", "PNLK");Command lockDoorCmd = new Command("lockDoor", "D1LK");
Command unlockDoorCmd = new Command("unlockDoor", "D1UL");
machine.addResetEvents(doorOpened);
State idle = new State("idle");State activeState = new State("active");
State waitingForLightState = new State("waitingForLight");
State waitingForDrawState = new State("waitingForDraw");State unlockedPanelState = new State("unlockedPanel");
StateMachine machine = new StateMachine(idle);
idle.addTransition(doorClosed, activeState);idle.addAction(unlockDoorCmd);
idle.addAction(lockPanelCmd);
activeState.addTransition(drawOpened, waitingForLightState);activeState.addTransition(lightOn, waitingForDrawState);
waitingForLightState.addTransition(lightOn, unlockedPanelState);
waitingForDrawState.addTransition(drawOpened, unlockedPanelState);
unlockedPanelState.addAction(unlockPanelCmd);
unlockedPanelState.addAction(lockDoorCmd);
unlockedPanelState.addTransition(panelClosed, idle);
7Tuesday, April 7, 2009
-
7/30/2019 Martin Fowler Dsl-Intro
8/24
8Tuesday, April 7, 2009
-
7/30/2019 Martin Fowler Dsl-Intro
9/24
events
doorClosed D1CLdrawOpened D2OP
lightOn L1ONdoorOpened D1OP
panelClosed PNCL
end
resetEvents
doorOpenedend
commands
unlockPanel PNULlockPanel PNLK
lockDoor D1LK
unlockDoor D1UL
end
state idle
actions {unlockDoor lockPanel}doorClosed => active
end
state active
drawOpened => waitingForLight
lightOn => waitingForDrawend
state waitingForLight
lightOn => unlockedPanelend
state waitingForDraw
drawOpened => unlockedPanel
end
state unlockedPanel
actions {unlockPanel lockDoor}
panelClosed => idleend
9Tuesday, April 7, 2009
-
7/30/2019 Martin Fowler Dsl-Intro
10/24
event :doorClosed, "D1CL"
event :drawOpened, "D2OP"event :lightOn, "L1ON"
event :doorOpened, "D1OP"
event :panelClosed, "PNCL"
command :unlockPanel, "PNUL"
command :lockPanel, "PNLK"command :lockDoor, "D1LK"
command :unlockDoor, "D1UL"
resetEvents :doorOpened
state :idle do
actions :unlockDoor, :lockPaneltransitions :doorClosed => :active
end
state :active dotransitions :drawOpened => :waitingForLight,
:lightOn => :waitingForDrawend
state :waitingForLight do
transitions :lightOn => :unlockedPanelend
state :waitingForDraw do
transitions :drawOpened => :unlockedPanelend
state :unlockedPanel doactions :unlockPanel, :lockDoor
transitions :panelClosed => :idle
end
10Tuesday, April 7, 2009
-
7/30/2019 Martin Fowler Dsl-Intro
11/24
state idleactions {unlockDoor lockPanel}
doorClosed => active
end
state :idle doactions :unlockDoor, :lockPanel
transitions :doorClosed => :active
end
External DSL Internal DSL(aka Embedded DSL)
XML as carr ier syntax11Tuesday, April 7, 2009
-
7/30/2019 Martin Fowler Dsl-Intro
12/2412Tuesday, April 7, 2009
-
7/30/2019 Martin Fowler Dsl-Intro
13/24
public class BasicStateMachine extends StateMachineBuilder {
Events doorClosed, drawOpened, lightOn, panelClosed;
Commands unlockPanel, lockPanel, lockDoor, unlockDoor;
States idle, active, waitingForLight, waitingForDraw, unlockedPanel;ResetEvents doorOpened;
protected void defineStateMachine() {
doorClosed. code("D1CL");
drawOpened. code("D2OP");lightOn. code("L1ON");panelClosed.code("PNCL");
doorOpened. code("D1OP");
unlockPanel.code("PNUL");
lockPanel. code("PNLK");lockDoor. code("D1LK");
unlockDoor. code("D1UL");
idle.actions(unlockDoor, lockPanel)
.transition(doorClosed).to(active);
active
.transition(drawOpened).to(waitingForLight)
.transition(lightOn). to(waitingForDraw);
waitingForLight.transition(lightOn).to(unlockedPanel)
;
waitingForDraw
.transition(drawOpened).to(unlockedPanel);
unlockedPanel.actions(unlockPanel, lockDoor)
.transition(panelClosed).to(idle);
}}
13Tuesday, April 7, 2009
-
7/30/2019 Martin Fowler Dsl-Intro
14/24
State idle = new State("idle");
State activeState = new State("active");idle.addTransition(doorClosed, activeState);
idle.addAction(unlockDoorCmd);
idle.addAction(lockPanelCmd);
activeState.addTransition(drawOpened, waitingForLightState);
activeState.addTransition(lightOn, waitingForDrawState);
idle
.actions(unlockDoor, lockPanel)
.transition(doorClosed).to(active)
;
active
.transition(drawOpened).to(waitingForLight)
.transition(lightOn). to(waitingForDraw)
;
Command-Query API
Fluent API
14Tuesday, April 7, 2009
-
7/30/2019 Martin Fowler Dsl-Intro
15/24
Domain Specific Language (noun)
a computer programming language of limitedexpressiveness focused on a particular domain
languagecomputer programming
limited expressivenessfocused on a particular domain
15Tuesday, April 7, 2009
-
7/30/2019 Martin Fowler Dsl-Intro
16/24
DSL
Script Parse
Semantic Model
Execute
Generate
Code
optional
16Tuesday, April 7, 2009
-
7/30/2019 Martin Fowler Dsl-Intro
17/24
Oslo
DSL Tools
Charles Simonyi
made Intel liJ andReSharper
open source
eclipsemature
Language Workbenches
17Tuesday, April 7, 2009
-
7/30/2019 Martin Fowler Dsl-Intro
18/24
Source Editing
javac hal.java
18Tuesday, April 7, 2009
-
7/30/2019 Martin Fowler Dsl-Intro
19/24
Model Repository
generate
Projectional Editing
projections
19Tuesday, April 7, 2009
-
7/30/2019 Martin Fowler Dsl-Intro
20/24
Source Projectional
DSL Tools
Diagrams
Structured Text
Oslo
20Tuesday, April 7, 2009
-
7/30/2019 Martin Fowler Dsl-Intro
21/24
input =~ /\d{3}-\d{3}-\d{4}/
21Tuesday, April 7, 2009
-
7/30/2019 Martin Fowler Dsl-Intro
22/24
p.question {
font-style: italic;
font-weight: bold;
}
p.answer { padding: 0 0 0 1em }
22Tuesday, April 7, 2009
-
7/30/2019 Martin Fowler Dsl-Intro
23/24
write
read23Tuesday, April 7, 2009
-
7/30/2019 Martin Fowler Dsl-Intro
24/24
For more information...http://www.martinfowler.com/bliki/DomainSpecificLanguage.html
MARTIN
FOWLER
http://martinfowler.com
http://martinfowler.com/http://martinfowler.com/http://www.martinfowler.com/bliki/DomainSpecificLanguage.htmlhttp://www.martinfowler.com/bliki/DomainSpecificLanguage.html