Aan de hand van het oplossen van het sudoku spel zal ik proberen de link tussen smalltalk en extreme pogramming te leggen. Hoe meer ik smalltalk begrijp, hoe meer ik zie dat het geen toeval is dat extreme programming vanuit de smalltalk hoek komt en dat het er heel anders uitgezien zou hebben als het door het java kamp bedacht zou zijn.
Het sudoku spel bestaat uit een buitenste 3×3 matrix gevuld met 3×3 matrixes gevuld met cellen waarin de nummers 1 tot en met 9 geplaatst kunnen worden. Een nummer kan binnen een matrix, rij of kolom maar een keer gebruikt worden.
Elke cel heeft dus initieel 9 mogelijke waarden. Aan de hand van reeds geplaatste nummers binnen zijn bereik, kun je een aantal mogelijkheden elimineren. Dit is dan de eerste stap.
Maar voordat we daaraan beginnen moeten we natuurlijk wel eerst een spel hebben. Ik begin heel simpel: ik wil gewoon de nummers kunnen plaatsen in een 9×9 matrix.
Vanuit een workspace roep ik de volgende code aan.
game := Matrix new: 9.
Een constructor met een argument zoals we dit in java ook kennen. Het geeft mij een 9×9 matrix waarin ik alles kan plaatsen. Mijn zojuist gecreeerde game object kan ik bekijken in de object inspector en ik zie daar inderdaad een matrix met 81 nil waarden. Het matrix object slaat de cellen intern blijkbaar in een array op en niet in een matrix.
Als ik nu een nummer wil plaatsen voer ik opnieuw wat code in de workspace uit, terwijl ik de inspector window open hou:
game at:1 at: 1 put: 7.
En we zien dat de inspector zich vanzelf update en een waarde 7 bijkomt in de matrix. Het een voor een invoeren van een cel waarde is misschien omslachtig. Is er een mogelijkheid om in een keer een hele regel toe te voegen? Inderdaad er is ook een atRow: put: methode. Aan onze game object kunnen we hiermee een berichtje sturen:
game atRow: 1 put: #( 7 9 nil nil nil nil 3 nil nil).
In de inspector zie je de wijzigingen weer verschijnen. En laten we maar meteen de rest van de nummers in de puzzel vullen door wat berichtjes te sturen naar onze game:
game atRow: 2 put: #(nil nil nil nil nil 6 9 nil nil).
game atRow: 3 put: #( 8 nil nil nil 3 nil nil 7 6 ).
game atRow: 4 put: #(nil nil nil nil nil 5 nil nil 2 ).
game atRow: 5 put: #(nil nil 5 4 1 8 7 nil nil).
game atRow: 6 put: #( 4 nil nil 7 nil nil nil nil nil).
game atRow: 7 put: #( 6 1 nil nil 9 nil nil nil 8 ).
game atRow: 8 put: #(nil nil 2 3 nil nil nil nil nil).
game atRow: 9 put: #(nil nil 9 nil nil nil nil 5 4 ).
Conversaties
Code schrijven in smalltalk kun je zien als converseren met het systeem. Een soort instant messaging met een bot. Je stuurt een regel smalltalk en krijgt ‘immediate feedback’. Een kortere cyclus bestaat niet.
Natuurlijk schrijf je niet je hele applicatie op deze manier, maar kijken hoe het systeem zich gedraagt is wezenlijk onderdeel van het software ontwikkelings proces. Doe eens een diff aan het einde van de dag met de code aan het begin van de dag. Valt wel mee, wat er allemaal gewijzigd is. Waar heeft al die tijd in gezeten? Juist, in kijken hoe het systeem zich gedraagt. jUnit helpt je wel om snel feedback te krijgen en ik misbruik mijn jUnit testcase ook weleens als een soort workspace, maar dan moet je nog eerst nog je assertions schrijven of de debugger gebruiken om in je objecten te kunnen kijken.
Feedback is een van de kern waarden van Extreme Programming en dit wordt in smalltalk van nature ondersteund. De volgende stap is om het gewenste gedrag vast te leggen in een testcase, in de originele sUnit!!