...
Key Concepts
Strategies for Project Success
...
groovyconsole
cma1_1.groovy
Expando objects allow dynamic class definitions with attributes, behavior and event handlers for async smart object testing
These tests provide the same interactivity when executed as async REST API event handlers so a solution model can be dynamically tested and validated for behavior before it's coded
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
//================================== //x2031 groovy smart objects w expando events println "//x2031 ex-expando-events-gen-v1.groovy" println """ ex-expando-events-gen-v1.groovy x111c groovy bound property example - https://blog.mrhaki.com/2009/08/groovy-goodness-bound-and-constrained.html shows the flexibility of event messaging in requirements modeling using bound property event listeners in the example the toyota vehicle has bound properties the owner listens for changes in the toyota properties this model has 2 independent objects, one listening for events on the other in a single Java process for modeling purposes, this simple method can proxy the concept of independent processes linked by event messages jim mason - jmason900@yahoo.com """ import groovy.beans.* class Owner implements PropertyChangeListener { boolean carPriceChange Car aCar String name String toString() { "owner = $this.name and the car is ${aCar.toString()} " } public void propertyChange(PropertyChangeEvent e) { String propertyName = e.getPropertyName(); println "debug>> e = ${e.toString()}" if ("price".equals(propertyName)) { println "\n Event >> Owner $this.name detected car ${e.source.brand} price changed to: ${e.newValue} from: ${e.oldValue} \n\t the car is ${aCar.toString()} \n" } if ("automatic".equals(propertyName)) { println "\n Event >> Owner $this.name detected car ${e.source.brand} automatic transmission type changed to: ${e.newValue} from: ${e.oldValue} \n\t the car is ${aCar.toString()} \n" } } } @Bindable class Car { int numberOfDoors @Vetoable String model @Vetoable String brand @Bindable boolean automatic @Bindable double price String toString() { "[Car details => brand: '${brand}', model: '${model}', #doors: '${numberOfDoors}', automatic: '${automatic}', price: '${price}']" } } import groovy.beans.* import java.beans.* def toyota = new Car(brand: 'Toyota', model: 'Verso', price: 28919, numberOfDoors: 5, automatic: false) toyota.propertyChange = { if (it.propertyName == 'price') { println "The price has changed. Inform sales the new price is '${it.newValue}'." } } toyota.vetoableChange = { PropertyChangeEvent pce -> if (pce.propertyName == "brand") { if (!(pce.newValue in ['Toyota', 'Lexus'])) { throw new PropertyVetoException('New value is not Toyota or Lexus', pce) } } if (pce.propertyName == "model") { if (pce.newValue ==~ /.*\d+.*/) { throw new PropertyVetoException('No numbers in model names allowed.', pce) } } } toyota.price = 30995 assert 30995 == toyota.price toyota.brand = 'Lexus' assert 'Lexus' == toyota.brand try { toyota.brand = 'AUDI' assert false: 'We should not be able to set this value.' } catch (PropertyVetoException e) { assert true println " could not set brand to AUDI. car brand is ${toyota.brand}" } try { toyota.model = 'A5' assert false: 'We should not be able to set this value.' } catch (PropertyVetoException e) { assert true println " could not set model to A5. car model is ${toyota.model}" } def anOwner = new Owner() anOwner.name = "Jim" println anOwner.toString() anOwner.aCar = toyota println "\n car was purchased \n ${ anOwner.toString() } \n " // how to add an propertyChangeListener to an object in groovy toyota.addPropertyChangeListener(anOwner) toyota.automatic = true toyota.price = 44000 toyota.automatic = true // no pce fired because the attribute state is the same |
...