rOOts 2005: Sample code and slides for a New Discipline of Programming Trygve Reenskaug, Department of informatics, University of Oslo, Norway http://heim.ifi.uio.no/~trygver 1 NetworkTester code ....................................................................................... 2 1 class NetworkTester ........................................................................................................... 2 1 public methods ................................................................................................................... 2 1 private methods .................................................................................................................. 2 2 SimpleComponent code ................................................................................. 4 2 class SimplePort ................................................................................................................. 4 2 SimplePort methodsFor: 'public' ........................................................................................ 4 2 SimplePort methodsFor: 'private' ....................................................................................... 4 2 class SimpleActivity .......................................................................................................... 4 2 SimpleActivity methodsFor: 'accessors' ............................................................................ 4 2 SimpleActivity methodsFor: 'component' .......................................................................... 5 2 SimpleActivity methodsFor: 'private' ................................................................................ 5 3 MasteredComponent Code ........................................................................... 6 3 MaestroPort class ............................................................................................................... 6 3 MaestroPort methodsFor: 'public' ...................................................................................... 6 3 MaestroPort methodsFor: 'private' ..................................................................................... 6 3 MaestroMaestro class ........................................................................................................ 6 3 MaestroMaestro methodsFor: 'port' ................................................................................... 6 3 MaestroMaestro methodsFor: 'private' .............................................................................. 7 3 MaestroActivity class ........................................................................................................ 7 3 MaestroActivity methodsFor: 'accessors' .......................................................................... 7 3 MaestroActivity methodsFor: 'component' ........................................................................ 7 3 MaestroActivity methodsFor: 'private' .............................................................................. 8 4 DeclarativeComponent code .......................................................................... 9 4 DeclarativeActivity class ................................................................................................... 9 4 DeclarativeActivity methodsFor: 'accessors' ..................................................................... 9 4 DeclarativeActivity methodsFor: 'component' .................................................................. 9 4 DeclarativeActivity methodsFor: 'private' ......................................................................... 9 4 DeclarativePort class ........................................................................................................ 10 4 DeclarativePort methodsFor: 'public' ............................................................................... 10 4 DeclarativePort methodsFor: 'private' .............................................................................. 10 4 DeclarativeMaestro class ................................................................................................. 10 4 DeclarativeMaestro methodsFor: 'network definition' ..................................................... 10 4 DeclarativeMaestro methodsFor: 'network operations' ................................................... 10 4 DeclarativeMaestro methodsFor: 'private' ....................................................................... 11 4 DeclarativeBase class ...................................................................................................... 11 4 DeclarativeBase methodsFor: 'data definition' ................................................................ 11 4 DeclarativeBase methodsFor: 'external schemas' ............................................................ 11 4 DeclarativeBase methodsFor: 'private' ............................................................................ 12 5 Slides .............................................................................................................. 15 BabyUML draft of April 22, 2005 11:33 am BabyUMLTOC.fm 1 1 NetworkTester CODE class NetworkTester Object subclass: #NetworkTester instanceVariableNames: 'activitiesData simpleComponent maestroComponent declarativeComponent public methods test " NetworkTester new test. " self initialize. " Test SimpleComponent. " simpleComponent := SimplePort new initialize. self runPort: simpleComponent. self checkPort: simpleComponent. " Test MaestroComponent. " maestroComponent := MaestroPort new initialize. self runPort: maestroComponent. self checkPort: simpleComponent. " Test DeclarativeComponent. " declarativeComponent := DeclarativePort new initialize. self runPort: declarativeComponent. self checkPort: simpleComponent. " Inspect. " self inspect. private methods checkPort: port port activityNames = (activitiesData collect: [:dict | dict at: 'name']) ifFalse: [self error]. activitiesData do: [:indict || outdict | outdict := port activityDescriptorFor: (indict at: 'name'). indict keys = outdict keys ifFalse: [self error: ‘different activities’] indict keys do: [:key | (indict at: key) = (outdict at: key) ifFalse: [self error: key]]. createDictA | dict | dict := Dictionary new. dict at: 'name' put: 'actA'. dict at: 'duration' put: 2. dict at: 'earlyStart' put: 1. dict at: 'earlyFinish' put: 2. dict at: 'successors' put: #('actC'). dict at: 'predecessors' put: #(). activitiesData add: dict. 2 71-NetworkTesterCode.fm BabyUML draft of April 22, 2005 11:36 am createDictB | dict | dict := Dictionary new. dict at: 'name' put: 'actB'. dict at: 'duration' put: 7. dict at: 'earlyStart' put: 1. dict at: 'earlyFinish' put: 7. dict at: 'successors' put: #('actD'). dict at: 'predecessors' put: #(). activitiesData add: dict. createDictC | dict | dict := Dictionary new. dict at: 'name' put: 'actC'. dict at: 'duration' put: 3. dict at: 'earlyStart' put: 3. dict at: 'earlyFinish' put: 5. dict at: 'successors' put: #('actD'). dict at: 'predecessors' put: #('actA'). activitiesData add: dict. createDictD | dict | dict := Dictionary new. dict at: 'name' put: 'actD'. dict at: 'duration' put: 2. dict at: 'successors' put: #(). dict at: 'predecessors' put: #('actC' 'actB'). dict at: 'earlyStart' put: 8. dict at: 'earlyFinish' put: 9. activitiesData add: dict. initialize super initialize. activitiesData := Set new. self createDictA. self createDictB. self createDictC. self createDictD. runPort: port " Define activities. " activitiesData do: [:dict | port newActivity: (dict at: 'name') duration: (dict at: 'duration')]. " Define dependencies. " activitiesData do: [:dict | (dict at: #predecessors) do: [:predNam | port addDependencyFrom: predNam to: (dict at: 'name')]. " Frontload. " port frontload: 1. BabyUML draft of April 22, 2005 11:36 am 71-NetworkTesterCode.fm 3 2 SimpleComponent CODE class SimplePort Object subclass: #SimplePort instanceVariableNames: 'activities' SimplePort methodsFor: 'public' activityDescriptorFor: actNam ^(self activityNamed: actNam) activityDescriptor. activityNamesSorted ^(activities collect: [:act | act name]) asSortedCollection asArray addDependencyFrom: predNam to: succNam (self activityNamed: predNam) successor: (self activityNamed: succNam) frontload: firstWeek activities do: [:act | act resetFrontload]. (activities select: [:act | act predecessors isEmpty]) do: [:act | act frontload: firstWeek] newActivity: actNam duration: dur | activity | activity := SimpleActivity new initialize. activity name: actNam. activity duration: dur. activities add: activity. SimplePort methodsFor: 'private' activityNamed: actNam ^activities detect: [:act | act name = actNam] defaultSymbolColor ^Color lightBlue initialize super initialize. activities := Set new. class SimpleActivity Object subclass: #SimpleActivity instanceVariableNames: 'name duration earlyStart predecessors successors counter' SimpleActivity methodsFor: 'accessors' duration: dur duration := dur name ^name 4 72-SimpleComponentCode.fm BabyUML draft of April 22, 2005 11:33 am name: aString name := aString predecessor: pred (predecessors includes: pred) ifFalse: [predecessors add: pred. pred successor: self]. predecessors ^predecessors successor: succ (successors includes: succ) ifFalse: [successors add: succ. succ predecessor: self]. SimpleActivity methodsFor: 'component' activityDescriptor | dict | dict := Dictionary new. dict at: 'name' put: name. dict at: 'duration' put: duration. dict at: 'earlyStart' put: earlyStart. dict at: 'earlyFinish' put: self earlyFinish. dict at: 'successors' put: (successors collect: [:act | act name]) asArray. dict at: 'predecessors' put: (predecessors collect: [:act | act name]) asArray. ^dict earlyFinish ^earlyStart + duration - 1. frontload: start earlyStart ifNil: [counter := 0. earlyStart := start] ifNotNil: [earlyStart := (start max: earlyStart)]. counter := counter+1. counter >= predecessors size ifTrue: [successors do: [:succ | succ frontload: self earlyFinish + 1]]. resetFrontload earlyStart := nil. SimpleActivity methodsFor: 'private' initialize super initialize. name := nil. duration := nil. earlyStart := nil. predecessors := Set new. successors := Set new. counter := 0. BabyUML draft of April 22, 2005 11:33 am 72-SimpleComponentCode.fm 5 3 MasteredComponent CODE MaestroPort class Object subclass: #MaestroPort instanceVariableNames: 'maestro publicSelectors' MaestroPort methodsFor: 'public' doesNotUnderstand: aMessage ^(publicSelectors includes: aMessage selector) ifTrue: [aMessage sendTo: maestro] ifFalse: [super doesNotUnderstand: aMessage] MaestroPort methodsFor: 'private' initialize super initialize. maestro := MaestroMaestro new initialize. publicSelectors := #(activityDescriptorFor: activityNamesSorted addDependencyFrom:to: frontload: newActivity:duration:) MaestroMaestro class Object subclass: #MaestroMaestro instanceVariableNames: 'activities' MaestroMaestro methodsFor: 'port' activityDescriptorFor: actNam ^(self activityNamed: actNam) activityDescriptor. activityNamesSorted ^(activities collect: [:act | act name]) asSortedCollection asArray addDependencyFrom: predNam to: succNam (self activityNamed: predNam) successor: (self activityNamed: succNam) frontload: firstWeek | frontActs | activities do: [:act | act resetFrontload]. [(frontActs := activities select: [:act | act earlyStart isNil and: [act predecessors allSatisfy: [:pred | pred earlyStart notNil]]]) notEmpty] whileTrue: [frontActs do: [:act | act frontload: firstWeek] ] newActivity: actNam duration: dur | activity | activity := MaestroActivity new initialize. activity name: actNam. activity duration: dur. activities add: activity. 6 73-MasteredComponentCode.fm BabyUML draft of April 22, 2005 11:33 am MaestroMaestro methodsFor: 'private' activityNamed: actNam ^activities detect: [:act | act name = actNam] initialize super initialize. activities := Set new. MaestroActivity class Object subclass: #MaestroActivity instanceVariableNames: 'name duration earlyStart predecessors successors' MaestroActivity methodsFor: 'accessors' duration: dur duration := dur earlyStart ^earlyStart name ^name name: aString name := aString predecessor: pred (predecessors includes: pred) ifFalse: [predecessors add: pred. pred successor: self]. predecessors ^predecessors successor: succ (successors includes: succ) ifFalse: [successors add: succ. succ predecessor: self] MaestroActivity methodsFor: 'component' activityDescriptor | dict | dict := Dictionary new. dict at: 'name' put: name. dict at: 'duration' put: duration. dict at: 'earlyStart' put: earlyStart. dict at: 'earlyFinish' put: self earlyFinish. dict at: 'successors' put: (successors collect: [:nod | nod name]) asArray. dict at: 'predecessors' put: (predecessors collect: [:nod | nod name]) asArray. ^dict earlyFinish ^earlyStart + duration - 1 BabyUML draft of April 22, 2005 11:33 am 73-MasteredComponentCode.fm 7 frontload: start earlyStart := start. predecessors do: [:pred | earlyStart := earlyStart max: pred earlyFinish + 1 ] resetFrontload earlyStart := nil. MaestroActivity methodsFor: 'private' initialize super initialize. name := nil. duration := nil. earlyStart := nil. predecessors := Set new. successors := Set new. 8 73-MasteredComponentCode.fm BabyUML draft of April 22, 2005 11:33 am 4 DeclarativeComponent CODE DeclarativeActivity class Object subclass: #DeclarativeActivity instanceVariableNames: 'name duration earlyStart' DeclarativeActivity methodsFor: 'accessors' duration ^duration duration: dur duration := dur earlyFinish ^self earlyStart + self duration - 1 earlyStart ^earlyStart name ^name name: aString name := aString DeclarativeActivity methodsFor: 'component' activityDescriptorInContext: context | dict | dict := Dictionary new. dict at: 'name' put: self name. dict at: 'duration' put: duration. dict at: 'earlyStart' put: earlyStart. dict at: 'earlyFinish' put: self earlyFinish. dict at: 'successors' put: ((context at: 'successors') collect: [:succ | succ name]) asArray. dict at: 'predecessors' put: ((context at: 'predecessors') collect: [:pred | pred name]) asArray. ^dict frontload: firstWeek inContext: context earlyStart := firstWeek. (context at: 'frontPreds') do: [:pred | earlyStart := (earlyStart max: (pred earlyFinish + 1))]. resetFrontloadInContext: context earlyStart := nil. DeclarativeActivity methodsFor: 'private' initialize super initialize. name := nil. duration := nil. earlyStart := nil. BabyUML draft of April 22, 2005 11:33 am74-DeclarativeComponentrCode.fm 9 DeclarativePort class Object subclass: #DeclarativePort instanceVariableNames: 'maestro publicSelectors' DeclarativePort methodsFor: 'public' doesNotUnderstand: aMessage ^(publicSelectors includes: aMessage selector) ifTrue: [aMessage sendTo: maestro] ifFalse: [super doesNotUnderstand: aMessage] DeclarativePort methodsFor: 'private' initialize super initialize. maestro := DeclarativeMaestro new initialize. publicSelectors := #(activityDescriptorFor: activityNamesSorted addDependencyFrom:to: frontload: newActivity:duration:). DeclarativeMaestro class Object subclass: #DeclarativeMaestro instanceVariableNames: 'base' DeclarativeMaestro methodsFor: 'network definition' addDependencyFrom: predNam to: succNam base addAssociationFrom: predNam to: succNam newActivity: actNam duration: dur base insertIntoActivities: #(#name #duration) values: {actNam. dur. DeclarativeMaestro methodsFor: 'network operations' activityDescriptorFor: actNam | context | context := base activityDescriptorContext: actNam. ^(context at: ‘activity’) activityDescriptorInContext: context. activityNamesSorted | context | context := base activitiesContext. ^((context at: 'activities') collect: [:act | act name]) asSortedCollection frontload: firstWeek | context | context := base activitiesContext. (context at: 'activities') do: [:act | act resetFrontloadInContext: context ]. [ context := base frontContext. (context at: 'frontAct') notNil ] whileTrue: [ (context at: 'frontAct') frontload: firstWeek inContext: context. ]. 10 74-DeclarativeComponentrCode.fm BabyUML draft of April 22, 2005 11:33 am DeclarativeMaestro methodsFor: 'private' initialize super initialize. base := DeclarativeBase new initialize. DeclarativeBase class Object subclass: #DeclarativeBase instanceVariableNames: 'activities associations' DeclarativeBase methodsFor: 'data definition' addAssociationFrom: predNam to: succNam (associations detect: [:assoc | assoc pred name = predNam and: [assoc succ name = succNam]] ifNone: [nil]) ifNil: [associations add: (DeclarativeBaseAssociation new initialize pred: (self activityNamed: predNam) succ: (self activityNamed: succNam) )] insertIntoActivities: keyNameArray values: valueArray | act | act := DeclarativeActivity new initialize. 1 to: keyNameArray size do: [:ind | act perform: ((keyNameArray at: ind) , ':') asSymbol withArguments: {valueArray at: ind} ]. activities add: act. DeclarativeBase methodsFor: 'external schemas' activitiesContext | dict | dict := Dictionary new. dict at: 'activities' put: activities. ^dict activityDescriptorContext: actNam | dict act | act := self activityNamed: actNam. dict := Dictionary new. dict at: 'activity' put: act. dict at: 'predecessors' put: (self predecessorsOf: act). dict at: 'successors' put: (self successorsOf: act). ^dict BabyUML draft of April 22, 2005 11:33 am74-DeclarativeComponentrCode.fm 11 frontContext | frontActs cntx thisAct | frontActs := activities select: [ :act | act earlyStart isNil and: [(self predecessorsOf: act) noneSatisfy: [:pred | pred earlyStart isNil]]. ]. cntx := Dictionary new. frontActs ifEmpty: [cntx at: 'frontAct' put: nil. cntx at: 'frontPreds' put: Array new] ifNotEmpty: [thisAct := frontActs anyOne. cntx at: 'frontAct' put: thisAct. cntx at: 'frontPreds' put: (self predecessorsOf: thisAct)]. ^cntx DeclarativeBase methodsFor: 'private' activityNamed: actNam ^activities detect: [:act | act name = actNam] initialize super initialize. activities := Set new. associations := Set new. predecessorsOf: act ^associations select: [:assoc | assoc succ = act] thenCollect: [:assoc | assoc pred] successorsOf: act ^associations select: [:assoc | assoc pred = act] thenCollect: [:assoc | assoc succ] 12 74-DeclarativeComponentrCode.fm BabyUML draft of April 22, 2005 11:33 am References [Blue book] Goldberg and Robson: Smalltalk-80. The language and implementation. Addison-Wesley 1983. ISBN 0-201-11371-6 [Dijkstra] Edsger Dijkstra: A Discipline of Programming, 1976 [DOI] The Digital Object Identifier System. The International DOI Foundation http://www.doi.org OR UUID????? [ECOOP-04] Trygve Reenskaug: Empowering People with BabyUML: A sixth Generation Programming Language. Opening talk, ECOOP 2004, Oslo. http://heim.ifi.uio.no/~trygver/2004/ECOOP-04/EcoopHandout.pdf [Eng62] Douglas C. Engelbart: Augmenting Human Intellect: A Conceptual Framework. Summary Report AFOSR-3223 under Contract AF 49(638)1024, SRI Project 3578 for Air Force Office of Scientific Research, Stanford Research Institute, Menlo Park, Ca., October 1962: [GOF] Gamma et.al.: Design Patterns. Addison Wesley1995 [Hay-03] David Hay: What Exactly IS a Data Model? DM Review Magazine, February 2003 Issue [Hy-60] T. Hysing: On the Use of Numerical Methods in the Design and Manufacture of Ships. Proceedings of the First International Congress of the International Federation of Automatic Control. Moscow, 1960. Butterworths, London. [Norman88] Donald A. Norman: The Design of Everyday Things. Doubleday, 1988 [ODMG] Cattell, Barry: The Object Data Standard: ODMG 3.0. Academic Press, London, 2000. ISBN 1-55860-647-4 [OORAM] Trygve Reenskaug: Working with objects. The OOram Software Engineering Method. Manning/Prentice Hall 1996. ISBN 0-13-452930-8. Out of print. Late draft may be downloaded here .PDF also Trygve Reenskaug et.al.: OORASS: Seamless Support for the Creation and Maintenance of Object-Oriented Systems. JOOP 27-41 (October 1992) [Pawson04] Richard Pawson: Naked Objects. PhD thesis, Trinity College, Dublin, 2004. [Ree-73] Trygve Reenskaug: Administrative control in the shipyard. ICCAS conference, Tokyo, 1973. Scanned by the author July 2003 to http://heim.ifi.uio.no/~trygver/1973/iccas/1973-08-ICCAS.pdf BabyUML draft of April 22, 2005 11:33 am 10-references.fm 13 [Schärli-03] Nathanael Schärli, Stéphane Ducasse, Oscar Nierstrasz and Andrew Black, Traits: Composable Units of Behavior, Proceedings ECOOP 2003 (European Conference on Object-Oriented Programming), LNCS, vol. 2743, Springer Verlag, July 2003, pp. 248—274. [UML] Unified Modeling Language: Superstructure. Version 2.0. Object Management Group. http://www.omg.org [Web Services] Web Services Architecture http://www.w3.org/TR/ws-arch/ [Kay77] Kay, Alan, Microelectronics and the Personal Computer, Scientific American, September 1977, p. 244. [Baby] Kulwinder S. Gill: The Manchester Small Scale Experimental Machine-"The Baby" http://www.computer50.org/mark1/new.baby.htm [Facit] Facit EDB 3 computer and ECM 64 carousell. Some documents are archived at The Norwegian Museum of Science and Technology, Autokon archive, Box #1. [HyRee-63]Thomas Hysing, Trygve Reenskaug: A system for computer plate preparation. Numerical methods applied to shipbuilding. A NATO Advanced Study Institute organized by Central Institute for Industrial Research and Det norske Veritas. Oslo-Bergen 1963. pp.324ff A copy of the proceedings is archived at The Norwegian Museum of Science and Technology, Autokon archive, Box #2. About the author Trygve Reenskaug, prof.em., Department of informatics, University of Oslo, Norway. mailto: trygver <at> ifi.uio.no http://heim.ifi.uio.no/~trygver 14 10-references.fm BabyUML draft of April 22, 2005 11:33 am 5 Slides Legal Notice How to Implement the BabyUML Discipline of Programming This presentation is copyright ©2001 Trygve Reenskaug Oslo, Norway. Workshop: How to do it. rOOts 2005 All rights reserved. Trygve Reenskaug University of Oslo Permission to make digital or hard copies of part or all of this work for personal or classroom use is granted without fee provided that the copies are not made for profit or commercial advantage and that copies bear this notice and full citation on the first page. http://heim.ifi.uio.no/~trygver trygver@ifi.uioi.no BabyUML workshop rOOts 2005 © Trygve Reenskaug 2005 22.04.2005 Slide 1 BabyUML workshop rOOts 2005 © Trygve Reenskaug 2005 Summary-1: Deal With Comprehensible Programs 22.04.2005 Slide 2 Summary-2: Divide and Conquer with Components «Port» All Programs ProductionControl «Component» Accounting MaterialsManagement «Port» All Meaningful Programs «Component» sampleNet actA(2) actC(3) actD (2) <2203> actB(7) All Comprehensible Programs «Port» Two ways of constructing asoftware design (C.A.R. Hoare) Make it 1) so simple that there are obviously no deficiencies «Port» Design Manufacturing «Port» 2) so complicated that there are no obvious deficiencies. BabyUML workshop rOOts 2005 © Trygve Reenskaug 2005 22.04.2005 Slide 3 BabyUML workshop rOOts 2005 Example: Example: «interface» newActivity: aString duration: anInteger addDependencyFrom: actName1 to: actName2 frontload: firstWeek activityNames activityDescriptor: actName actC(3) actD(2) actB(7) sampleNetTester ActA 22.04.2005 Slide 4 First Example: Example: Frontloading a simple network Activity Network Frontloading actA(2) © Trygve Reenskaug 2005 test required == newActivity:duration: (aString, anInteger) provided «port» <0321> «SimpleComponent» «port» <0724> «MasteredComponent» «port» <1931> «DeclarativeComponent» sampleNet ActB ActC sampleNet ActD 1 BabyUML workshop rOOts 2005 2 3 © Trygve Reenskaug 2005 4 5 6 7 week 22.04.2005 BabyUML draft of April 22, 2005 11:33 am 8 9 Slide 5 80-Slides.fm BabyUML workshop rOOts 2005 © Trygve Reenskaug 2005 sampleNet 22.04.2005 Slide 6 15 NetworkTester NetworkTester class definition initialize Object subclass: #NetworkTester instanceVariableNames: 'activitiesData simpleComponent maestroComponent declarativeComponent’ initialize super initialize. activitiesData := Set new. self createDictA. self createDictB. self createDictC. self createDictD. BabyUML workshop rOOts 2005 BabyUML workshop rOOts 2005 © Trygve Reenskaug 2005 22.04.2005 Slide 7 NetworkTester © Trygve Reenskaug 2005 22.04.2005 Slide 8 NetworkTester createDictD test self initialize. " Test SimpleComponent. “ createDictD | dict | dict := Dictionary new. == at:put: (’name’, ’actD’) dict at: 'name' put: 'actD'. dict at: 'duration' put: 2. dict at: 'successors' put: #(). dict at: 'predecessors' put: #('actC' 'actB'). dict at: 'earlyStart' put: 8. dict at: 'earlyFinish' put: 9. activitiesData add: dict. simpleComponent := SimplePort new initialize. self runPort: simpleComponent. self checkPort: simpleComponent. " Test MaestroComponent. " maestroComponent := MaestroPort new initialize. self runPort: maestroComponent. self checkPort: simpleComponent. " Test DeclarativeComponent. " declarativeComponent := DeclarativePort new initialize. self runPort: declarativeComponent. self checkPort: simpleComponent. " Inspect. " self inspect. BabyUML workshop rOOts 2005 © Trygve Reenskaug 2005 22.04.2005 Slide 9 BabyUML workshop rOOts 2005 NetworkTester © Trygve Reenskaug 2005 22.04.2005 Slide 10 NetworkTester runPort: runPort: port checkPort: checkPort: port " Define activities. " activitiesData do: [:dict | port newActivity: (dict at: 'name') duration: (dict at: 'duration')]. port activityNames = (activitiesData collect: [:dict | dict at: 'name']) ifFalse: [self error]. activitiesData do: [:indict || outdict | outdict := port activityDescriptorFor: (indict at: 'name'). indict keys = outdict keys ifFalse: [self error: ‘different activities’] indict keys do: [:key | (indict at: key) = (outdict at: key) ifFalse: [self error: key]]. " Define dependencies. " activitiesData do: [:actdict | (actdict at: #predecessors) do: [:predNam | port addDependencyFrom: predNam to: (dict at: 'name')]. ]. " Frontload. " port frontload: 1. BabyUML workshop rOOts 2005 16 © Trygve Reenskaug 2005 22.04.2005 Slide 11 80-Slides.fm BabyUML workshop rOOts 2005 © Trygve Reenskaug 2005 22.04.2005 Slide 12 BabyUML draft of April 22, 2005 11:33 am Object structure NetworkTester Test SimpleComponent «interface» newActivity: aString duration: anInteger addDependencYFrom: actName1 to: actName2 frontload: firstWeek activityNames ActivityDescriptor: actName sampleNetTester required test BabyUML workshop rOOts 2005 © Trygve Reenskaug 2005 22.04.2005 Slide 13 BabyUML workshop rOOts 2005 SimplePort • What are activities? • What are their predecessors? • How does it frontload: ? © Trygve Reenskaug 2005 «MasteredComponent» «port» <1931> «DeclarativeComponent» © Trygve Reenskaug 2005 sampleNet sampleNet 22.04.2005 Slide 14 • What are activities? • What are predecessors and successors ? • Do all activities frontload the same way ? 22.04.2005 Slide 15 BabyUML workshop rOOts 2005 © Trygve Reenskaug 2005 22.04.2005 Slide 16 SimpleActivity class definition predecessor: predecessor: pred Object subclass: #SimpleActivity instanceVariableNames: 'name duration earlyStart predecessors successors counter' predecessor: pred (predecessors includes: pred) ifFalse: [predecessors add: pred. pred successor: self ]. • What are activities? • What are predecessors and successors ? • Do all activities frontload the same way ? © Trygve Reenskaug 2005 «port» <0724> sampleNet frontload: start SimpleActivity BabyUML workshop rOOts 2005 «SimpleComponent» earlyStart ifNil: [counter := 0. earlyStart := start] ifNotNil: [earlyStart := (start max: earlyStart)]. counter := counter+1. counter >= predecessors size ifTrue: [successors do: [:succ | succ frontload: self earlyFinish + 1]]. frontload: firstWeek activities do: [:act | act resetFrontload]. (activities select: [:act | act predecessors isEmpty]) do: [:act | act frontload: firstWeek] BabyUML workshop rOOts 2005 «port» <0321> SimpleActivity class + frontLoad: firstWeek Object subclass: #SimplePort instanceVariableNames: 'activities‘. provided 22.04.2005 BabyUML draft of April 22, 2005 11:33 am Slide 17 80-Slides.fm • • • • What are activities? - OK What are predecessors and successors - OK Do all activities frontload the same way ? What about predecessors/successors integrity ? BabyUML workshop rOOts 2005 © Trygve Reenskaug 2005 22.04.2005 Slide 18 17 The objects of the SimpleComponent test The Simple Component «Component» <0321> port members actD name = ' actD' duration = 2 earlyStart = 8 earlyFinish = 9 predecessors = { actB . ' actC .} successors { } frontload ( firstWeek : Integer) example- white5 frontload (1) sampleNet <2203> «port» < 0321 > newActivity (name : String, duration : Integer) addDependency (from, to : String) frontload (firstWeek : Integer) activityNames () : String [] {sorted} activityDescriptor (name: String) : Dictionary <2200> actA <2261> actB <2272> actC <2203> actD (2) (7) (3) (2) frontload (1) frontload (3) frontload (6) frontload (1) BabyUML workshop rOOts 2005 firstWeek : Integer) Bowl of noodles? frontload (8) © Trygve Reenskaug 2005 22.04.2005 Slide 19 Test Mastered Component «interface» newActivity: aString duration: anInteger addDependencYFrom: actName1 to: actName2 frontload: firstWeek activityNames ActivityDescriptor: actName sampleNetTester test BabyUML workshop rOOts 2005 required 22.04.2005 Slide 20 «SimpleComponent» «port» <0321> sampleNet provided «port» <0724> «MasteredComponent» «port» <1931> «DeclarativeComponent» © Trygve Reenskaug 2005 sampleNet sampleNet 22.04.2005 Slide 21 MaestroPort doesNotUnderstand: aMessage ^(publicSelectors includes: aMessage selector) ifTrue: [aMessage sendTo: maestro] ifFalse: [super doesNotUnderstand: aMessage] 22.04.2005 Slide 22 | frontActs | activities do: [:act | act resetFrontload]. [ (frontActs := activities select: [:act | act earlyStart isNil and: [act predecessors allSatisfy: [:pred | pred earlyStart notNil]]) ] notEmpty ] whileTrue: [frontActs do: [:act | act frontload: firstWeek] ] • xxx? • An implementation of the facade pattern 22.04.2005 © Trygve Reenskaug 2005 MaestroMaestro initialize super initialize. maestro := MaestroMaestro new initialize. publicSelectors := #(activityDescriptorFor: activityNamesSorted addDependencyFrom:to: frontload: newActivity:duration: © Trygve Reenskaug 2005 BabyUML workshop rOOts 2005 frontload: frontload: firstWeek Object subclass: #MaestroPort instanceVariableNames: 'maestro publicSelectors' 18 © Trygve Reenskaug 2005 The MasteredComponent class + essential methods BabyUML workshop rOOts 2005 BabyUML workshop rOOts 2005 Slide 23 80-Slides.fm BabyUML workshop rOOts 2005 © Trygve Reenskaug 2005 22.04.2005 Slide 24 BabyUML draft of April 22, 2005 11:33 am MaestroActivity The Mastered Component frontload: frontload: start Interaction frontload: start earlyStart := start. predecessors do: [:pred | earlyStart := earlyStart max: pred earlyFinish + 1 ] <2322> maestro <1131> actA <2646>actB (2) (7) <2813>actC <144>actD (3) (2) frontload: 1 frontload: 1 frontload: 1 frontload: 1 frontload: 1 • xxx? BabyUML workshop rOOts 2005 © Trygve Reenskaug 2005 22.04.2005 Slide 25 BabyUML workshop rOOts 2005 © Trygve Reenskaug 2005 22.04.2005 Slide 26 The Coffee Machine Design Problem: version 1 Centralized Delegated Delegated Centralized BabyUML workshop rOOts 2005 © Trygve Reenskaug 2005 22.04.2005 Slide 27 BabyUML workshop rOOts 2005 © Trygve Reenskaug 2005 Three Schema Architecture External External External External External Schema Schema Schema Schema Schema sampleNetTester test required «port» <0321> «SimpleComponent» «port» <0724> «MasteredComponent» provided «port» <1931> Slide 28 Separation of concern Test Declarative Component «interface» newActivity: aString duration: anInteger addDependencYFrom: actName1 to: actName2 frontload: firstWeek activityNames ActivityDescriptor: actName 22.04.2005 sampleNet sampleNet «DeclarativeComponent» sampleNet How are they used? External Mapping What are the component members? Conceptual Schema Internal Mapping External ExternalSchema Schema How are they implemented? Thanks to Ragnar Normann BabyUML workshop rOOts 2005 © Trygve Reenskaug 2005 22.04.2005 BabyUML draft of April 22, 2005 11:33 am Slide 29 80-Slides.fm BabyUML workshop rOOts 2005 © Trygve Reenskaug 2005 22.04.2005 Slide 30 19 The Declarative Component The Declarative Component Layered – External Schemas Conceptual Schema «Component» sampleNet <0321> Activity name: pred duration: newActivityNamed: aString duration: anInteger * earlyStart addDependentFrom: actName1 to: actName2 frontloadFrom: firstWeekNo / earlyFinish activityNames activityDescriptorFor: actName * BabyUML workshop rOOts 2005 succ LayeredComponent © Trygve Reenskaug 2005 22.04.2005 Slide 31 BabyUML workshop rOOts 2005 frontAct maestro frontload: frontload: firstWeek [ context := base frontContext. (context at: 'frontAct') notNil activitiesContext ] activities whileTrue: resetEarlyStart [ (context at: 'frontAct') frontload: firstWeek inContext: context. ]. activities resetEarlyStart frontPreds loop queries «schema» Slide 32 context := base activitiesContext. (context at: 'activities') do: [:act | act resetFrontloadInContext: contextmaestro ]. frontload : firstWeek activitiesContext «Collaboration» frontContext 22.04.2005 DeclarativeMaestro The Declarative Component frontloading sequence diagram frontload: firstWeek © Trygve Reenskaug 2005 frontContext [frontAct notNil] Network frontAct loop frontPreds frontContext frontload: firstWeek [frontAct notNil] Activity name: duration: earlyStart /earlyFinish * succ frontAct pred * frontPreds : frontload: firstWeek inContext: context example-frontload8 BabyUML workshop rOOts 2005 © Trygve Reenskaug 2005 22.04.2005 Slide 33 BabyUML workshop rOOts 2005 DeclarativeActivity 22.04.2005 Slide 34 DeclarativeBase frontload: frontload: firstWeek inContext: inContext: context frontload: firstWeek inContext: context earlyStart := firstWeek. (context at: 'frontPreds') do: [:pred | earlyStart := (earlyStart max: (pred earlyFinish + 1))]. © Trygve Reenskaug 2005 frontContext (ODMG) define query frontActivities as select act from activities where act.earlyStart.isNil and ( select succ from dependencies where succ = act and pred.earlyStart.isNil) ) isEmpty • xxx? BabyUML workshop rOOts 2005 20 © Trygve Reenskaug 2005 22.04.2005 Slide 35 80-Slides.fm BabyUML workshop rOOts 2005 © Trygve Reenskaug 2005 22.04.2005 Slide 36 BabyUML draft of April 22, 2005 11:33 am frontContext (Smalltalk) Smalltalk) frontActs := activities select: [:act | act earlyStart isNil and: [(self predecessorsOf: act) noneSatisfy: [:pred | pred earlyStart isNil]]. ]. cntx := Dictionary new. frontActs ifEmpty: [cntx at: 'frontAct' put: nil. cntx at: 'frontPreds' put: Array new] ifNotEmpty: [thisAct := frontActs anyOne. cntx at: 'frontAct' put: thisAct. cntx at: 'frontPreds' put: (self predecessorsOf: thisAct)]. ^cntx BabyUML workshop rOOts 2005 © Trygve Reenskaug 2005 22.04.2005 Slide 37 Summary: A Discipline of Programming Combining Three Architectures Input Output Input Output Input Central Processing Unit Memory Central Processing Unit Output Tape Tape Memory Tape CPU-Centered Communication Bus DeclarativeBase Central Processing Unit Disk Memory Disk CommunicationCentered Storage-Centered Conceptual schema (classes) Databases Components [1G L]Binary HTTP / HTML Methods [4GL]schema Schema(collaboration) Language External Interactions [2GL] Assembly [3GL++] C++, Java, C # (NIAM)(classes) [3GL]FORTRAN, Algol Internal schema Procedures BabyUML workshop rOOts 2005 Thank You © Trygve Reenskaug 2005 22.04.2005 Slide 38 More details …. http://www.ifi.uio.no/~trygver mailto: trygver ‘at’ ifi.uio.no Trygve Reenskaug: Towards a New Discipline of Programming with the BabyUML Language Laboratory. http://heim.ifi.uio.no/~trygver/2005/babyuml/BabyUML.book.pdf More info at [UML] Unified Modeling Language: Superstructure. Version 2.0. Object Management Group. Document ptc/04-10-02 or later http://www.omg.org heim.ifi.uio.no/~trygver Edsger Dijkstra: A Discipline of Programming, 1976 Trygve Reenskaug: Empowering People with BabyUML: A sixth GenerationProgramming Language. Opening talk, ECOOP 2004, Oslo. http://heim.ifi.uio.no/~trygver/2004/ECOOP-04/EcoopHandout.pdf Model Driven Architecture See: http://www.omg.org/mda/ Cattell, Barry: The Object Data Standard: ODMG 3.0. Academic Press, London, 2000. ISBN 1-55860-647-4 Erik Arisholm and Dag Sjøberg, A Controlled Experiment with Professionals to Evaluate the Effect of a Delegated versus Centralized Control Style on the Maintainability of Object-Oriented Software, Simula Research Laboratory Technical Report 2003-6 http://www.simula.no/publication_one.php?publication_id=601 Alistair Cockburn: The Coffee Machine Design Problem: Part 1. http://alistair.cockburn.us/crystal/articles/cmdp1/coffeemachineproblem1.htm BabyUML workshop rOOts 2005 © Trygve Reenskaug 2005 22.04.2005 BabyUML draft of April 22, 2005 11:33 am Slide 39 80-Slides.fm BabyUML workshop rOOts 2005 © Trygve Reenskaug 2005 22.04.2005 Slide 40 21