Who am I? • Academics – PhD Student, University of Bern Magritte • Industrial Lukas Renggli – Software Engineer, netstyle.ch • Communities renggli@iam.unibe.ch Software Composition Group – Author of Magritte and Pier, and some University of Bern other open-source projects – Contributor to Seaside and Squeak 2 Agenda • Introduction Magritte • Examples • Implementation Introduction • Customization Describe once, • Hands-on Exercises Get everywhere 3
What is it useful for? Why is it useful? • Introspection • Object persistency • Describe once, get everywhere. • Reflection • Object indexing • Automatically build views and editors, • Documentation • Object setup process queries and store objects. • Viewer building • Object verification • Extensibility of classes is ensured. • Editor building • Object adaption • Fully customizable, e.g., it is possible to • Report building • Object customization replace any automatically generated view • Data validation with a modified or customized one. and much more • Query processing 5 6 Why is it cool? What is it used for? (1) • Pier – � a meta-described collaborative web- • Describe once, get everywhere. application framework. • Be more productive. • Aare – � a proprietary workflow definition • Lower coupling in software components. and runtime engine with integrated • Do more, with less code. document management system. • Conrad – a conference registration and • Do more, with less hacking. management system. 7 8
What is it used for? (2) • Seaside-Hosting – � free hosting service for non-commercial Seaside applications. • DigiSens – � a proprietary monitoring system for high precision sensors. • cmsbox – the next generation of a content Pier management system. Content Management 9 10 Seaside-Hosting Aare Hosting Application Workflow System 11 12
Address Book Person Address title street Magritte firstName 1 plz lastName place Examples 1 homeAddress canton 1 officeAddress 0..1 picture Phone Describe once, birthday * kind Get everywhere 1 phoneNumbers number 14 “Describing” the Address Defining Descriptions street: StringDescription • A object is described by adding methods named #description* (naming convention) Address plz: NumberDescription street to the class-side answering different 1000 - 9999 plz :Container description-entities. place canton place: StringDescription • All descriptions will be automatically collected and put into a container description when canton: SingleOptionDescription sending #description to the object. Solothurn, Aargau, • Descriptions can be built programmatically. Zuerich, Schwyz, Glarus, ... 15 16
Describing the Address Seaside Interface result := self call: (aModel asComponent MAAddressModel class>>descriptionStreet addValidatedForm; ^ MAStringDescription auto: 'street' label: 'Street' priority: 10. yourself). MAAddressModel class>>descriptionPlz ^ (MANumberDescription auto: 'plz' label: 'PLZ' priority: 20) min: 1000 max: 9999; yourself. MAAddressModel class>>descriptionPlace ^ MAStringDescription auto: 'place' label: 'Place' priority: 30. MAAddressModel class>>descriptionCanton ^ (MASingleOptionDescription auto: 'canton' label: 'Canton' priority: 40) options: #( 'Bern' 'Solothurn' 'Aargau' 'Zuerich' 'Schwyz' 'Glarus' ...); reference: MAStringDescription new; beSorted; yourself. 17 18 Morphic Interface Address Book result := aModel asMorph addButtons; Person Address addWindow; title street callInWorld. firstName 1 plz lastName place 1 homeAddress canton 1 officeAddress 0..1 picture Phone birthday * kind 1 phoneNumbers number 19 20
Describing the Person (1) Describing the Person (2) MAPersonModel class>>descriptionTitle MAPersonModel class>>descriptionHomeAddress ^ (MASingleOptionDescription auto: 'title' label: 'Title' priority: 10) ^ (MAToOneRelationDescription auto: 'homeAddress' label: 'Home Address') options: #( 'Mr.' 'Mrs.' 'Ms.' 'Miss.' ); classes: (Array with: MAAddressModel); yourself. yourself. MAPersonModel class>>descriptionFirstName MAPersonModel class>>descriptionOfficeAddress ^ (MAStringDescription auto: 'firstName' label: 'First Name' priority: 20) ^ (MAToOneRelationDescription auto: 'officeAddress' label: 'Office Address') beRequired; classes: (Array with: MAAddressModel); yourself. yourself. MAPersonModel class>>descriptionLastName MAPersonModel class>>descriptionPicture ^ (MAStringDescription auto: 'lastName' label: 'Last Name' priority: 30) ^ (MAFileDescription auto: 'picture' label: 'Picture') beRequired; addCondition: [ :value | value isImage ] labelled: 'Image expected'; yourself. yourself. 21 22 Describing the Person (3) Recapitulation • Put your descriptions on the class-side MAPersonModel class>>descriptionPhoneNumbers ^ (MAToManyRelationDescription auto: 'phoneNumbers' label: 'P. Numbers') according to the naming-convention . classes: (Array with: MAPhoneNumber); • Ask your object for its description-container default: Array new; yourself. by sending #description . MAPersonModel class>>descriptionBirthday • Ask your object for an User-Interface by ^ MADateDescription auto: 'birthday' label: 'Birthday'. MAPersonModel class>>descriptionAge sending #asComponent or #asMorph . ^ (MANumberDescription selector: #age label: 'Age') beReadonly; yourself. 23 24
Descriptions • Problem – Smalltalk classes are all very different and require Magritte different configuration possibilities. • Example Implementation – Boolean and String are not polymorphic, therefor different code for printing, parsing, serializing, editing, Describe once, comparing, querying, etc. is necessary. Get everywhere • Solution – Introduce a descriptive hierarchy that can be instantiated, configured and composed. 26 Descriptions Descriptions a composite pattern to describe model-classes/-instances reference Description children Container ElementDesc. Accessor Condition Description ColorDesc. MagnitudeDesc. StringDesc. BooleanDesc. ReferenceDesc. children DateDesc. NumberDesc. OptionDesc. RelationDesc. Container ElementDesc. SingleDesc. MultipleDesc. ToOneDesc. ToManyDesc. StringDesc. BooleanDesc. 27 28
Accessors Accessors a strategy pattern • Problem to access model-entities – In Smalltalk data can be stored and accessed in very different ways. • Examples next, accessor Accessor – Accessor methods, chains of accessor methods, instance-variables, dictionaries, blocks, etc. Cascade Selector Dictionary Block Null • Solution – Provide a strategy pattern to be able to access the Auto data trough a common interface. 29 30 o: Object d: Description a: Accessor Conditions readUsing: d accessor read: o • Problems <strategy a> – End users want to visually compose conditions. – Instances of BlockContext can be hardly serialized. write: v using: d • Solution accessor – Introduce condition objects that can be composed write: v to: o to describe constraints on objects and data. <strategy a> 31 32
Conditions Exceptions a composite pattern • Problems to model constraints – Actions on the meta-model can fail. – Objects might not match a given meta-model. – Software would like to avoid errors. conditions Condition – End users want readable error messages. • Solution Composed Constant Selector BlockContext – Introduce an exception hierarchy knowing about the All Any None True False description, the failure and a human-readable error message. 33 34 Exceptions Mementos a composite pattern • Problems of smalltalk exceptions – Editing might turn a model (temporarily) invalid. – Canceling an edit shouldn’t change the model. – Concurrent edits of the same model should be Exception detected and (manually) merged. • Solution ValidationError – Introduce mementos that behave like the original MultipleErrors KindError RequiredError ConflictError RangeError model and that delay modifications until they are proven to be valid. 35 36
Mementos a proxy pattern to cache model-entities Magritte Customization description model Description Memento Object cache Describe once, Strait Cached Dictionary Get everywhere original Checked Dictionary 37 Building Descriptions Dynamic Descriptions Dynamically • Problem “ select descriptions “ MAPersonModel>>descriptionPrivateData – Instances might want to dynamically filter, add or ^ self description select: [ :each | #( title firstName lastName homeAddress ) modify their descriptions. includes: each accessor selector ]. – Users of a described object often don’t need all the “ add another description “ MAPersonModel>>descriptionWithEmail available descriptions . ^ self description copy • Solution add: (MAStringDescription auto: ‘email’ label: ‘E-Mail’ priority: 35); yourself. – Override #description on the instance-side to “ modify existing description “ MAPersonModel>>descriptionWithRequiredImage modify the default description-container. ^ self description collect: [ :each | each accessor selector = #picture – Add other methods returning different filtered or ifTrue: [ each copy beRequired ] ifFalse: [ each ] ]. modified sets of your descriptions. 39 40
Recommend
More recommend