Kuinka löydät tarvitsemasi suunnittelukuvion? Suunnittelumalleja. OOP-kuviot metaforeissa

Ennen kuin aloitan artikkelin, haluan tarjota ystäväni Denis Porplenkon raportin ohjelmoinnin suunnittelumalleista:

Haluan muistuttaa, että suunnittelumallit syntyivät ratkaisuna usein esiin tuleviin samantyyppisiin ongelmiin, itse asiassa suunnittelussa. Mutta he saivat pääkehityksensä vuonna ohjelmistokehitys. Ja jatkan tarinaa kehityksen yhteydessä ohjelmisto.

Kuvioiden aihealue on hyvin laaja. Nämä ovat suosituimpia malleja, on muitakin. Listan ne kaikki alla.

Monet yritykset käyttävät malleja käytännössä. Kuvioiden käytössä on hyvät ja huonot puolensa.
Suunnittelukuvioiden käytön edut:
— kuvioiden käytön tärkein etu vapaaseen suunnitteluun verrattuna on se, että kuvio antaa ongelmalle nimen ja määrittelee tapoja ratkaista monia ongelmia valmiiden abstraktioiden avulla
— helpottaa järjestelmänkehittäjien välistä viestintää
— Suunnittelumallien käyttö on samanlaista kuin valmiiden koodikirjastojen käyttö
oikea käyttö Mallit auttavat kehittäjiä määrittämään halutun kehitysvektorin ja välttämään monia kehitysprosessin aikana mahdollisesti ilmeneviä ongelmia.

Suunnittelukuvioiden aiheuttamat ongelmat:
— Mielestäni suurin ongelma mallien käytössä on joustavuuden menetys järjestelmän suunnittelussa ja kehittämisessä
— mallien käyttö monimutkaistaa järjestelmää
— Tietyn kaavan sokea seuraaminen ja sen käyttäminen kaikkialla voi aiheuttaa joukon arkkitehtonisia ja loogisia ongelmia

Ohjelmoinnin perusmallit

Perusteellista

Delegointimalli Delegointimalli — Objekti ilmaisee ulkoisesti jonkinlaista käyttäytymistä, mutta todellisuudessa siirtää vastuun tämän toiminnan suorittamisesta liittyvälle objektille.
Näyte toimiva muotoilu Toiminnallinen suunnittelu - Varmistaa, että jokaisella tietokoneohjelman moduulilla on vain yksi vastuu, ja suorittaa sen mahdollisimman vähäisin sivuvaikutuksin ohjelman muihin osiin.
Muuttumaton käyttöliittymä(Muuttumaton käyttöliittymä) - Muuttumattoman objektin luominen.
Käyttöliittymä - Yleinen strukturointimenetelmä tietokoneohjelmat jotta ne olisi helpompi ymmärtää.
Käyttöliittymän merkki(Marker interface) - Merkintärajapinnan toteutuksen olemassaoloa tai puuttumista käytetään attribuuttina (objektikokonaisuuden merkkinä). Nykyaikaiset ohjelmointikielet voivat käyttää sen sijaan attribuutteja tai huomautuksia.
Ominaisuudet kontti(Ominaisuussäilö) - Voit lisätä luokan lisäominaisuuksia säilöön (luokan sisällä) sen sijaan, että laajentaisit luokkaa uusilla ominaisuuksilla.
Tapahtumamalli(Tapahtumakanava) - Laajentaa Julkaise/Tilaa mallia luodakseen keskitetyn kanavan tapahtumille. Käyttää välityspalvelinobjektia tilaamiseen ja välityspalvelinobjektia tapahtuman julkaisemiseen kanavalle. Edustaja on erillään varsinaisesta kustantajasta tai tilaajasta. Tilaaja voi vastaanottaa julkaistuja tapahtumia useammalta kuin yhdeltä taholta, vaikka se olisi rekisteröitynyt vain yhteen kanavaan.

Generatiiviset mallit

Luovat kuviot ovat suunnittelumalleja, jotka abstraktoivat toteutusprosessin. Niiden avulla on mahdollista tehdä järjestelmästä riippumaton tavasta, jolla esineet luodaan, koostetaan ja esitetään. Malli, joka ilmentää luokkia, käyttää periytymistä luokan muokkaamiseen, ja malli, joka luo objektit, delegoi ilmentämisen toiselle objektille.
Abstrakti tehdas(Abstract factory) - Luokka, joka tarjoaa käyttöliittymän järjestelmäkomponenttien luomiseen.
Rakentaja(Builder) - Luokka, joka tarjoaa käyttöliittymän monimutkaisen objektin luomiseen.
Tehdasmenetelmä(Tehdasmenetelmä) - Määrittää rajapinnan objektin luomista varten, mutta jättää alaluokkien päätettäväksi, mikä luokka instantoidaan.
Laiska alustus(Lazy alustus) — Objekti, joka alustetaan ensimmäisen kutsun aikana.
Single-allas(Multiton) - Varmistaa, että luokalla on nimetyt objektiinstanssit ja tarjoaa niille maailmanlaajuisen tukiaseman.
Objektiallas(Objektivarasto) - Luokka, joka edustaa käyttöliittymää alustettujen ja käyttövalmiiden objektien joukon kanssa työskentelyyn.
Prototyyppi(Prototyyppi) — Määrittää käyttöliittymän objektin luomiseen kloonaamalla toinen objekti sen sijaan, että se luotaisiin rakentajan avulla.
Resurssin hankkiminen on alustamista(Resurssien hankinta on alustus (RAII)) - Tietyn resurssin hankkiminen yhdistetään alustukseen ja sen vapauttaminen objektin tuhoamiseen.
Yksinäinen(Singleton) - Luokka, jolla voi olla vain yksi esiintymä.

Rakenteelliset kuviot

Rakennemallit määrittelevät erilaisia monimutkaiset rakenteet, jotka muuttavat olemassa olevien objektien käyttöliittymää tai sen toteutusta, mikä helpottaa ohjelman kehittämistä ja optimointia.
Sovitin(Sovitin / kääre) - Objekti, joka tarjoaa vuorovaikutuksen kahden muun objektin välillä, joista toinen käyttää ja toinen tarjoaa rajapinnan, joka ei ole yhteensopiva ensimmäisen kanssa.
Silta(Silta) - Rakenne, jonka avulla voit muuttaa käyttöliittymää ja luokan toteutusliittymää itsenäisesti.
Linkki(Yhdistelmä) - Objekti, joka yhdistää itseään muistuttavia objekteja.
Sisustusarkkitehti tai Kääre(Decorator) tai (Wrapper) - Luokka, joka laajentaa toisen luokan toimintoja ilman periytymistä.
Julkisivu(Julkisivu) - Objekti, joka abstrakti teoksen useilla luokilla yhdistäen ne yhdeksi kokonaisuudeksi.
Yksi sisääntulopiste(Etuohjain) - Tarjoaa yhtenäinen käyttöliittymä osajärjestelmän liitäntöjä varten. Front Controller määrittelee korkean tason rajapinnan, joka helpottaa alijärjestelmän käyttöä.
Opportunisti(Flyweight) - Tämä on objekti, joka edustaa itseään ainutlaatuisena esiintymänä eri paikkoja ohjelma, mutta itse asiassa se ei ole yksi.
Sijainen(Välityspalvelin) - Objekti, joka toimii välittäjänä kahden muun objektin välillä ja joka toteuttaa/rajoittaa pääsyä sen kautta käytettävään kohteeseen.

Käyttäytymismallit

Käyttäytymismallit määrittelevät esineiden välisen vuorovaikutuksen, mikä lisää sen joustavuutta.
Vastuuketju(Vastuuketju) - Suunniteltu organisoitumaan vastuutasojärjestelmään.
Tiimi(Komento) - Edustaa toimintoa. Komentoobjekti sisältää itse toiminnon ja sen parametrit.
Tulkki(Tulkki) - Ratkaise ongelma, joka esiintyy usein, mutta joka voi muuttua.
Iteraattori(Iteraattori) - Edustaa objektia, jonka avulla voit saada peräkkäisen pääsyn koosteobjektin elementteihin käyttämättä kuvauksia jokaisesta koostumukseen kuuluvasta objektista.
Välittäjä(Välittäjä) - Tarjoaa vuorovaikutusta useiden objektien välillä muodostamisen aikana löysä kytkentä ja eliminoi objektien tarpeen viitata suoraan toisiinsa.
Pitäjä(Memento) - Voit kaapata ja tallentaa objektin sisäiset tilat rikkomatta kapselointia, jotta voit myöhemmin palauttaa sen näihin tiloihin.
Nollaobjekti(Null-objekti) - Estää nollaosoittimet tarjoamalla "oletus"-objektin.
Tarkkailija(Observer) - Määrittää objektien välisen riippuvuuden yksi-moneen siten, että kun yhden objektin tila muuttuu, kaikki siitä riippuvaiset saavat tiedon tästä tapahtumasta.
Palvelija(Palvelija) - Käytetään tarjoamaan yhteisiä toimintoja luokkaryhmälle.
Erittely(Spesifikaation) - Linkitä liiketoimintalogiikka.
Osavaltio(State) - Käytetään tapauksissa, joissa objektin on ohjelman suorituksen aikana muutettava käyttäytymistään tilastaan ​​riippuen.
strategia(Strategia) - Suunniteltu määrittelemään algoritmiperhe, kapseloimaan jokainen niistä ja varmistamaan niiden vaihdettavuus.
Mallimenetelmä(Mallimenetelmä) - Määrittää algoritmin perustan ja antaa jälkeläisille mahdollisuuden määritellä uudelleen joitain algoritmin vaiheita muuttamatta sen rakennetta kokonaisuutena.
Vierailija(Visitor) - Kuvaa toiminnon, joka suoritetaan muiden luokkien objekteille. Kun vaihdat Vierailija-luokkaa, tarjottuja luokkia ei tarvitse muuttaa.
Yksinkertainen politiikka– Tiedän, että tällainen malli on olemassa, mutta en ole vielä löytänyt, mitä se tarkoittaa. Jos sinulla on tietoa, laita se kommentteihin.
Kuuntelija(Tapahtumakuuntelija) - samanlainen
Kerran vierailija(Yksittäinen vierailija) - Optimoi vierailijamallin toteutuksen, joka alustetaan, käytetään kerran ja sitten poistetaan.
Hierarkkinen vierailija(Hierarkkinen vierailija) - Tarjoaa tavan kulkea hierarkkisen tietorakenteen (esimerkiksi puun) kaikkien kärkien läpi.

Rinnakkaisohjelmointimallit

Käytetään tehokkaampaan monisäikeisten ohjelmien kirjoittamiseen, ja se tarjoaa valmiita ratkaisuja synkronointiongelmiin.
Aktiivinen kohde(Aktiivinen objekti) - Erottaa menetelmän suoritussäikeen säikeestä, jossa sitä kutsuttiin. Käyttää malleja asynkroninen puhelu menetelmät ja aikataulu.
Dodger(Balking) - Suorittaa toiminnon kohteelle vain, kun se on oikeassa tilassa.
Omaisuuden sitominen(Sidontaominaisuudet) - Yhdistää useita tarkkailijoita varmistaakseen ominaisuuksien synkronoinnin eri objektien välillä
Viestinvaihto(Messaging design pattern (MDP)) - Sallii komponenttien ja sovellusten vaihtaa tietoja (viestejä).
Tarkista lukko(Kaksoistarkistettu lukitus) - Suunniteltu vähentämään lukon saamiseen liittyviä ylimääräisiä kustannuksia.
Asynkroniset tapahtumat(Tapahtumapohjainen asynkroninen) — Käsittele ongelmia Asynkronisella kuviolla, joka esiintyy ohjelmissa, joissa on useita säikeitä.
Suojattu jousitus(Suojattu keskeytys) - Käytetään estämään toiminnon suorittaminen objektille vain, kun se on oikeassa tilassa.
Puolisynkronointi(Half-Sync/Half-Async) - tästä kuviosta ei ole vielä tietoa.
Johtajat(Johtajat/seuraajat) - tästä mallista ei ole vielä tietoa.
Lukko(Lukitse) – Yksi säiettä lukitsee resurssin, jotta muut säikeet eivät pääse käsiksi tai muuttamaan sitä.
Monitori(Monitor object) — Objekti, joka on tarkoitettu turvallinen käyttö enemmän kuin yksi lanka.
Reactor - Suunniteltu pyyntöjen synkroniseen lähettämiseen palveluun yhdestä tai useammasta lähteestä.
Luku-kirjoitus lukitus(Lukukirjoituslukko) - Sallii useiden säikeiden lukea tietoja samanaikaisesti jaetusta tallennustilasta, mutta vain yhden säikeen voi muuttaa niitä kerrallaan.
Ajastin(Scheduler) - Tarjoaa mekanismin aikataulutuskäytäntöjen toteuttamiseksi ilman, että se on riippuvainen mistään tietystä käytännöstä.
Lanka allas(Säikevarasto) - Tarjoaa säikevalikoiman töiden käsittelyä varten, yleensä jonon muodossa.
Erityinen stream-varasto(Säiekohtainen tallennus) - Tarjoaa erilaisia ​​globaaleja muuttujia eri säikeille.
Yksisäikeinen suoritus(Yksisäikeinen suoritus) - Estää samanaikaisen menetelmän kutsumisen ja estää siten tämän menetelmän rinnakkaisen suorittamisen.
Yhteistyökuvio(Yhteistyökuvio) - Tarjoaa mekanismin, jolla voidaan turvallisesti pysäyttää suorituksen säikeet käyttämällä yhteistä lippua viestimään säikeiden päättymisestä.

Järjestelmäarkkitehtuurimallit

Malli-näkymä-ohjain(MVC) - Model-View-Controller.
Malli-näkymä-Esittäjä
Malli-näkymä-näkymä-malli
Esitys-Abstraktio-Ohjaus
Alastomia esineitä
Hierarkkinen malli-näkymä-ohjain

Yritysmallit

Active Record - tapa päästä käsiksi tietoihin relaatiotietokannat tieto olio-ohjelmoinnissa.
Liiketoiminnan edustaja
Yhdistelmäkokonaisuus
Yhdistelmänäkymä
DAO (Data Access Object) Data Access Object
Lähettäjänäkymä
Etuohjain
Sieppaava suodatin
Rekisteri
Palvelun aktivaattori
Palvelun paikannus
Palvelu työntekijälle
Session Julkisivu / Session Julkisivu
Transfer Object Assembler
Siirrä objekti
Arvoluettelon käsittelijä
Näytä Helper
Työyksikkö

Muuntyyppiset mallit

Nykyään on saatavilla myös useita muita malleja.
Varastointi(Arkisto)
Carrier Rider Mapper kuvaile pääsyn tarjoamista tallennettuihin tietoihin.
Analyyttiset mallit kuvaile ohjelmistovaatimusten kehittämisen peruslähestymistapaa (vaatimusanalyysi) ennen kuin ohjelmistokehitysprosessi alkaa
Viestintämallit kuvaamaan organisaation yksittäisten osallistujien/työntekijöiden välistä kommunikaatioprosessia
Organisaatiomallit kuvaile yrityksen/yrityksen organisaatiohierarkiaa
Antikuvioita(Anti-Design-Patterns) kuvaa mitä ei saa tehdä ohjelmia kehitettäessä, esitettäessä tyypillisiä virheitä suunnittelussa ja toteutuksessa

Jos olet koskaan miettinyt, mitä suunnittelukuviot ovat, niin tervetuloa. Tässä artikkelissa kerron sinulle, mitä ne ovat, miksi niitä tarvitaan, kuinka niitä käytetään, ja annan esimerkkejä yleisimmistä PHP-malleista.

Mitä ovat suunnittelumallit?

Suunnittelumallit ovat todistettuja, käyttövalmiita ratkaisuja usein kohtaaviin ongelmiin. jokapäiväistä ohjelmointia tehtäviä. Tämä ei ole luokka tai kirjasto, joka voidaan yhdistää projektiin, se on jotain muuta. Tehtävään sopiva suunnittelumalli toteutetaan kussakin tapauksessa. Lisäksi se on ohjelmointikielestä riippumaton. Hyvä malli on helppo toteuttaa useimmilla, ellei kaikilla kielillä, riippuen kielen ilmaisukyvystä. On kuitenkin muistettava, että tällainen kaava voi aiheuttaa paljon ongelmia, jos sitä käytetään väärin tai väärään ongelmaan. Oikein käytetty malli auttaa kuitenkin ratkaisemaan ongelman helposti ja yksinkertaisesti.

Malleja on kolmen tyyppisiä:

  • rakenteellinen;
  • tuottaa;
  • käyttäytymiseen.

Rakenteellinen mallit määrittelevät suhteita luokkien ja objektien välillä, jolloin ne voivat toimia yhdessä.

Generatiivinen mallit tarjoavat alustusmekanismeja, joiden avulla voit luoda objekteja kätevällä tavalla.

Käyttäytyminen malleja käytetään yksinkertaistamaan entiteettien välistä vuorovaikutusta.

Miksi suunnittelumalleja tarvitaan?

Suunnittelukuvio on pohjimmiltaan harkittu ratkaisu tiettyyn ongelmaan. Jos sinulla on tunnettu ongelma, miksi et käytä valmis ratkaisu, todistettu kokemuksella?

Esimerkki

Oletetaan, että sinun täytyy yhdistää kaksi luokkaa, jotka tekevät erilaisia ​​operaatioita tilanteesta riippuen. Nykyinen järjestelmä käyttää voimakkaasti näitä luokkia, mikä tekee mahdottomaksi poistaa yhtä niistä ja lisätä sen toimintoja toiseen. Lisäksi koodin muuttaminen vaatii huolellista testausta, koska tällainen uudelleenjärjestely johtaa väistämättömiin virheisiin. Sen sijaan voit ottaa käyttöön strategia- ja sovitinmallit ja käyttää niitä ongelman ratkaisemiseen.

LuokkastrategiaAndAdapterExampleClass ( yksityinen $_class_one; yksityinen $_class_two; yksityinen $_context; julkinen funktio __construct($context) ( $this->_context = $context; ) julkinen funktio operaatio1() ( if($this->_context == "context_for_class_one ") ( $this->_class_one->operation1_in_class_one_context(); ) else ($this->_context == "konteksti_luokan_kahdelle") ( $this->_class_two->operation1_in_class_two_context(); ) ) )

Yksinkertaista, eikö? Katsotaanpa tarkemmin strategiamallia.

Malli "Strategia"

strategia- käyttäytymismalli, jonka avulla voit valita ohjelman käyttäytymisen suorituksen aikana kontekstista riippuen kapseloimalla useita algoritmeja eri luokkiin.

Yllä olevassa esimerkissä strategian valinta perustuu $context-muuttujan arvoon objektin luomishetkellä. Jos arvo oli "context_for_class_one" , ohjelma käyttää luokkaa class_one . Ja päinvastoin.

Okei, mutta missä tätä voi käyttää?

Kuvittele, että kehität luokkaa, joka voi luoda tai päivittää tietueen tietokannassa. Kummassakin tapauksessa syöttöparametreja on sama (nimi, osoite, puhelinnumero jne.), mutta tilanteen mukaan hänen on käytettävä erilaisia ​​toimintoja päivittääksesi ja luodaksesi tietueen. Voit kirjoittaa if/else-ehdon uudelleen joka kerta tai voit luoda yhden menetelmän, joka hyväksyy kontekstin:

Luokan käyttäjä ( julkinen toiminto CreateOrUpdate($nimi, $osoite, $mobiili, $käyttäjätunnus = null) ( if(is_null($userid)) ( // käyttäjää ei ole olemassa, luo tietue ) else ( // tietue on olemassa, päivitä se )))

Tyypillisesti strategiamalli sisältää algoritmien kapseloinnin luokkiin, mutta sisään tässä tapauksessa tämä on tarpeetonta. Muista, että sinun ei tarvitse seurata mallia sanasta sanaan. Kaikki vaihtoehdot ovat hyväksyttäviä, jos ne ratkaisevat ongelman ja vastaavat konseptia.

Sovittimen malli

Sovitin- rakennemalli, jonka avulla voit käyttää toteuttavaa luokkaa tarvittavat toiminnot, mutta käyttöliittymä on sopimaton.

Sen avulla voit myös muuttaa joitain tuloja yhteensopiviksi sisäisen luokan käyttöliittymän kanssa.

Kuinka käyttää sitä?

Toinen sovittimen nimi on "Wrap". Se "käärii" uuden käyttöliittymän luokan ympärille käyttöä varten. Klassinen esimerkki: sinun on luotava luokka aiheen malli, joiden objektiluokat tietokannassa. Sen sijaan, että käyttäisit taulukkoluokkia suoraan ja kutsuisit niiden menetelmiä yksi kerrallaan, voit kapseloida näiden menetelmien kutsut yhteen menetelmään sovittimessa. Sen lisäksi, että voit käyttää uudelleen useita toimintoja, se myös säästää sinua jatkuvasti uudelleenkirjoittamasta paljon koodia, jos sinun on suoritettava samat toiminnot muualla.

Vertaa kahta esimerkkiä.

Ilman adapteria
$käyttäjä = uusi käyttäjä(); $user->CreateOrUpdate(// parametrit); $profiili = uusi profiili(); $profiili->CreateOrUpdate(// parametrit);

Jos meidän on käytettävä tällaista koodia uudelleen, meidän on pakko kirjoittaa koko juttu uudelleen.

Adapterin käyttö

Voimme luoda Account wrapper -luokan:

Luokkatili() ( julkinen toiminto NewAccount(// parametrit) ( $user = new User(); $user->CreateOrUpdate(// osa parametreista); $profiili = uusi profiili(); $profiili->LuoOrUpdate( // osa parametreista); ) ) $account_domain = new Account(); $account_domain->NewAccount(// parametrit);

Nyt voimme käyttää Account-luokkaa joka kerta ja lisäksi voimme lisätä siihen lisätoimintoja.

Tehdasmenetelmämalli

Tehdas- generoiva malli, joka on luokka, jossa on menetelmä erilaisten objektien luomiseen.

Tämän mallin päätarkoitus on kapseloida menettely eri luokkien luomiseksi yhdeksi funktioksi, joka sille välitetystä kontekstista riippuen palauttaa vaaditun objektin.

Kuinka käyttää sitä?

Tehdasta käytetään tyypillisesti perusluokan eri muunnelmien luomiseen. Oletetaan, että sinulla on painikeluokka - Button - ja kolme vaihtoehtoa - ImageButton, InputButton ja FlashButton. Tehtaalla voit luoda erilaisia ​​vaihtoehtoja painikkeita tilanteen mukaan.

Luodaan ensin kolme luokkaa:

Abstract class Button ( suojattu $_html; julkinen funktio getHtml() ( return $this->_html; ) ) class ImageButton extends Button ( suojattu $_html = "..."; // kuvapainikkeen HTML-koodi ) class InputButton laajenee Button ( suojattu $_html = "..."; // HTML-koodi tavalliselle painikkeelle ( ); ) luokka FlashButton laajentaa painiketta ( suojattu $_html = "..."; // Flash-painikkeen HTML-koodi )

Nyt voimme kirjoittaa tehtaallemme:

Class ButtonFactory ( julkinen staattinen funktio createButton($type) ( $baseClass = "Button"; $targetClass = ucfirst($type).$baseClass; if (class_exists($targetClass) && is_subclass_of($targetClass, $baseClass)) ( return new $targetClass; else ( heittää uusi poikkeus("Painikkeen tyyppiä "$type" ei tunnisteta."); ) )

ja käytä sitä:

$painikkeet = array("kuva","syöttö","flash"); foreach($buttons as $b) ( echo ButtonFactory::createButton($b)->getHtml() )

Tulosteen tulee olla HTML, jossa on kaikentyyppisiä painikkeita. Näin pystyimme määrittelemään minkä tyyppisen painikkeen halusimme ja käyttämään koodia uudelleen.

Sisustimen malli

Sisustusarkkitehti on rakenteellinen malli, jonka avulla voit lisätä objektiin uutta käyttäytymistä ohjelman suorittamisen aikana tilanteen mukaan.

Tavoitteena on laajentaa tietyn objektin käyttäytymistä ilman, että perusluokan käyttäytymistä tarvitsee muuttaa. Näin voit käyttää useita koristeluja samanaikaisesti. Tämä malli on vaihtoehto perinnölle. Toisin kuin periytyminen, sisustaja lisää käyttäytymistä ohjelman suorittamisen aikana.

Sisustajan toteuttamiseen tarvitsemme:

  1. Peri sisustajaluokka perusluokkasta.
  2. Lisää kenttä, jossa on linkki perusluokka sisustajalle.
  3. Välitä viittaus sisustettavaan esineeseen sisustajan rakentajalle.
  4. Ohjaa menetelmät sisustajalta koristeltavaan esineeseen.
  5. Ohita menetelmät sisustajassa, jonka käyttäytymistä haluat muuttaa.

Kuinka käyttää sitä?

Oletetaan, että meillä on esine, jolla on oltava tietty käyttäytyminen tietyssä tilanteessa. Meillä on esimerkiksi HTML-linkki, jonka avulla voit kirjautua ulos tilistäsi. Linkin pitäisi näkyä eri tavalla riippuen siitä, millä sivulla olemme. Tämä on juuri silloin, kun sisustajat auttavat meitä.

Ensin päätetään, mitä "maisemia" tarvitsemme:

  • Jos olemme pääsivulla ja kirjautuneena sisään, linkin tulee olla h2-tunnisteessa.
  • Jos olemme millä tahansa muulla sivulla ja olemme kirjautuneita sisään, linkki tulee alleviivata.
  • Jos olemme kirjautuneena sisään, linkin tulee olla vahvassa tagissa.

Nyt voimme kirjoittaa sisustajat itse:

Luokka HtmlLinks ( // menetelmät minkä tahansa HTML-linkin kanssa työskentelemiseen) luokka LogoutLink laajentaa HtmlLinkkejä ( suojattu $_html; julkinen toiminto __construct() ( $this->_html = "Logout"; ) julkinen funktio setHtml($html) ( $this - >_html = $html ) julkinen funktio render() ( echo $this->_html; ) ) luokka LogoutLinkH2Decorator laajentaa HtmlLinkkejä ( suojattu $_logout_link; public function __construct($logout_link) ( $this->_logout_link = $logout_link; $ this ->setHtml("" . $this->_html . "" ) julkinen funktio __call($name, $args) ( $this->_logout_link->$name($args); ) ) luokka LogoutLinkUnderlineDecorator laajentaa HtmlLinkkejä ( suojattu $ _logout_link; julkinen funktio __construct($logout_link) ( $this->_logout_link = $logout_link; $this->setHtml("" . $this->_html . ""); ) julkinen funktio __call($name, $ args) ( $this->_logout_link->$name($args ) ) luokka LogoutLinkStrongDecorator laajentaa HtmlLinkit ( suojattu $_logout_link; julkinen toiminto __construct($logout_link) ( $this->_logout_link = $logout_link; $this->setHtml("" . $this->_html . ""); ) julkinen funktio __call($nimi, $args) ( $this->_logout_link->$name($args); ) )

Nyt voimme käyttää niitä näin:

$logout_link = uusi LogoutLink(); if($is_logged_in) ( $logout_link = new LogoutLinkStrongDecorator($logout_link); ) if($in_home_page) ( $logout_link = new LogoutLinkH2Decorator($logout_link); ) else ( $logout_link = new LogoutLinkUnderlineDecorator);- $logout_link_); >render();

Huomaa, kuinka voit käyttää useita sisustajia samassa esineessä. Ne kaikki käyttävät __call-funktiota kutsuakseen alkuperäistä menetelmää. Jos kirjaudumme tilillemme ja siirrymme etusivulle, tulos on seuraava:

Kirjautua ulos

Malli "Single"

Yksinäinen- generointimalli, jonka avulla voit varmistaa, että ohjelman suorittamisen aikana luodaan vain yksi esiintymä luokasta, jolla on yleinen pääsy.

Sitä voidaan käyttää "koordinaatiopisteenä" muille objekteille, koska Singleton-kentät ovat samat kaikille, jotka kutsuvat sitä.

Kuinka käyttää sitä?

Jos sinun on välitettävä tietty ilmentymä luokasta toiselle, voit välittää sen joka kerta konstruktorin kautta tai käyttää Singletonia. Oletetaan, että sinulla on Istunto-luokka, joka sisältää tiedot nykyisestä istunnosta. Koska istunto alustetaan vain kerran, voimme toteuttaa sen seuraavasti:

Luokkaistunto ( yksityinen staattinen $instanssi; julkinen staattinen funktio getInstance() ( if(is_null(self::$instance)) ( self::$instance = new self(); ) return self::$instance; ) yksityinen funktio __construct () ( ) yksityinen funktio __clone() ( ) // muut istuntomenetelmät... ... ... ) // hanki istunnon esiintymä $session = Session::getInstance();

Nyt voimme päästä istuntoon koodin eri osista, jopa muista luokista. GetInstance-menetelmä palauttaa aina saman istunnon.

Johtopäätös

Tässä artikkelissa tarkastelimme vain yleisimpiä malleja monista. Jos haluat oppia lisää suunnittelumalleista, löydät paljon tietoa Wikipediasta. Lisää täydelliset tiedot katso kuuluisa kirja "Object Oriented Design Techniques", jonka on kirjoittanut Gang of Four.

Ja lopuksi: kun käytät tätä tai tätä mallia, varmista, että ratkaiset ongelman oikea tapa. Kuten mainittiin, väärin käytettynä suunnittelukuviot voivat aiheuttaa lisää ongelmia kuin päättää. Mutta jos ne tehdään oikein, niiden etuja ei voi yliarvioida.

Viimeksi päivitetty: 31.10.2015

Mitä ovat suunnittelumallit? Kuvio edustaa tiettyä tapaa rakentaa ohjelmakoodi yleisten suunnitteluongelmien ratkaisemiseksi. Tässä tapauksessa oletetaan, että on olemassa tietty joukko yleisiä formalisoituja ongelmia, joita esiintyy melko usein, ja mallit tarjoavat joukon periaatteita näiden ongelmien ratkaisemiseksi.

Vaikka ajatus kuvioista tapana kuvata ratkaisuja yleisiin suunnitteluongelmiin syntyi jo kauan sitten, niiden suosio alkoi kasvaa suurelta osin johtuen kuuluisa teos neljä kirjailijaa Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides, jonka nimi oli "Design Patterns: Elements of Reusable Object-Oriented Software" (venäjäksi "Object-Oriented Design Techniques. Design Patterns") ja joka julkaistiin vuonna 1994. Ja itse kirjoittajatiimiä kutsutaan usein nimellä "Gang of Four" tai "Gang of Four" tai lyhennettynä GoF. Tämä kirja oli pohjimmiltaan ensimmäinen laajamittainen yritys kuvata yleisiä ohjelmien suunnittelumenetelmiä. Ja ajan myötä kuvioiden käyttöä alettiin pitää hyvänä ohjelmointikäytäntönä.

Mitä kuvioiden käyttö antaa meille? Ohjelmia kirjoitettaessa voimme formalisoida ongelman luokkien ja objektien sekä niiden välisten suhteiden muodossa. Ja ratkaise se käyttämällä jotakin olemassa olevista malleista. Tämän seurauksena meidän ei tarvitse keksiä mitään. Meillä on jo valmis malli, ja meidän on vain käytettävä sitä tietyssä ohjelmassa.

Lisäksi kuviot eivät pääsääntöisesti riipu ohjelmointikielestä. Niiden soveltamisperiaatteet ovat samanlaiset C#:ssa, Javessa ja muilla kielillä. Vaikka tässä oppaassa puhumme malleista C#-kielen yhteydessä.

Kaavoissa ajattelu helpottaa myös ohjelmien kehittämistä ryhmässä. Kun tuntee käytetyn suunnittelumallin ja sen perusperiaatteet, toisen ohjelmoijan on helpompi ymmärtää ja käyttää sen toteutusta.

Samanaikaisesti sinun ei pitäisi käyttää kuvioita itse kuvioiden vuoksi. Hyvä ohjelma sisältää kuvioiden käytön. Mallit eivät kuitenkaan aina yksinkertaista ja paranna ohjelmaa. Niiden perusteeton käyttö voi johtaa ohjelmakoodin monimutkaisuuteen ja sen laadun heikkenemiseen. Mallin tulee olla perusteltu ja tehokas tapa ongelman ratkaisemiseksi.

On monia erilaisia ​​​​malleja, jotka ratkaisevat erilaisia ​​ongelmia ja esiintyä erilaisia ​​tehtäviä. Mutta toimintansa mukaan ne voidaan yhdistää useiksi ryhmiksi. Katsotaanpa joitain kuvioryhmiä. Perusmallien luokittelu perustuu tarkoitukseen tai tehtäviin, joita tietty kuvio suorittaa.

Generatiiviset mallit

Generatiiviset mallit ovat kuvioita, jotka abstraktioivat ilmentymisprosessin tai toisin sanoen luokkien ja objektien luomisprosessin. Niistä erottuvat seuraavat:

    Rakentaja

    Prototyyppi

    Singleton

Toinen malliryhmä - rakenteellisia malleja- tutkii, kuinka luokat ja objektit muodostavat suurempia rakenteita - luokkia ja objekteja, jotka ovat luonteeltaan monimutkaisempia. Nämä mallit sisältävät:

    Sovitin

    Silta

    Komposiitti

    Sisustusarkkitehti

    Julkisivu

    Kärpässarja

    sijainen (valtuutettu)

Kolmatta malliryhmää kutsutaan käyttäytymismalliksi - ne määrittelevät algoritmeja ja vuorovaikutuksia luokkien ja objektien välillä, eli niiden käyttäytymistä. Tällaisten mallien joukossa ovat seuraavat:

    Komento

    Tulkki

    Iteraattori

    Välittäjä

    huoltaja (muisto)

    Tarkkailija

    Osavaltio

    strategia

    Mallimenetelmä

    Vierailija

Kuvioille on olemassa muita luokituksia riippuen siitä, kuuluuko kuvio luokkiin vai objekteihin.

Luokkamallit kuvaavat luokkien välisiä suhteita periytymisen kautta. Luokkien väliset suhteet määritellään käännöshetkellä. Näitä malleja ovat:

    Tehdasmenetelmä

    Tulkki

    Mallimenetelmä

    Sovitin

Toinen osa kuvioista - esinekuvioita kuvaa objektien välisiä suhteita. Nämä suhteet syntyvät ajon aikana ja ovat siksi joustavampia. Objektimallit sisältävät seuraavat:

    Abstrakti tehdas

    Rakentaja

    Prototyyppi

    Singleton

    Silta

    Komposiitti

    Sisustusarkkitehti

    Julkisivu

    Kärpässarja

    sijainen (valtuutettu)

    Vastuuketju

    Komento

    Iteraattori

    Välittäjä

    huoltaja (muisto)

    Tarkkailija

    Osavaltio

    strategia

    Vierailija

Ja nämä ovat vain joitain tärkeimmistä malleista. Yleensä erilaisia ​​suunnittelumalleja on paljon enemmän. Jotkut niistä ovat vasta alkaneet käyttää, toiset ovat tällä hetkellä suosittuja, ja jotkut ovat jo vähemmän yleisiä kuin ennen.

Ja sisään tämä käsikirja Tarkastellaan perus- ja yleisimpiä niiden käytön malleja ja periaatteita suhteessa C#-kieleen.

Kuinka valita oikea kuvio?

Ensinnäkin ongelmaa ratkaistaessa tulee tunnistaa kaikki käytetyt entiteetit ja niiden väliset yhteydet ja abstrakti ne tietystä tilanteesta. Sitten sinun on katsottava, sopiiko abstrakti ongelmanratkaisumuoto tiettyyn malliin. Esimerkiksi ratkaistavan ongelman ydin voi olla uusien objektien luominen. Tässä tapauksessa saattaa olla syytä tarkastella generatiivisia malleja. Lisäksi on parempi olla ottamatta heti tiettyä mallia - ensimmäinen, joka näytti tarpeelliselta, vaan tarkastella useita saman ryhmän liittyviä kuvioita, jotka ratkaisevat saman ongelman.

Samalla on tärkeää ymmärtää kuvion merkitys ja tarkoitus, esittää selkeästi sen abstrakti organisaatio ja sen mahdolliset konkreettiset toteutukset. Yhdellä mallilla voi olla erilaisia ​​toteutuksia, ja mitä useammin kohtaat näitä toteutuksia, sitä paremmin ymmärrät kuvion merkityksen. Mutta sinun ei pitäisi käyttää kuviota, jos et ymmärrä sitä, vaikka se ensi silmäyksellä auttaisi sinua ratkaisemaan ongelman.

Ja viime kädessä meidän on noudatettava KISS-periaatetta (Keep It Simple, Stupid) - pidä ohjelmakoodi mahdollisimman yksinkertaisena ja selkeänä. Loppujen lopuksi kuvioiden tarkoitus ei ole monimutkaista ohjelmakoodia, vaan pikemminkin yksinkertaistaa sitä.

Niiden ytimessä ovat kuviot tavalliset mallit design. Lainattu tavallisilta arkkitehteiltä (rakennuksia käsitteleviltä). Pointti on yksinkertainen. Arkkitehdin työssä on tehtäviä, jotka voidaan kätevästi ratkaista yhdellä tai useammalla todistetulla tavalla.

Analogisesti ohjelmistosuunnittelussa on omat arkkitehtoniset ongelmansa, kuten sovelluksen jakaminen komponentteihin/moduuleihin, riippuvuuksien järjestäminen niiden välillä, toiminnallisten vastuiden jakaminen jne. Kuten kirjan kirjoittajat tästä neljän hengen jengistä ("Neljän jengi") taitavasti huomauttivat, toimialallamme on myös mahdollista tunnistaa tietty määrä käytännössä testattuja vakiomalleja, jotta ei astuta haravalle. jonka muut ovat jo ohittaneet.

Kuvioiden ymmärtämisen ydin on ymmärtää, missä tilanteissa on oikein käyttää tiettyä suunnittelumallia ja soveltaa sitä oikein. On tärkeää ymmärtää, että kaava "mitä enemmän malleja voin laittaa sovellukseeni, sitä parempi" on virheellinen. Niitä tulee käyttää viisaasti ja vain siellä, missä niitä todella tarvitaan. Lisäksi kuviot vanhenevat ja muuttuvat anti-kuvioiksi tekniikan kehittyessä (joka alallamme tekee tämän enemmän kuin nopeasti). Ja tietysti on yleisesti hyväksyttyjä malleja ja niitä, joita käytetään menestyksekkäästi kapeissa piireissä.
Tässäkin sinun on ymmärrettävä, että tämä ei ole jonkinlainen dogmi - kuten 10 pyhää suunnittelumallia :)

Tarvitset kokemusta ymmärtääksesi, missä niitä tarvitaan. Eli (olen henkilökohtaisesti vakuuttunut), että vain erittäin rajallinen määrä ihmisiä voi oppia toisten virheistä. Kaikki muut joutuvat itse keksimään :)

Annan seuraavat vinkit kuvioiden opiskeluun:

1) Lue pari kirjaa ymmärtääksesi, millainen eläin tämä on ja minkä kanssa sitä syödään. Voit ottaa yhden GoF-kirjan muunnelmista tai joitain johdannaisia ​​kehityspinoasi - tutustu tärkeimpiin suosittuihin malleihin. Heti tämän jälkeen suosittelen lukemaan kirjan "Javan katkera maku" (Bruce Tate) - se kertoo anti-kuvioista. Tämä on ymmärrettävä kääntöpuoli niiden käyttöä. Pidin siitä ja mielestäni se säästi minut monilta ongelmilta. Java-esimerkillä ei ole merkitystä. Se on noin malleista, jotta muiden pinojen edustajat (mukaan lukien minä) ymmärtävät joka tapauksessa helposti.

2) Yritä oivaltaa, oletko koskaan kohdannut työssäsi jotain, joka on tai voisi helposti tulla yhdeksi kaavoista. Missä konseptia oli mahdollista soveltaa oikein, ja missä oli vain ongelmia sen vuoksi.

3) Pidä uusissa projekteissa malleista hankittu tieto päässäsi - se tulee yhtäkkiä tarpeeseen.

Loppujen lopuksi, tiedät kuviot tai et, kokemuksen myötä tulee ymmärrys siitä, mikä arkkitehtuuri on oikea ja mikä ei. Kuinka tehdä siitä kätevä ja miten ei. Ja sillä ei ole väliä, millä kaavoilla sitä kutsut.

Suosittelen jopa lähestymään IT-arkkitehtonisen viisauden kehittämistä toiselta puolelta - ei-toiminnallisten vaatimusten tai ns. "-ilities" puolelta - niitä on monia. Tässä on kuvattu 7 kappaletta. Yleensä niitä on kymmeniä.

Muun muassa - kuten ylläpidettävyys ( yksinkertainen tuki koodi), skaalautuvuus, laajennettavuus, saatavuus jne. Jos mietit sovellustasi suunnitellessasi näitä ”ilityjä” ja yrität tarjota niitä projektin kannalta tarpeellisessa laajuudessa, sovelluksellasi on pääsääntöisesti erinomainen arkkitehtuuri. Samalla suunnittelukuviot ilmestyvät siihen ytimekkäästi itsestään.

Koska idea mallien käytöstä on kokeneiden ohjelmistosuunnittelijoiden yritys antaa tusinaa valmista reseptiä vähemmän kokeneemmille, jotta he eivät kypsennä jotain täysin syömätöntä ennen kuin he oppivat keittämään "herkullista puuroa". :) Opettele "kokkaamaan", ymmärtämään -ilites :) ja kaikki on hyvin

Arkkitehtuuri

Tietokoneohjelmien suunnittelu

Tarina

Hyöty

Jokaisen tärkein hyöty erillinen malli on, että se kuvaa ratkaisun kokonaiseen abstraktien ongelmien luokkaan. Lisäksi se, että jokaisella kuviolla on oma nimi, helpottaa abstraktien tietorakenteiden (ADT) keskustelua kehittäjien kesken, koska ne voivat viitata tunnettuihin malleihin. Siten mallien, terminologian, moduulien ja projektielementtien nimet ovat yhtenäisiä.

Oikein muotoiltu suunnittelukuvio mahdollistaa sen, että onnistuneen ratkaisun löydettyä, sitä voidaan käyttää uudestaan ​​ja uudestaan.

Toisin kuin idiomit, mallit ovat riippumattomia käytetystä ohjelmointikielestä.

Kritiikkiä

Joskus mallit säilyttävät kapean ryhmän kehittämän hankalan ja tehottoman käsitejärjestelmän. Kun kuvioiden määrä kasvaa yli kriittisen monimutkaisuuden, esiintyjät alkavat jättää huomiotta kuviot ja koko niihin liittyvä järjestelmä.

Mallit korvaavat usein dokumentaation puutteen tai riittämättömyyden monimutkaisessa ohjelmistoympäristössä.

On olemassa mielipide, että hakuteoksen mallien sokea soveltaminen ymmärtämättä jokaisen yksittäisen mallin tunnistamisen syitä ja edellytyksiä hidastaa ohjelmoijan ammatillista kasvua, koska se korvaa luovan työn mallien mekaanisella korvaamisella. Ihmiset, jotka noudattavat tätä mielipidettä, uskovat, että sinun tulee tutustua malliluetteloihin, kun olet "kasvanut" niihin ammattimaisesti - eikä aikaisemmin. Hyvä kriteeri vaadittava ammattitaito - mallien tunnistaminen itsenäisesti, niiden perusteella oma kokemus. Samalla tietysti kaavoihin liittyvän teorian tuntemus on hyödyllistä kaikilla ammattitason tasoilla ja ohjaa ohjelmoijan kehittymistä oikeaan suuntaan. Ainoastaan ​​"viitekirjan mukaisten" mallien käyttö on kyseenalaista.

Mallit voivat edistää huonoja sovelluskehitystyylejä, ja niitä käytetään usein sokeasti.

Näiden puutteiden voittamiseksi käytetään uudelleenjärjestelyä.

Suunnittelukuvioiden perustyypit

Perusmallit (Fundamental)

  • Merkin käyttöliittymä
  • Kiinteistösäiliö

Generatiiviset suunnittelumallit

  • Tehdasmenetelmä, virtuaalinen rakentaja
  • Nimettömät aliohjelmaobjektit

Rakenteelliset mallit

  • Välityspalvelin / sijainen, sijainen
  • Säiliö
  • Laajennettavuus
  • Putket ja suodattimet
  • Yksityiset luokkatiedot

Käyttäytymismallit

Rinnakkaisohjelmointimallit (samanaikaisuus)

  • Aktiivinen objekti
  • Balking
  • Suojattu jousitus
  • Half-Sync/Half-Async
  • Johtajat/seuraajat
  • Monitor Object
  • Reaktori
  • Lue kirjoituslukko
  • Ajastin
  • Lanka allas
  • Säiekohtainen tallennustila
  • Yhden säikeen suoritus

MVC

  • Yritys

    Lajittelematon

    • Kiinteistösäiliö
    • Tapahtumakanava
    • Arkisto/Tallennus

    Muuntyyppiset mallit

    Nykyään on myös useita muita malleja:

    • Carrier Rider Mapper, joka tarjoaa pääsyn tallennettuihin tietoihin
    • analyyttiset mallit kuvaavat peruslähestymistavan ohjelmistovaatimusten kehittämiseen (vaatimusanalyysi) ennen kuin ohjelmistokehitysprosessi alkaa
    • viestintämallit kuvaavat viestintäprosessia organisaation yksittäisten osallistujien/työntekijöiden välillä
    • organisaatiomallit, kuvaavat yrityksen/yrityksen organisaatiohierarkiaa
    • Suunnittelun vastaiset mallit kuvaavat, mitä ei pidä tehdä ohjelmia kehitettäessä, ja ne osoittavat tyypillisiä suunnittelu- ja toteutusvirheitä.

    Katso myös

    • Yleistetty ohjelmointi
    • Linkit

      • Olga Dubina Design Patterns Review. - Katsaus useisiin merkittävimpiin suunnittelumalleja käsitteleviin monografioihin tietojärjestelmä. Haettu 5. syyskuuta 2006.
      • Portland Pattern Repository - luettelo wiki-moottorin suunnittelumalleista
      • mgrandin kirja - sivusto, jossa on kuvaus suuresta määrästä suunnittelumalleja
      • Resign Patterns - projektiin suuntautuneen suunnittelun rikkomukset (kuvioiden parodia)
      • Eclipsen laivauskulttuuri (englanniksi) Erich Gamma

      Kirjallisuus

      • E. Gamma, R. Helm, R. Johnson, J. Vlissides Oliolähtöiset suunnittelutekniikat. Suunnittelumallit = Suunnittelumallit: Uudelleenkäytettävän olio-ohjelmiston elementit. - Pietari: "Peter", 2007. - S. 366. - ISBN 978-5-469-01136-1 (myös ISBN 5-272-00355-1)
      • Craig Larman UML:n sovellus 2.0 ja suunnittelumallit = UML:n ja mallien soveltaminen: Johdatus olio-analyysiin ja suunnitteluun ja iteratiiviseen kehittämiseen. - M.: "Williams", 2006. - S. 736. - ISBN 0-13-148906-2
      • Martin Fowler Yritysarkkitehtuuri ohjelmistosovelluksia= Patterns of Enterprise Application Architecture (Addison-Wesley Signature Series). - M.: "Williams", 2007. - S. 544. - ISBN 0-321-12742-0
      • Joshua Kerievsky Refactoring to Patterns (Addison-Wesley Signature Series). - M.: "Williams", 2006. - S. 400. - ISBN 0-321-21335-1
      • Scott W. Ambler, Pramodkumar J. Sadalaj Refactoring Databases: Evolutionary Database Design (Addison-Wesley Signature Series). - M.: "Williams", 2007. - S. 368. - ISBN 0-321-29353-3

      Wikimedia Foundation. 2010.

  • Patterson, James
  • Patterson, Percival

Katso, mitä "suunnittelukuviot" ovat muissa sanakirjoissa:

    Suunnittelumalli- Tällä termillä on muita merkityksiä, katso kuvio. Ohjelmistokehityksessä suunnittelumalli on toistettava arkkitehtoninen suunnittelu, joka edustaa ratkaisua ongelmaan... ... Wikipedia

    Suunnittelumalleja- (kuvio, englanninkielinen design pattern) on uudelleenkäytettävä arkkitehtoninen rakenne, joka tarjoaa ratkaisun yleinen ongelma suunnittelu tietyssä kontekstissa ja kuvataan tämän päätöksen merkitystä. Malli ei ole täydellinen... ...Wikipedia

    GRASP Design Patterns- GRASP (General Responsibility Assignment Software Patterns) - mallit, joita käytetään oliosuunnittelussa ratkaisemaan yhteisiä tehtäviä määrittämällä vastuita luokille ja objekteille. Wikipediassa