Please enable JavaScript.
Coggle requires JavaScript to display documents.
Ohjelmistojen suunnittelu (Harkkatyö (Qt luento (Networking (Qt HTTP(S)…
Ohjelmistojen suunnittelu
Harkkatyö
Tehdään oma rajapinta! Jonka läpi sovellus hakee dataa
Tehdään mielellään C++ / QML teknologioita käyttäen, eli sisältää käyttöliittymän
Data
Avoimesti saatavilla netistä
Harkkatyöllä sama arvo kuin tentillä eli harkkatyöhön kannattaa panostaa
Qt luento
Networking
Qt HTTP(S) eli QNetworkAccessManager on se mikä on kiinnostavaa harkkatyön kannalta
QNetworkAccessManagerin avulla pystyy tekemään POST, GET ja PUT jne.
Ensin tehdään QNetworkAccessManager obejcti ja sillä pystyy kutsumaan metodeja get(), post() jne, palautuksena saadaan QNetworkReply objecti
SetHeader() ja setRawHeader() asettaa headereita kutsuille
Data Availability
Exposing data from C++ models to QML
QML and C++ integration
All communication between these two worlds goes via the Qt Meta-Object System
Qt Meta-Object System creates the signals and slots and makes possible to access/modify properties
QObjects need to be explicitly exposed to the QML runtime context in order to be accessible
Qt Charts
Voi piirtää kivuttomasti chartteja
QML saa datan C++ puolelta
MVC
Yhteenveto
Tunnetuin suunnittelumalli kälin ja ohjelman muiden osien erittelyyn toisistaan, tämä on fiksua varsinkin isoissa projekteissa
Hyväksi todettu ratkaisu dokumentoida ja keskustella
Mahdollisuus tehdä testausta ja kehitystä osakokonaisuus kerrallaan
Muutokset helpompia, koska käli ja logiikka komponentit eivät ole sekaisin
MVC lisää modulaarisuutta
Model-View-Controller
View-Näkymä
Esittää tiedot käyttäjille
Sisältää käli komponentit, esittää mallilta saamiaan tietoja
Controller-Kontrolleri
Käsittelee käyttäjän syötteet ja tarjoaa näkymälle rajapinnan
Käyttää mallia toteuttamaan tarjoamansa toiminnot, muuttaa mallia
On yhdistävä komponentti mallin ja näkyämän välissä
Model-Malli
Huolehtii tiedon hallinnasta/käsittelystä
Sisältää ohjelman "pihvin" eli bisnes logiikan ja talletettavan tiedon
Ei pelkästään passiivinen tietovarasto
Passivinen jos tekee asioita vain jos kontrolleri kutsuu sen palveluita
Puoliaktiivinen jos malli kertoo kiinnostuneille näkymille jos tila on muuttunut, sitten kiinnostuneet näkymät kysyvät mallilta uuden tiedon ja päivittää kälin
Aktiivinen malli kertoo kiinnostuneille muuttuneen tiedon suoraan kutsumalla palvelua, jonka avulla välittää tiedon, näkymä päivittää käyttöliittymän tietojen mukaiseksi
GOF, SOLID - SRP ja SOLID - OCP
GOF - Gang of four
Creational / Luomista
Abstrakti tehdas
Hyödyllistä jos ohjelman tulee ola konffattavissa erilaisille olioille
Hyödyllistä jos olioista halutaan paljastaa vain rajapinta - ei konkreettista luokkaa
Abstraktin tehtaan suunnitteluperiaatteen avulla pystytään enkapsuloimaan ryhmä saman teeman jakavia tehtaita ilman spesifioiden konkreettisia luokkia
Miksi?
Asiakkaan/luokan käyttäjän ei tarvitse tietää miten objekti luodaan
Voidaan luoda objektiryhmiä tai perheitä
Hyödyllinen jos ohjelman pitää olla riippumaton olioiden luontitavasta
Luo olion kertaheitolla toisin kuin Builder, joka luo olion askel kerrallaan
Builder / Rakentaja
Builderissa olioiden luonti ja algoritmi luomiseen on eriytetty
HouseBuilder luokka on interface pääluokka ja sen alla on konkreettisia IglooHouseBuilder, TipiHouseBuilder jne. luokkia, jotka luovat erilaisia olioita/taloja
Milloin builder?
Kun olio on monimutkainen ja koostuu useista ei osista
Kun sisäkkäisiä olioita ja useiden kenttien alustusta
Kun halutaan luomisalgoritmin olevan riippumaton olion muodostavista osista ja niiden koonnista
Kun halutaan luomisprosessin tukevan erilaisia rakenteita
Muista taloesimerkki, jossa oli pääluokka HouseBuilder, jonka metodit pystytään toteuttamaan KonkreettisissaBuildereissa
Rakentajaa käyttävät luokat eivät tiedä, mistä osista olio rakentuu -> Eriytetään luomiseen ja rakenteeseen liittyvät koodit
Miinuksena että kompleksisuus ja kasvaa, koska luokkien määrä kasvaa
Prototyyppi
Käytössä esimerkiksi JavaScriptissä
Miksi?
Hyvä jos halutaan välttää monimutkainen perintähierarkia
Hyvä jos alkutiloja on vain muutama
Hyvä jos luokkien luonti ja alustus määräytyy ajoaikana esim. jostain konffifilusta
Kapseloi tuoteluokat asiakasluokasta, asiakkaan ei tarvitse tietää miten tuottaminen tapahtuu
Uusia tuotteita voi määritellä vaihtelevilla arvoilla ilman uusien luokkien luomista
Tuoteolioita voi lisätä ja poistaa ajonaikana
Singleton
Kun luokalla on vain yksi ainoa ilmentymä
Tulisi olla laajennettavissa periytymisellä ja ĺaajennuksen tulisi olla käytössä ilman koodimuutoksia
Hyvää että on kontrolloitu pääsy ainoaan ilmentymään
Hyvää myös että ilmentymä alustetaan vain kerran
Hyvää hallittu nimiavaruuden käyttö
Mahdollistaa poikkeustilanteessa toistenkin singleton olioiden luonnin
Ongelmana vain yhden olion olemassaolon varmistaminen voi olla haastavaa
Objektien luomiseen liittyvät suunnittelumallit
SOLID
Single responsibility - Luokalla tulisi olla vain yksi tehtävä
Open/Closed principle - Suljettu muutoksilta mutta avoin lisäyksille
Liskov substitution principle - Aliluokan instanssi kelpaa kantaluokkaolion tilalle
Interface segregation principle - Jaetaan isommat rajapinnat pienemmiksi roolien mukaan
Dependency inversion principle - Riippuvuudet abstraktioihin, ei konkreettisiin toteutuksiin
Ei estä ketterää kehitystä
SRP
"a class should have only on responsibility"
Vain yksi vastuualue per luokka
Single responsibility principle
Etuna että yksikkötestit helpompi toteuttaa ja virheiden löytyminen helpottuu koska tietyn toiminnon asiat samassa paikassa
Virheiden korjaaminen helpompaa, koska juttujen korjaaminen tuskin hajoittaa mitään muuta
OCP
Open-closed principle
Software entities should be open for extensions, but closed for modifications
One should be able to extend a classes behaviour, without modifying it
Ominaisuuksien lisäämisen tulisi tapahtua uudella nimellä niin että vanhaa ei muuteta
Käytössä olio-ohjelmoinnissa ja sisältää viisi tärkeää suunnitteluperiaatetta, joiden avulla ohjelmasta saadaan tehokas, ylläpidettävä ja muuteltava
LSP
Objects should be replaceable with instances of their subtypes without altering the correctness of that program
Also derived classes must be substitutable with their base classes objects
Funktiot jotka käyttävät pääluokan pointtereita tai referenssejä tulee pystyä käyttämään derivoitujen luokkien objekteja tietämättä siitä
Voi käyttää "is-a" -testiä testatakseen noudattaako Liskovin periaatetta
Liskov substitution principle
Rakennemalleja
Sovitin / Adapter / Wrapper
Jos luokka ei pysty tarjoamaan sitä mitä toinen luokka tarvitsee niin tarvitaan väliin adapteri
Adapteri on siis palikka välissä, jotta saadaan yhteensopivuutta
2 versiota
Luokkasovitin
1 more item...
Oliosovitin
1 more item...
Milloin käyttää?
Kun luokan tarjoama rajapinta on EPÄyhteensopiva odotetun rajapinnan kanssa
Eli kun haluat käyttää olemassa olevaa luokkaa, mutta se ei toimi halutun luokan kanssa suoraan
Voi olla 2 suuntainen eli sovitetaan molempiin suuntiin
Jos on kaksi luokkaa joista toinen tarjoaa rajapinnan ja toinen käyttää ja adapteri mahdollistaa rajapinnan käyttämisen
Silta / Bridge
Kun halutaan erottaa rajapinta toteutuksesta, jotta kumpaakin voi varioida toisesta riippumatta
Kun halutaan jakaa ja organisoida iso monoliittiluokka, jolla useita variantteja joistain toteutuksista, kuten db palvelimia
Kun halutaan laajentaa luokkaa useisiin suuntiin
Silta vähän sama kuin sovitin, mutta sen tarkoitus on eri: Sen tarkoitus on erottaa rajapinta ja toteutus, lisäksi sovitinta käyetetään usein jälkikäteen kun taas siltaa jo suunnittelussa
Silta erottaa abstraktion ja toteutuksen
Koristelija / Decorator
Kun halutaan lisätä oliolle toiminnallisuutta ajonaikana
Kun ei haluta että ajonaikainen toiminnanlisäys vaikuttaa muihin olioihin
Kun aliluokitus on epäkäytännöllistä
Koristelija parantaa oliota muuttamalla rajapintaa ja se muuttaa vain olion vastuita, ei rajapintaa
Edustaja / Proxy
On jokin proxy johon otetaan yhteyttä sen varsinaisen asian sijaan
Proxy esittää oikeaa oliota ja siihen siis tulee ottaa yhteyttä
Kun tarvitaan sijainen oliolle, jotta kyetään hallitsemaan pääsyä olioon
Käytösmallit / Behavioral
Välittäjä / Mediator
Välittäjän tarkoitus on välittää viestejä
Välittäjä voi esimerkiksi välittää viestejä kahden aliluokan Colleague1 ja Colleague2 välillä
Miksi?
7 more items...
Javassa välittäjä toimii kuin MVC mallin controller, koska se välittää viestejä eri GUI-komponettien välillä
Tarkkailija / Observer
Tarkkailija on todella yleinen oliosuunnittelumalli
Tunnetaan myös nimellä Event-Subscriber
On olemassa luokat "Kohde" ja "Tarkkailija" ja näistä periytetyt luokat "KonkreettinenTarkkailija" ja "KonkreettinenKohde"
"Kohde" luokassa kyetään rekisteröimään tarkkailijoita joille kerrotaan heti jos jotain tärkeää Kohde luokassa muuttuu
Kohteen tarkkailu kyetään lopettamaan irtaudu() metodilla
Miksi?
3 more items...
Tyypillistä MVC mallissa kun kaikille näkymille ilmoitetaan mallin muutoksista
Plussaa että kohteen ja tarkkailijan välillä sidosteisuutta vain abstraktioiden kautta, koska kohde tietää vain että sillä on joukko tarkkailijoita
Plussaa että kohteen lähettämä tiedotus ei ole riippuvainen vastaanottajista tai niiden määrästä, Tarkkailija itse päättää miten toimii
Tarkkailija muistuttaa hyvin paljon QT:n signaaleita ja slotteja
Miinusta että tarkkailijat saavat ilmoituksen satunnaisessa järjestyksessä
Strategia / Strategy
Strategia mahdollistaa algoritmin vaihtamista lennosta, esim. sorttausalgoritmia
Milloin?
5 more items...
Kapseloi algoritmin ja tekee algoritmista vaihdettavan
Yhteenveto
Variaatiopisteiden kapselointi
2 more items...
Käytösmallit vahvistavat ja täydentävät toisiaan
Rakenteeseen kuuluu abstrakti luokka/rajapinta, joka kuvaa kapseloidun olion, patternin nimi johdetaan tästä oliosta
Luento 9
Muodoste
4 more items...
Kooste
5 more items...
Assosisaatio
4 more items...
Perintä
2 more items...
Yleisesti
2 more items...
Facade / Fasaadi
Eriyttää ison sekalaisen rajapinnan, niin että kaikki yhteydet menevätkin yhden yhteisen rajapinnan, Fasaadin kautta
Milloin?
Kun tarvitaan yhtenäinen, helppo rajapinta alijärjestelmälle/kirjastolle/frameworkille
Kun tarvitaan helppo rajapinta monimutkaiselle luokkakokoelmalle
Kun asiakkaiden ja konkreettisten toteutusten välillä paljon riippuvuuksia, niin fasaadi erottaa alijärjestelmän asiakkaasta ja muista alijärjestelmistä
Jos halutaan kerrostaa alijärjestelmiä, niin voidaan tehdä fasaadi, joka kerroksen väliin
Fasaadi tarjoaa yksinkertaisen näkymän alijärjestelmään, kuitenkin niin että asiakas kykenee sen kautta tekemään kaiken tarvitsemansa
Plussat ja miinukset
Peittää alijärjestelmän asiakkaalta -> Peitää olioita, joiden kanssa asiakkaan tulee olla tekemisissä ja tekee alijärjestelmästä helpomman käyttää
Kapsuloi ja abstraktoi alijärjestelmää
Edistää löysää sidosteisuutta alijärjestelmä ja kutsujan välillä eli mahdollistaa sisäisten komponettien varioinnin ilman että asiakkaan tarvitsee välittää
Fasaadi ei kuitenkaan estä asiakasta käyttämstä aliluokan luokkia suoraan, jos niin haluaa
Fasaadin ongelma on että siitä tulee helposti jumalluokka riippuvuuksineen todella moneen luokkaan -> Vaikea hallita
Muista Fasaadi esimerkki, jossa oli ComputerFacade luokka, jossa oli Start() funktio joka käskytti CPU luokan oliota tekemään kaikkea käynnistykseen liittyvää
ISP
Interface segregation principle means that many client-specific interfaces are better than one general-purpose interface
Make fine grained interfaces that are client specific
Clients should not be forced to depend upon methods they do not use
Jaetaan isommat rajapinnat pienemmiksi roolien mukaan, saadaan roolirajapintoja
Iso ohjelma jossa paljon keskinäisiä riippuvuuksia ja isoja rajapintoja -> pienikin muutos heijastuu moneen paikkaan
Vältä sitä että luokkien on pakko toteuttaa rajapintoja joihin ne ei taivu
Interface segregation principle
DIP
High-level modules should not depend on low-level modules, both should depend on abstractions
Abstractions should not depend upon details, details should depend upon abstractions
Riippuvuudet abstraktioihin, ei konkreettisiin toteutuksiin
Mitä jos rikkoo: Koodi ei siirrettävää, ohjelman rakenne täynnä riippuvuuksia, komponentteja ei voi uudelleen käyttää tai siirtää niiden takia
Muutos yhteen paikkaan rikkoo asioita muualla ohjelmistossa
Jos noudattaa OCP ja LSP niin DIP pitäisi olla siinä sivussa hoidossa
Dependency inversion principle
Hyvää settiä kurssista
https://andor.tuni.fi/permalink/358FIN_TAMPO/i4qs1o/alma9910626184405973
Mitä SE on?
Miksi?
Varmistetaan ohjelman oikeellisuus ja luotettavuus --> Yhteinen ymmärrys
Sovitaan projektin vaiheistus ja työnjako
Millä teknologialla mitäkin ja kaikki tietää mitä tekee
Ohjelmasta suunnitellaan ylläpidettävä ja muunneltava
Ohjelman jakamista komponentteihin, kuten moduuleihin ja luokkiin
Suunnittelussa pitää myös huomata koodi jota voitaisiin uudelleenkäyttää
Suunnittelua tekee ohjelmistoarkkitehti ja kehittäjät
Suunnittelu on myös ratkaisuja ja niiden dokumentointia!
Suunnittelu kertoo että mitä ja MIKSI? On syytä dokumentissa kertoa miksi on päädytty tekemään jokin asia tietyllä tavalla ja mitä muissa tavoissa mahdollisesti olisi ollut huonompaa
Sopimussuunnittelu
Esiehdot - Miten rajapintaa saa kutsua? - Kutsujan vastuu
Jälkiehdot - Mitä rajapinta lupaa tehdä? - Toteuttajan vastuu
Luokkainvariantti - Milloin oliot ovat järjissään / omaavat sallittuja arvoja
Rajapinnat
Rajapinnan toiminnallisuuden kuvaamisen tulee olla yksinkertaista
Huonoja merkkejä
Useamman sanan pitkät rajapinnat
Funktioita on paljon/liikaa
Huonoa myös rajapinnan toteutusyksityiskohtien paljastaminen pinnan kommenteissa/ohjeistuksessa
Älä laita käyttäjää tekemään sellaista mikä olisi helppo tehdä moduulin sisällä, tämä helpottaa rajapinnan kutsujan elämää