Upload
tomas-kukol
View
375
Download
3
Embed Size (px)
DESCRIPTION
Prezentace o praktickém použití programovacího jazyka Smalltalk na FIT ČVUT z 10.12.2012.
Citation preview
Smalltalk prakticky
Tomáš [email protected]
Agenda
• Představení
• Co je Smalltalk (aneb trocha teorie neuškodí)
• Smalltalk prakticky
• Diskuse?
Představení
• Od roku 2003 pracuji v ČSOB jako vývojář SW
• Od roku 2008 jsem Certified Scrum Master
• Programuji v C#, Java a Smalltalk
– Agilní vývoj pomocí metodiky Scrum
–Webové projekty
– Pokusy o Test Driven Development (TDD)
• NUnit, JUnit, SUnit
• WebWalker
Malá upozornění
• Jsem fanoušek Smalltalk – Seznámení se Smalltalk na vysoké škole u doc.
Merunky v roce 1993
• Prezentace může být subjektivní
– Jsem fanoušek Smalltalk
• Prezentace nemusí být úplně seriozní
– Jsem člověk z praxe
Co je Smalltalk• Programovací jazyk
– Jednoduchý a mocný objektový jazyk (všechno jsou objekty )
–Má pouze několik pravidel a je jednoduché se ho naučit
– Velmi stabilní syntaxe (platí od roku 1980)
• Objektová databáze (a také aplikační platforma!)
– Ukládá kompletní objekty a jejich vazby
– Aplikační kód je uložen současně s objekty
– Všechno se programuje v jediném programovacím jazyce Smalltalk
• Velmi produktivní vývojové prostředí
– Obsahuje všechny nástroje pro rychlý vývoj aplikací
– Ideální pro webové a mobilní aplikace, REST webové služby, backendové databáze pro mobilní aplikace
Otázky do diskuse
• Co má Smalltalk navíc oproti jazykům C# a Java (dále jen „ostatní“)?
• Co ostatní jazyky nemají?
• Co naopak nemá Smalltalk?
Méně je někdy více
• Žádné konstruktory
• Žádné definice typů
• Žádná rozhraní (interfaces)
• Žádné jmenné prostory/private/protected
• Žádné šablony (templates)
• Žádný boxing/unboxing
Ostatní (zatím) nemají
• Posílání zpráv
– Objekt zprávě rozumí a vyvolá příslušnou metodu
– Objekt zprávě nerozumí a zavolá metodu „zprávě nerozumím“
• Metody „become“
– Všechny instance určitého objektu lze jednoduše vyměnit za jiný objekt
• Persistenci objektů v rámci jazyka
– Viz Pharo Smalltalk nebo GemStone Smalltalk
Přejděme k praktickým věcem
• Prototypový projekt pro FT ČSOB (zkouší obchodní a technologické inovace)
– Nativní mobilní aplikace pro Android a iPad
– HTML5 mobilní aplikace pro všechny platformy
– V rámci technologických inovací byl mimo jiné zvolen Smalltalk
• Backend pro nativní mobilní aplikace (objektová databáze, REST webové služby), webová aplikace pro správu aplikačních dat, HTML5 mobilní aplikace
Jak to vypadá? Co jsme udělali?
Použité technologie na backendu
• Linux
• Apache
– Proxy, load balancing, URL rewriting, obsluha statických souborů (obrázky, JS, CSS, HTML stránky)
• Pharo Smalltalk 1.4
– REST webové služby, HTML5 mobilní aplikace
• Pharo Smalltalk 1.3
– Objektová databáze Magma
Co je Pharo Smalltalk?
• Nová moderní implementace Smalltalku vycházející ze Squeaku orientovaná na vývoj a provoz webových a mobilních aplikací
• Dostupná pod licencí MIT
• Běží na Mac, Linux, Android, iOS, Windows
• Skvělá aktivní komunita
• Rychlý průběžný vývoj
• Spousty skvělých knihoven a nástrojů
• Dostupná a připravena na komerční provoz!
Použité frameworky v rámci Pharo
• Seaside 3.0
• Magritte 3
• Seaside-REST
• NeoCSV
• Seaside-JQuery
• JQueryMobile
• Zinc
• Fuel (součást Marea)
• Magma (klient a server)
• Monticello
• Metacello
• FileTree
• Gitocello
Seaside• Webový framework naprogramovaný ve Smalltalku (vývoj probíhá
přímo ve Pharo)– Umožňuje psaní webových aplikací v desktopovém stylu díky call:/answer: nebo
show:/answer: přístupu
– Používá continuations (struktura, která obsahuje běžící
– Řeší problém tlačítka „Zpět“
• Nepoužívá šablony jako ASP.NET MVC nebo JSP, ale komponenty (což jsou běžné třídy/objekty)– Je možné je dědit, skládat a testovat v kódu
– Každá komponenta má vlastní stav a díky tomu nezávislé flow
– Metoda renderContentOn: slouží pro kreslení na HTML canvas
• Třídy mají prefix WA (Web Aubergine)
• Obsahuje podporu pro Javascript a integruje JQuery
– Snadno se rozšiřuje o další Javascriptové frameworky (Scriptaculous, JQueryMobile, Dojo Toolkit)
Seaside – důležité třídy
• WAComponent
– Vizuální komponenta
– Je třeba přepsat metodu renderContentOn:
• WATask
– Nevizuální komponenta určená pro psaní workflow (programu)
– Je třeba přepsat metodu go, do které se píše workflow, což může být klidně komunikace vizuálních komponent
–Metoda renderContentOn: se nepoužívá
• WASession
– Obsahuje session state pro každého uživatele
– Obvykle se dědí a tvoří na míru aplikace
Seaside – kreslení na HTML canvas1. SAWebPage>>renderContentOn: html
2. self isEmbedded
3. ifTrue: [ self renderWrappedMainOn: html ]
4. ifFalse: [
5. self renderWrappedPageOn: html.
6. self showDefaultRefresher
7. ifTrue: [ self renderDefaultRefresherOn: html ] ]
8. SAWebPage>>renderWrappedMainOn: html
9. html div
10. jqmContent;
11. with: [ self renderMainOn: html ]
12. SAListPage>>renderMainOn: html
13. self renderListTitleOn: html.
14. self renderListOn: html.
15. self renderButtonsOn: html
16. SAListPage>>renderListTitleOn: html
17. self showListTitle
18. ifTrue: [
19. html div
20. jqmHeader;
21. jqmTheme: 'a';
22. class: 'sa-bar-header-title';
23. with: [ self renderListTitleDetailOn: html ] ]
Seaside – ošetření události (callback)
1. SAContactDetailPage>>renderButtonsOn: html
2. self isEmployee
3. ifTrue: [
4. html div
5. with: [
6. html anchor
7. jqmButton;
8. jqmTheme: 'a';
9. callback: [ self showContact: self model ];
10. with: 'Detail kontaktu'.
11. html anchor
12. jqmButton;
13. jqmTheme: 'e';
14. callback: [ self editContact: self model ];
15. with: 'Editovat kontakt'.
16. html anchor
17. jqmButton;
18. callback: [ self deleteContact: self model ];
19. with: 'Smazat kontakt' ] ]
20. SAContactDetailPage>>editContact: contact
21. self call: (SAEditPage withModel: contact)
22. SAContactDetailPage>>showContact: contact
23. self call: (SADetailPage withModel: contact)
Seaside – stav v komponentě1. SAWebPage>>isEmployee
2. ^ self isUserLogged
3. ifTrue: [ self user isEmployee ]
4. ifFalse: [ false ]
5. SABaseComponentPage>>isUserLogged
6. ^ [ self user isNil not ]
7. on: Error
8. do: [ false ]
9. SABaseComponentPage>>user
10. ^ self session user
11. SALoginPage>>login: user
12. | userFromDb |
13. user isNil not
14. ifTrue: [
15. userFromDb := self database getUserWith: user login and: user password.
16. self session user: userFromDb.
17. self database chat loginUser: userFromDb.
18. self answer: userFromDb ]
19. ifFalse: [ self answer: nil ]
Magritte
• Meta framework, který popisuje objekty a jejich vazby pomocí tzv. „MADescriptions“. Díky tomu máme:
– Automaticky validované webové (Magritte-Seaside) a desktopové formuláře (Magritte-Morphic)
• Díky tomu aplikace obsahuje pouze dvě componenty pro GUI – SAEditPage a SADetailPage
– Automaticky validovaný vstup a výstup (import a export)
• JSON, XML, CSV
• Umožňuje bohaté rozšiřování Magritte
– Popisky, vizuální komponenty, import a export
– Obvykle Visitor pattern
Magritte – příklad popisu objektu1. SAArticle>>descriptionCreatedAt
2. <magritteDescription>
3. ^ SADateAndTimeDescription new
4. accessor: #createdAt;
5. label: 'Datum a čas publikace';
6. priority: 10;
7. beRequired;
8. yourself
9. SAArticle>>descriptionTitle
10. <magritteDescription>
11. ^ MAStringDescription new
12. accessor: #title;
13. label: 'Titulek';
14. priority: 20;
15. beRequired;
16. yourself
17. SAArticle>>descriptionText
18. <magritteDescription>
19. ^ MAMemoDescription new
20. accessor: #text;
21. label: 'Text komentáře';
22. priority: 40;
23. beRequired;
24. yourself
Magritte – tvorba webového formuláře
1. SAEditPage>>buildComponent
2. | container newComponent |
3. newComponent := self model asComponent
4. readonly: false;
5. addValidation;
6. addDecoration: (SAMessageDecoration withMessage: 'Editace záznamu');
7. addDecoration: (SAFormDecoration buttons: self buttons);
8. yourself.
9. newComponent
10. onAnswer: [ :answer |
11. self saveItem: answer.
12. self answer: answer ].
13. ^ newComponent
14. SAModel>>asComponent
15. ^ self asContainer asComponentOn: self
16. SAModel>>asContainer
17. ^ self magritteDescription
18. componentRenderer: SAJQMRenderer;
19. validator: SAChildParentValidatorVisitor
Seaside-REST
• Umožňuje tvorbu REST webových služeb
• Postavené na HTTP a JSON
• Snadno se používají
– Podpora v C#, Java, Javascript
• Snadno se ladí
– Podpora ve Firefoxu (Firebug) a Chrome (nástroj pro vývojáře)
Seaside-REST – příklady použití1. SARestfulFilter>>getMessagesFor: aClientSessionId of: ofCsi
2. <get>
3. <path: '/api/chat/messagesof?csi={aClientSessionId}&ofcsi={ofCsi}'>
4. <produces: 'text/json'>
5. | uuid ofUuid |
6. (self simplePing: aClientSessionId)
7. ifFalse: [ ^ nil asJson ].
8. uuid := SATool tryParseUUIDFrom: aClientSessionId.
9. ofUuid := SATool tryParseUUIDFrom: ofCsi.
10. ^ (self database chat getMessagesFor: uuid of: ofUuid) asJson
11. SARestfulFilter>>updateFxRates
12. <post>
13. <path: '/api/fxrates'>
14. | isOk |
15. isOk := self updateFxRates: self requestContext request rawBody.
16. self requestContext
17. respond: [ :response |
18. isOk
19. ifTrue: [
20. response
21. status: WAResponse statusOk;
22. contentType: WAMimeType textPlain;
23. nextPutAll: 'OK' ]
24. ifFalse: [
25. response
26. status: WAResponse statusNotFound;
27. contentType: WAMimeType textPlain;
28. nextPutAll: 'KO' ] ]
NeoCSV – práce s CSV soubory
• Umožňuje jednoduše importovat a exportovat CSV soubory
• Podporuje validaci a přímé načítání do aplikačních objektů
NeoCSV – příklady použití1. SADatabase>>fillForecastsFromStream: aStream
2. self forecasts addAll: (self getForecastsFromStream: aStream)
3. SADatabase>>getForecastsFromStream: aStream
4. | reader array |
5. reader := NeoCSVReader on: aStream.
6. reader next. "skip first line with headers"
7. reader
8. recordClass: SAForecast;
9. addField: #indicator:;
10. addField: #time:;
11. addField: #source:;
12. addField: #numberAsString:;
13. addField: #country:;
14. addField: #unit:;
15. addField: #period:;
16. addField: #type:;
17. addField: #descriptionCZ:.
18. array := reader upToEnd.
19. array do: [ :each | each initializeId ].
20. ^ array
Příklad CSV souboruIndicator,Time,Source,Value,Country,Unit,Period,Type,DescriptionCZ
GDP yoy,2011Q2,Bloomberg,2.1,CZ,%,Q,chng,Reálný HDP
GDP yoy,2011Q1,Bloomberg,2.8,CZ,%,Q,chng,Reálný HDP
GDP yoy,2010Q4,Bloomberg,2.7,CZ,%,Q,chng,Reálný HDP
JQueryMobile
• Umožňuje tvorbu HTML webových aplikací, které vypadají jako mobilní aplikace
• Samozřejmě, že se programuje ve Smalltalku a ne v Javascriptu
• Přehledný návod pro Seaside je zde:http://jquerymobile.seasidehosting.st/
JQueryMobile – příklady použití1. SAGridPage>>renderGridInJqmDivsOn: html
2. html div
3. jqmContainerTwoColumn;
4. with: [
5. html div
6. jqmColumnOne;
7. with: [ html render: (pages at: 1) ].
8. html div
9. jqmColumnTwo;
10. with: [ html render: (pages at: 2) ] ].
11. html div
12. jqmContainerTwoColumn;
13. with: [
14. html div
15. jqmColumnOne;
16. with: [ html render: (pages at: 3) ].
17. html div
18. jqmColumnTwo;
19. with: [ html render: (pages at: 4) ] ]
Zinc
• Moderní implementace HTTP klienta a serveru ve Smalltalku
• Součástí je i Zinc Web Server
Fuel
• Velmi rychlá serializace a deserializace objektového grafu do streamu (paměť, disk, ZIP stream)
• Součást frameworku Marea
Fuel – příklady použití1. SADatabase>>simpleBackupToFileNamed: aFilename
2. FLSerializer serialize: self default toFileNamed: aFilename
3. SADatabase>>simpleRestoreFromFileNamed: aFilename
4. ^ (FLMaterializer materializationFromFileNamed: aFilename) root
5. SADatabase>>simpleBackupWithValidation
6. | newFilename hiddenFilename fd |
7. newFilename := SADatabase fileNameOfDefault.
8. hiddenFilename := '.' , newFilename.
9. fd := FileDirectory default.
10. (fd fileExists: hiddenFilename)
11. ifTrue: [ fd deleteFileNamed: hiddenFilename ].
12. self simpleBackupToFileNamed: hiddenFilename.
13. (self isBackupValidOfFileNamed: hiddenFilename)
14. ifTrue: [
15. fd copyFileWithoutOverwriteConfirmationNamed: hiddenFilename toFileNamed: newFilename.
16. (fd fileExists: hiddenFilename)
17. ifTrue: [ fd deleteFileNamed: hiddenFilename ] ]
18. ifFalse: [ self error: 'Nepodařilo se ověřit zálohu.' ]
Monticello
• Balíčkovací systém pro Smalltalk
• Podobné jako DPKG nebo RPM na Linuxu
• Balíčky se tvoří na základě kategorií tříd
• Již Monticello umožňuje snadné verzování zdrojového kódu
Metacello
• Nadstavba nad Monticello, která přináší hlídání závislostí a podmíněné nahrávání balíčků
• Podobné jako apt-get (Synaptic) nebo yum na Linuxu
• Používají se tzv. „ConfigurationOfXyz“
– Nahráním jediného Metacello balíčku můžeme nahrát desítky závislých balíčků
Diskuse?