TDDB84: Lecture 7 State, Visitor, Interpreter, DSL
Creational Prototype SOLID Structural Facade Flyweight Behavioral State Visitor Interpreter Summary The exam LE7 LE8 LE9 Several different patterns GUI apps LA4 LA5
Creational Prototype Structural Facade Flyweight SOLID How language design can make design patterns disappear (open classes, multiple dispatch, eval) Behavioral Domain-specific languages State Visitor Interpreter Fluent API:s as a demo of the Façadeprinciple Program to an interface, e.g. {1,2,3}.ShouldNot().Contain(EvenNumber) Summary The exam LE7 LE8 LE9 Several different patterns GUI apps LA4 LA5
State
dispense with ball NoQuarter insert HasQuarter turncrank Sold eject dispense without ball SoldOut
public void insertquarter() { if (state == HAS_QUARTER) { System.out.println("You can't insert another quarter"); } else if (state == NO_QUARTER) { state = HAS_QUARTER; System.out.println("You inserted a quarter"); } else if (state == SOLD_OUT) { System.out.println("You can't insert a quarter, the machine is sold out"); } else if (state == SOLD) { System.out.println("Please wait, we're already giving you a gumball"); } } public void ejectquarter() { if (state == HAS_QUARTER) { System.out.println("Quarter returned"); state = NO_QUARTER; } else if (state == NO_QUARTER) { System.out.println("You haven't inserted a quarter"); } else if (state == SOLD) { System.out.println("Sorry, you already turned the crank"); } else if (state == SOLD_OUT) { System.out.println("You can't eject, you haven't inserted a quarter yet"); } }
Demo
State: consequences
State: consequences + Allows classes to react differently deping on internal state
State: consequences + Allows classes to react differently deping on internal state + Describes all interaction results in one place, for each state
State: consequences + Allows classes to react differently deping on internal state + Describes all interaction results in one place, for each state - Introduces a lot of subclasses even if only parts of the behavior is modified
Visitor
tostring() (b+4) * a a=3 * eval() 18 b=2 getvars() [a,b] + a... b 4
Enter Visitor * + a b 4 Provide a traversal mechanism Let all nodes implement a single method for accepting an external visitor and calling the visitor with themselves as the argument Let the visitor do the job
Demo
Encapsulate what varies Program to an interface, not to an implementation Favor composition over inheritance Classes should be open for extension but closed for modification Don t call us, we ll call you Dep on abstractions, do not dep on concrete classes Classes should only have one reason to change Strive for loosely-coupled design
Compare GoF p. 335 & Head First p. 629 Who should do the traversal? Why does it matter?
Visitor: consequences
Visitor: consequences + A visitor can add functionality to an existing compound structure
Visitor: consequences + A visitor can add functionality to an existing compound structure - The traversal mechanism may be hidden from the visitor if the compound structure does not expose it, so the visitor cannot infer the relationship between one node and others
Visitor: consequences + A visitor can add functionality to an existing compound structure - - The traversal mechanism may be hidden from the visitor if the compound structure does not expose it, so the visitor cannot infer the relationship between one node and others Adding parts to the compound structure affects all visitors
Interpreter
Interpreter Composite Operation() Operation()
BNF Grammar expression ::= plus minus variable number plus ::= expression expression '+' minus ::= expression expression '-' variable ::= 'a' 'b' 'c'... 'z' digit = '0' '1'... '9' number ::= digit digit number Nonterminal expression Terminal expression
Demo
Any sufficiently complicated C or Fortran program contains an ad-hoc, informally-specified, bug-ridden, slow implementation of half of CommonLisp Philip Greenspun So what about using.. the language itself?
DSL Domain-Specific Language
require 'models/users' migrate do user=users.new user.person_nr=112233 user.name='ola' user.save!
class Migrator include Dsl require 'models/users' migrate do user=users.new user.person_nr=112233 user.name='ola' user.save! def initialize(f) load(f) def migrate(&block) @migration=block def run @migration.call
class Migrator require 'models/users' migrate do user=users.new user.person_nr=112233 user.name='ola' user.save! class Migrator include Dsl def initialize(f) load(f) def migrate(&block) @migration=block def run @migration.call
class Migrator def initialize require 'models/users' migrate do user=users.new user.person_nr=112233 user.name='ola' user.save! class Migrator include Dsl def initialize(f) load(f) def migrate(&block) @migration=block def run @migration.call
class Migrator def initialize require 'models/users' migrate do user=users.new user.person_nr=112233 user.name='ola' user.save! class Migrator include Dsl def initialize(f) load(f) def migrate(&block) @migration=block def run @migration.call
Interpreter: consequences
Interpreter: consequences + If your program does not have access to an interpreter/compiler for the language you write your program in, this is the design pattern for you
Interpreter: consequences + If your program does not have access to an interpreter/compiler for the language you write your program in, this is the design pattern for you + Allows you to create retricted languages with domain-specific features
Interpreter: consequences - + If your program does not have access to an interpreter/compiler for the language you write your program in, this is the design pattern for you + Allows you to create retricted languages with domain-specific features Introduces a lot of overhead for only moderately useful scripting constructs.
Exam question 4. Choose the best description of a Proxy: a) Allows substituting objects for other objects at run time b) Provides decoupling of an abstraction from its implementation c) Is used to transparently ext objects with functionality such as deferred initialization d) Can add responsibilities of objects dynamically at run time without affecting other objects