WWW-ohjelmointi ANTTI SAND TIETA12

Samankaltaiset tiedostot
WWW-ohjelmointi ANTTI SAND TIETA12

Ohjelmistojen mallintaminen. Luento 11, 7.12.

JReleaser Yksikkötestaus ja JUnit. Mikko Mäkelä

SEPA REFAKTOROINTI Antti Ahvenlampi, 57408L Erik Hakala, 57509T

WWW-ohjelmointi ANTTI SAND TIETA12

Ohjelmoinnin jatkokurssi, kurssikoe

Concurrency - Rinnakkaisuus. Group: 9 Joni Laine Juho Vähätalo

Tapahtumakalenteri & Jäsentietojärjestelmä Ylläpito

IDL - proseduurit. ATK tähtitieteessä. IDL - proseduurit

ATK tähtitieteessä. Osa 3 - IDL proseduurit ja rakenteet. 18. syyskuuta 2014

ELM GROUP 04. Teemu Laakso Henrik Talarmo

Valppaan asennus- ja käyttöohje

Kanta PHR:n CapabilityStatement ja REST-API. Eeva Turkka

Arkkitehtuuri. Ylätason sovellusarkkitehtuuri

Operaattoreiden ylikuormitus. Operaattoreiden kuormitus. Operaattoreiden kuormitus. Operaattoreista. Kuormituksesta

Nebula pilvi 9.0 saatavuusalueiden välinen verkkoliikenne

Kanta PHR:n CapabilityStatement ja REST-API. Eeva Turkka

Visma Business AddOn Tositteiden tuonti. Käsikirja

Harjoitustyö: virtuaalikone

Yksikkötestaus. import org.junit.test; public class LaskinTest public void testlaskimenluonti() { Laskin laskin = new Laskin(); } }

Transkribuksen pikaopas

Amazon Web Services (AWS) on varmaankin maailman suosituin IaaS-tarjoaja. Lisäksi se tarjoaa erilaisia PaaS-kategoriaan kuuluvia palveluita.

Opintojakso TT00AA11 Ohjelmoinnin jatko (Java): 3 op Rajapinnat ja sisäluokat

Luento 5. Timo Savola. 28. huhtikuuta 2006

JWT 2016 luento 11. to klo Aulikki Hyrskykari. PinniB Aulikki Hyrskykari

815338A Ohjelmointikielten periaatteet Harjoitus 5 Vastaukset

CLOUDBACKUP TSM varmistusohjelmiston asennus

edocker PUBLISH! -paketinhallinnan käyttöohje 9/2015

Oliosuunnitteluesimerkki: Yrityksen palkanlaskentajärjestelmä

Written by Administrator Monday, 05 September :14 - Last Updated Thursday, 23 February :36

TAMPEREEN TEKNILLINEN YLIOPISTO Digitaali- ja tietokonetekniikan laitos. Harjoitustyö 4: Cache, osa 2

Pätevyyttä haettava oikeustulkkirekisterilautakunnalta. Edellytyksenä (lakiesityksestä lainaus):

815338A Ohjelmointikielten periaatteet Harjoitus 3 vastaukset

Esimerkkiprojekti. Mallivastauksen löydät Wroxin www-sivuilta. Kenttä Tyyppi Max.pituus Rajoitukset/Kommentit

Versionhallintaa. Versionhallinnan käyttöönotto SAS ympäristössä

815338A Ohjelmointikielten periaatteet Harjoitus 6 Vastaukset

UCOT-Sovellusprojekti. Asennusohje

Opintojakso TT00AA11 Ohjelmoinnin jatko (Java): 3 op

Ohjelmoinnin perusteet Y Python

Mainosankkuri.fi-palvelun käyttöohjeita

Ohjelmoinnin peruskurssi Y1

Pedanet oppilaan ohje Aleksanteri Kenan koulu Eija Arvola

EMVHost Online SUBJECT: EMVHOST ONLINE CLIENT - AUTOMAATTISIIRROT COMPANY: EMVHost Online Client sovelluksen käyttöohje AUTHOR: DATE:

Office ohjelmiston asennusohje

Ohjelmoinnin perusteet Y Python

Apuja ohjelmointiin» Yleisiä virheitä

add_action( wordcamp_jkl, johdatus_filttereihin );

Pythonin Kertaus. Cse-a1130. Tietotekniikka Sovelluksissa. Versio 0.01b

Sukupuu -ohjelma. Ossi Väre ( ) Joni Virtanen ( )

Maastotietokannan torrent-jakelun shapefile-tiedostojen purkaminen zip-arkistoista Windows-komentojonoilla

Tiedonsiirto- ja rajapintastandardit

Pakkauksen kokoaminen

JAVA-PERUSTEET. JAVA-OHJELMOINTI 3op A JAVAN PERUSTEET LYHYT KERTAUS JAVAN OMINAISUUKSISTA JAVAN OMINAISUUKSIA. Java vs. C++?

Käyttöohje HERE Maps painos FI

HAME PostGIS-tietokanta

KIITOS RICA OPTIMOINTIOHJELMAN VALITSEMISESTA

Järjestelmäarkkitehtuuri (TK081702)

Tekninen suunnitelma - StatbeatMOBILE

Arkkitehtuurikuvaus. Ratkaisu ohjelmistotuotelinjan monikielisyyden hallintaan Innofactor Oy. Ryhmä 14

Visma Liikkuvan työn ratkaisut

Ohjelmoinnin perusteet Y Python

Ohje kehitysympäristöstä. Dokumentti: Ohje kehitysympäristöstä.doc Päiväys: Projekti : AgileElephant

815338A Ohjelmointikielten periaatteet Harjoitus 7 Vastaukset

Adobe Digital Editions -ohjeet

MPCC-työkalua voidaan käyttää yhden laitteen valvontaan ja yhden tai useamman laitteen konfigurointiin (Modbus broadcast, osoite 0).

Visma Liikkuvan työn ratkaisut Päivitysohje. Pääkäyttäjän opas

Ohjelmointikielet ja -paradigmat 5op. Markus Norrena

TIETOKANNAT: MYSQL & POSTGRESQL Seminaarityö

Bitnami WordPress - Asenna WordPress koneellesi. Jari Sarja

Ohjelmistojen testaus ja hallinta. Gradle

erasmartcardkortinlukijaohjelmiston

Mikäli olet saanut e-kirjan latauslinkin sähköpostilla, seuraa näitä ohjeita e-kirjan lataamisessa.

Johdatus ohjelmointiin

812341A Olio-ohjelmointi, IX Olioiden välisistä yhteyksistä

Tekninen suunnitelma - StatbeatMOBILE

Ohjelmisto on selainpohjaisen käyttöliittymän tarjoava tietokantajärjestelmä merikotkien seurantaan WWF:n Merikotka-työryhmän tarpeisiin.

Harjoitustyö 3 - Millosemeni

C++11 Syntaksi. Jari-Pekka Voutilainen Jari-Pekka Voutilainen: C++11 Syntaksi

JUnit ja EasyMock (TilaustenKäsittely)

WWW-ohjelmointi ANTTI SAND TIETA12

MY STANDARD -OHJE. mystandard.hansaworld.com. Standard ERP Pilvipalvelu Sivu 1/6

Toiminnalliset ja ei-toiminnalliset vaatimukset Tunnus (ID) Vaatimus Vaatimuksen

Digikoulu Pilviteknologiat - Tunti 1001: Tiedon varastointi Amazon Simple Storage Service (Amazon S3) palveluun

WWW-PALVELUN KÄYTTÖÖNOTTO LOUNEA OY

Gree Smart -sovelluksen (WiFi) asennus- ja käyttöohje: Hansol-sarjan ilmalämpöpumput WiFi-ominaisuuksilla

F-Secure KEY salasanojenhallintaohjelman käyttöönotto PC -laitteella

erasmartcard-kortinlukijaohjelmiston asennusohje (mpollux jää toiseksi kortinlukijaohjelmistoksi)

NAVITA BUDJETTIJÄRJESTELMÄN ENSIASENNUS TYÖASEMALLE

INTINU13A6 Java sovellukset

SQL Buddy JAMK Labranet Wiki

Java kahdessa tunnissa. Jyry Suvilehto

Projektityö: Mobiiliajopäiväkirja. Mikko Suomalainen

Tietokantasovellus (4 op) - Web-sovellukset ja niiden toteutus

Testidatan generointi

Pakkauksen kokoaminen

Ohjelmistotuotanto. Luento

Olio-ohjelmointi: Luokkien toteuttaminen. Jukka Juslin

Ohjelmoinnin perusteet Y Python

Solteq Tekso v Versiopäivitysohje.

Käyttäjähallintapalvelun REST-rajapinnat

Transkriptio:

WWW-ohjelmointi ANTTI SAND TIETA12

Namespaces 2

Namespaces 3 No man is an island Haluamme hyödyntää muiden kirjoittamia komponentteja Mutta tähän asti kaikki luokkamme sijaitsevat globaalissa nimiavaruudessa Jos meillä on luokka Request ja haluamme käyttää pakettia, joka myös määrittää luokan Request, seuraa poikkeus Tarvitaan tapa jaotella luokat nimiavaruuksiin Yksinkertaisimmillaan seuraavasti

Suositeltuja käytäntöjä 4 Yksi luokka per tiedosto Yksi nimiavaruus per tiedosto Yksi pakettikohtainen päänimiavaruus (tässä geneerinen App) Nimiavaruuksien olisi hyvä vastata hakemistorakennetta App\Core\Bar = App/Core/Bar.php Mutta tähän ei pakoteta Mutta tästä on myöhemmin hyötyä

Use namespace 5 Voidaan kirjoittaa luokan täydellinen nimiavaruus Jos ollaan nimiavaruudessa App ja halutaan App\Core\Bar, voidaan kirjoittaa vain Core\Bar Tai jos halutaan Vendor\Bar, kirjoitetaan \Vendor\Bar, jolloin haetaan juuresta Tai voidaan käyttää (use) nimiavaruutta Ja voidaan halutessaan antaa alias (as Bar1) TIETA12-2017 - A.S.

Namespace caveats 6 Kielen omat luokat eivät kuulu sovelluksen nimiavaruuteen Esimerkiksi Router palauttaa poikkeuksen (Exception), joka ei kuulu luokan omaan nimiavaruuteen App\Core Jos kutsuja on vain yksi, voidaan kirjoittaa throw new \Exception(.. ); Tai jos kutsuja on useita (kuten QueryBuilderin PDO), voidaan kirjoittaa normaalisti use PDO;

Täydellinen nimi vai use? 7 Jos käytät jotain luokkaa vain muutamassa kohdassa, voit kirjoittaa täydellisen nimen $request = new \App\Core\Request(); Mutta jos komponenttia käytetään toistuvasti samassa luokassa, voidaan tuoda se osaksi luokan nimiavaruuksia Use App\Core\Request; $request = new Request(); Jos sinulla on useampia kuin yksi samanniminen luokka, voit käyttää täydellisiä nimiä, käyttää toista nimeä, tai käyttää molempia, mutta lisätä alias $a = new \App\Core\MyClass(); $b = new \Support\Something\MyClass();

Namespace caveats 8 Aiemmin käytimme Model luokassa get_called_class() funktiota määrittämään taulun nimen Kun siirrymme käyttämään nimiavaruuksia, tuo funktio palauttaa täydellisen nimen (l. Sisältää nimiavaruuden) Eli jos laitamme luokan Task nimiavaruuteen App\Models, funktio palauttaisi App\Models\Task Muokataan siis Model luokan gettablename metodia palauttamaan vain viimeisen kenoviivan jälkeinen osuus

9 PHP-FIG Framework Interop Group - http://www.php-fig.org/psr/

PHP-FIG 10 Ohjelmointikehyksen kehittyivät eristyksissä toisistaan, ne eivät jakaneet toiminnallisuutta, eivätkä noudattaneet samoja käytäntöjä CodeIgniter toteutti toiminnallisuuden X tavalla Y Ja Zend toteutti toiminnallisuuden X tavalla Z Php tek2009 konferenssissa muodostettiin PHP-FIG työryhmä sopimaan yhteisistä käytännöistä Luodaan komponentteja, jotka noudattavat sovittuja käytäntöjä ja koostetaan ohjelmointikehykset näistä komponenteista Kehittäjä voi vaihdella ja yhdistellä käytännön toteutuksia mieleisellään tavalla Komponentit tarjoavat sovitun rajapinnan, mutta itse toteutus vaihtelee

11 PHP-FIG antaa suosituksia rakenteelle PSRs = PHP Standards Recommendations PSR1&2 antavat suosituksia merkkaustavoista PSR0&4 määrittävät nimiavaruuksien käytön tiedostojen automaattiseen lataamiseen Ei enää tarvetta require file.php ;

Composer 12

Composer 13 Composer on paketinhallintatyökalu PHP:lle Voidaan merkata jokin paketti riippuvuudeksi Composer huolehtii sen asentamisesta ja päivittämisestä Vertaa NPM https://getcomposer.org/

Packagist 14 Packagist on koostesivu PHP komponenteista https://packagist.org/ The League of Extraordinaty Packages https://thephpleague.com/ Voit etsiä tarpeeseesi sopivan komponentin ja asentaa sen Composerilla Composer require guzzlehttp/guzzle Composer lisää komponentin composer.json tiedostoon projektin riippuvuudeksi Uusi kehittäjä tulee mukaan projektiin, ajaa composer install ja saa projektin riippuvuudet omalle kehityskoneelleen

Composer.json 15 NPM Packages.json Composer Composer.json Määrittää JSON -muodossa vaaditut riippuvuudet Lisätään seuraavaksi riippuvuus yksinkertaiselle autoloaderille

Composer.json 16 Luodaan projektin juureen composer.json tiedosto Kirjoitetaan JSON objekti autoload ja määritetään sille classmap taulukko Tässä ladataan koko projektin sisältä kaikki luokat automaattisesti HUOM! PSR-0 autoload standardi on vanhentunut ja korvattu PSR-4 autoload standardilla Harjoituksena muuttaa PSR-0 -> PSR-4

Composer install 17 Ajetaan komentorivillä composer install Tämä lukee composer.json tiedoston ja asentaa vendor hakemistoon projektin riippuvuudet. Tässä autoload.php tiedoston Voidaan poistaa require:t kaikilta luokkatiedostoilta ja ladata vain autoload.php Composer rakentaa autoload_classmap.php tiedoston, jossa mapataan nimiavaruudellinen luokka sen toteuttavaan tiedostoon Tämä ei päivity automaattisesti. Jos siirtelet tiedostoja hakemistosta tai nimiavaruudesta toiseen, tai lisäät tiedostoja, sinun tulee uudelleen generoida classmap ajamalla komentorivillä composer dump-autoload

Composer.json ja composer.lock 18 Composer.json määrittää paketin projektin riippuvuudeksi Composer.lock sitoo riippuvuuden tiettyyn versioon Kun uusi kehittäjä ajaa composer install, composer.lock varmistaa, että hän saa juuri saman version komponentista, vaikka uudempikin olisi tarjolla Tämä ehkäisee mahdollisia versioyhteensopivuusongelmia Composer update päivittää riippuvuudet uusimpiin versioihin Composer.lock luodaan uudestaan viittaamaan ajohetken uusimpaan versioon Lisää siis molemmat tiedostot versionhallintaan!

Autoload 19 käytössä Nyt voidaan poistaa bootstrap.php tiedostosta require:t ja korvata ne vendor/autoload.php:lla Kuvassa luokat jaoteltu nimiavaruuksiin Päänimenä geneerinen App Framework spesifi koodi App\Core -nimiavaruudessa

Composer packages & Symfony 20 Vaihdetaan aikaisempi Request luokka paljon kypsempään toteutukseen Symfony on PHP Framework, mutta myös kokoelma tarkkaan valittuja komponentteja, joita monet muut kirjastot hyödyntävät https://symfony.com/components Halutaan lisätä symfonyn http-foundation paketti, joka määrittää Request luokan, joka tarjoaa paremman API:n PHP:n superglobaaleille ($_GET, $_POST, $_SERVER, ) Ajetaan komento composer require symfony/http-foundation Tämä lataa tarvittavat tiedostot vendor hakemistoon ja kirjoittaa composer.json tiedostoon sen projektin riippuvuudeksi Näin varmistetaan, että jokaisella kehittäjällä on samat paketit asennettuna Koska näitä ulkopuolisia paketteja ei kuulu sisällyttää projektin versionhallintaan

Vaihdetaan luokan toteutus toiseen 21 Muista composer dumpautoload Käytetään symfonyn Request luokkaa Luodaan $request objekti superglobaaleista (luettavuuden vuoksi. Todellisuudessa inline) Annetaan reitittimelle uuden luokan luoma pyyntö

Composer ja versionhallinta 22 Laitetaan versionhallintaan vain projektin oma koodi Ne komponentit, joita hyödynnetään, listataan composer.json tiedostossa Jos uusi kehittäjä liittyy projektiin, hän kloonaa repositoryn ja ajaa composer install saadakseen täsmälleen samat versiot vaadituista riippuvuuksista Riippuvuuskomponenteilla on omat repositorynsä, ne eivät kuulu tämän projektin versionhallintaan Riippuvuuskomponentteihin ei tästä syystä tehdä suoraan muutoksia Koska muuten uudempaan versioon siirtyminen ylikirjoittaisi tekemämme muutokset Muutokset toteutetaan esimerkiksi perimisen kautta

Kontrollerien refaktorointi ja reititys 23

Halutaan kontrollerit luokiksi 24 Nyt kontrolleri on vain pätkä koodia Halutaan refaktoroida se luokaksi, jolla on metodeja Halutaan reitittää pyyntö tiettyyn kontrolleriin ja tiettyyn metodiin Tiedostetaan, että voidaan tehdä lukupyyntö GET tai kirjoituspyyntö POST Esim. Lomake lähettää tallennettavat tiedot POST /todos Joka johtaa TodosController->save() metodiin Tätä metodia ei tarvitse, eikä saa kutsua luettavaksi, se vastaa vain POST pyyntöön GET /todos johtaa TodosController->index() metodiin RESTful routes

25 RESTful routes https://en.wikipedia.org/wiki/re presentational_state_transfer Erityisen tärkeä toteutettaessa avoimia rajapintoja, koska rajapinnan hyödyntäjä voi olettaa sovitun reititysmallin Mutta luontevaa toteuttaa myös sisäisessä reitityksessä, koska tämä on yleisesti oletettu nimeämiskäytäntö TIETA12-2017 - A.S.

Miten monta tasoa on liikaa? 26

Reitit täytyy määritellä uudestaan 27 Sovitaan API: REITITIN->[METODIN NIMI]( polku, Kontrolleri@metodi ); $router->get( /todos, TodosController@index ); $router->post( /todos, TodosController@save ); Muutetaan routes.php käyttämään tätä API:a

Reititintä täytyy 28 refaktoroida Jotta voimme ottaa huomioon pyynnön tyypin, muutetaan $routes taulukko assosiatiiviseksi tyypin mukaan $routes[ GET ][ /todos ] = TodosController@index ; Koska routes.php sisältää kutsuja, ladataan tiedosto Router luokan sisällä Router palauttaa luokan, sitä ei enää tarvitse ladata erikseen

Reittien 29 tallentaminen

30 Reitittäminen TIETA12-2017 - A.S.

31 Metodin kutsuminen Huomaa tuplakenoviiva Koska yksi kenoviiva toimii escape :na varatuille merkeille (\{), laitetaan kaksi \\ => \ Tästä syystä osa käyttää aina kaksinkertaista kenoviivaa, jolloin asiaa ei tarvitse miettiä TIETA12-2017 - A.S.

Kontrolleri 32 luokaksi Nyt voidaan jakaa toiminnallisuus kontrolleri-luokille Reititin päättää mitä luokkaa ja luokan metodia kutsutaan pyynnön polun ja tyypin perusteella

Reititin käytännössä 33

Resurssikontrolleriksi 34

Halutaan tallentaa tietoja järjestelmään Siirretään Request luokka DI containeriin App::bind('request', Request::createFromGlobals()); Lisätään POST reitti $router- >post( /todos, TodosController@save ); Lisätään TodosController luokkaan save() metodi Asetetaan lopuksi vastauksen header, joka pakottaa uudelleenohjauksen 35.htaccess:n kanssa voidaan ohjata suoraan /todos

Resurssin 36 lisääminen Lomake lähettää tyypillä POST polkuun /todos Päädytään siis tallennusmetodiin Kentän nimi vastaa parametria TIETA12-2017 - A.S.

Tietoa muokkaavat reitit ovat POST 37 reittejä HTTP tarjoaa verbit GET, POST, PUT/PATCH, DELETE, Nämä vastaavat hyvin Read, Create, Update ja Delete (CRUD) Mutta selain tällä hetkellä ymmärtää vain GET ja POST kutsuja Voidaan lisätä lomakkeelle piilokenttä method=delete Ohjelma voidaan laittaa reagoimaan samalla tavalla lomakkeen simuloituun DELETE -pyyntöön ja joltain muulta asiakkaalta tulevalle oikealle DELETE pyyntöön Usein kuitenkin toteutetaan myös POST /delete-item, $_POST[ id ] Tietoa muokkaavat reitit määritellään POST reiteiksi XSS haavoittuvuuksien välttämiseksi (tästä lisää seuraavalla luennolla) Nullipotent ja idempotent -toiminnot

Kielen ominaisuuksia - traits 38

Trait 39 Trait on joukko ominaisuuksia, joita voidaan liittää luokkaan Vertaa mixin Rubyssä Vaihtoehto perinnälle siinä tapauksessa, että luokilla ei ole luontevaa yhteistä yläluokkaa Koska kielessä ei ole tuke moniperinnälle Esimerkiksi kauppa ja auto. Näillä ei ole helppoa yhteistä yläluokkaa, mutta molemmilla on jokin sijainti ja molemmilla voisi olla metodi, joka muuttaa sijainnin katuosoitteeksi $car->getstreedaddrs() ja $shop->getstreetaddrs()

Trait -esimerkki 40 Trait tuo ominaisuuksia ja metodeja luokkiin, joihin se liitetään Metodia voidaan kutsua luokan instanssin kautta aivan kuin se olisi luokan oma metodi Trait mahdollistaa toistuvan toiminnallisuuden liittämisen eri luokkiin ilman perintää ja toistamatta samaa koodia useassa kohdassa Huomaa use sanan käyttö. Luokan ulkopuolella se viittaa nimiavaruuteen, luokan sisällä trait:in DRY Don t repeat yourself

Traits esimerkki 2 41 Halutaan, että aina kun tietomalliluokan tieto muuttuu, siitä kirjoitetaan muutostieto tietokantaan. Mutta sovitaan, että vain tiettyjen tietomalliluokkien muutokset ovat ilmoittamisen arvoisia, emme halua tietoa kaikista tietomalliluokista. Voidaan lisätä tietomalliluokkaan trait Loggable, joka tarjoaa toiminnallisuuden muutostietojen tallentamiseen. Tai halutaan, että joitain tietomalliluokkia voidaan hakea rajapinnan kautta JSON muodossa. Voidaan lisätä vain haluttuihin tietomalliluokkiin trait JsonSerializable.

Kielen ominaisuuksia anon. funktiot 42

Anonyymi funktio 43 On yleensä metodin callback funktio Esimerkiksi array_map käy läpi taulukon arvot ja palauttaa kunkin arvon funktion läpi ajettuna

Anonyymi funktio 44 Anonyymi funktio ei tiedä ulkopuolisesta maailmasta Tämä koodi ei toimi, koska muuttujaa $multiplier ei tunneta anonyymin funktion sisäisessä maailmassa

Jälleen use - avainsana 45 Lisäämällä anonyymiin funktioon use($var), voidaan tuoda sen sisäiseen todellisuuteen ulkopuolisia muuttujia Muuttujan arvo sulkeuman sisällä on pysyvästi se, mikä se oli kutsumisen hetkellä

Kielen ominaisuuksia - generaattori 46

Generaattorit 47 Normaalisti iteroitava entiteetti, vaikka taulukko, ladataan kokonaan muistiin Esimerkki: luodaan halutun kokoinen taulukko, joka täytetään juoksevilla numeroilla ja tulostetaan sitten jokaisen solun arvo

Generaattorit 48 Jos parametrina on 15, ohjelma useimmiten toimii Mutta jos parametrina on tarpeeksi suuri luku, lopulta palvelimen varaama muisti loppuu kesken Jos numeron sijaan käsiteltäisiin tiedoston rivejä, ongelma olisi todennäköisempi (siis jos emme tiedä tiedoston kokoa) Jos suoritukselle on varattu 1gb muistia ja tiedoston koko on 2gb Muistiin ei voida ladata enempää tietoa, kuin mitä sinne mahtuu Generaattori lukee muistiin vain yhden iteraation kerralla Mutta samalla iterointi on vain yhdensuuntainen, eikä iteraatioiden yli voi hyppiä, kuten normaaleilla iteroitavilla

yield 49 Yield palauttaa yhden iteraation kerralla, muistia varataan vain yhdelle Iterointia jatketaan viimeiseen yield:n asti tai siihen saakka, kunnes vastaan tulee return

Generaattori voidaan myös keskeyttää 50 Kesken iteroinnin voidaan syöttää arvo $generator- >send() ja ottaa se vastaan $injected = yield $i; Voisi olla hyödyllinen isoa CSV tiedostoa parsiessa Jos jokin ehto täyttyy, tiedostoa ei tarvitse käsitellä loppuun

Arkkitehtuurista ja riippuvuuksista 51

Spaghetti Coupling 52

OOP Coupling 53

SOLID 54 Purettu riippuvuus konkreettiseen toteutukseen Code to an interface Open to extension / closed for modification Dependency inversion Single responsibility Voidaan yksikkötestata vaihtamalla tietolähde Division of concerns

Kysymyksiä? 55