Ohjelmointi

Johdatus suunnittelumalleihin, osa 1: Suunnittelumallien historia ja luokittelu

Lukuisia strategioita on suunniteltu yksinkertaistamaan ja vähentämään ohjelmistojen suunnittelun kustannuksia, erityisesti huollon alalla. Opi tunnistamaan uudelleenkäytettävät ohjelmistokomponentit (joskus kutsutaan nimellä) ohjelmisto-integroidut piirit) on yksi strategia. Suunnittelumallien käyttö on toinen asia.

Tämä artikkeli julkaisee kolmiosaisen sarjan suunnittelumalleista. Tässä osassa esitän suunnittelumallien käsitteellisen kehyksen ja käyn läpi esittelyn tietyn käyttötapauksen suunnittelumallin arvioimisesta. Keskustelen myös suunnittelumallien ja anti-kuvioiden historiasta. Lopuksi luokittelen ja tiivistän eniten käytetyt ohjelmistosuunnittelumallit, jotka on löydetty ja dokumentoitu parin viime vuosikymmenen aikana.

Mikä on suunnittelumalli?

Olemassa olevaa järjestelmää mallinnavien uudelleenkäytettävien olio-ohjelmistojen suunnittelu on aidosti haastavaa. Ohjelmistokehittäjän on luokiteltava järjestelmän entiteetit luokkiin, joiden julkiset rajapinnat eivät ole liian monimutkaisia, luotava suhteet luokkiin, paljastettava perintöhierarkiat ja paljon muuta. Koska suurin osa ohjelmistoista on käytössä kauan sen kirjoittamisen jälkeen, ohjelmistokehittäjien on myös vastattava nykyisiin sovellusvaatimuksiin pitäen samalla koodinsa ja infrastruktuurinsa riittävän joustavana vastaamaan tulevia tarpeita.

Kokeneet objektisuuntautuneet kehittäjät ovat havainneet, että ohjelmistosuunnittelumallit helpottavat vakaiden ja vankkojen ohjelmistojärjestelmien koodausta. Näiden suunnittelumallien uudelleenkäyttö pikemminkin kuin uusien ratkaisujen jatkuva kehittäminen tyhjästä on tehokasta, ja se vähentää virheriskiä. Jokainen suunnittelumalli tunnistaa toistuvan suunnitteluongelman tietyssä sovelluskontekstissa ja tarjoaa sitten yleistetyn, uudelleenkäytettävän ratkaisun, jota voidaan soveltaa erilaisiin sovellusskenaarioihin.

"A suunnittelumalli kuvaa luokat ja vuorovaikutuksessa olevat objektit, joita käytetään yleisen suunnitteluongelman ratkaisemiseen tietyssä kontekstissa. "

Jotkut kehittäjät määrittelevät a suunnittelumalli luokan koodattuna kokonaisuutena (kuten linkitetty luettelo tai bittivektori), kun taas toiset sanovat, että suunnittelumalli on koko sovelluksessa tai alijärjestelmässä. Katson, että a suunnittelumalli kuvaa luokat ja vuorovaikutuksessa olevat objektit, joita käytetään yleisen suunnitteluongelman ratkaisemiseen tietyssä kontekstissa. Muodollisemmin suunnittelumalli määritetään kuvaukseksi, joka koostuu neljästä peruselementistä:

  1. A nimi joka kuvaa suunnittelumallin ja antaa sanaston keskustelemaan siitä
  2. A ongelma joka tunnistaa ratkaistavan suunnittelun ongelman yhdessä kontekstin kanssa, jossa ongelma esiintyy
  3. A ratkaisu ongelman, jonka (ohjelmistosuunnittelumallin yhteydessä) tulisi tunnistaa luokat ja objektit, jotka vaikuttavat suunnitteluun, sekä niiden suhteet ja muut tekijät
  4. Selitys seuraukset suunnittelukuvion käytöstä

Jotta voit tunnistaa sopivan suunnittelumallin, sinun on ensin yksilöitävä selvästi ongelma, jonka yrität ratkaista; siinä ongelma Suunnittelumallin kuvauksen osa on hyödyllinen. Suunnittelumallin valitseminen toisen sijaan sisältää yleensä kompromisseja, jotka voivat vaikuttaa sovelluksen tai järjestelmän joustavuuteen ja tulevaan ylläpitoon. Siksi on tärkeää ymmärtää seuraukset tietyn mallin käyttämistä ennen sen aloittamista.

Suunnittelumallin arviointi

Harkitse tehtävää suunnitella monimutkainen käyttöliittymä painikkeilla, tekstikentillä ja muilla ei-säilöosilla. Komposiittisuunnittelukuvio pitää kontteja komponentteina, mikä antaa meille mahdollisuuden sijoittaa kontit ja niiden komponentit (kontit ja muut kuin kontit) muihin kontteihin ja tehdä niin rekursiivisesti. Jos päätämme olla käyttämättä komposiittikuviota, meidän on luotava monia erikoistuneita ei-kontti-komponentteja (yksi komponentti, joka yhdistää esimerkiksi salasanan tekstikentän ja kirjautumispainikkeen), mikä on vaikeampi saavuttaa.

Tämän jälkeen olemme ymmärtäneet ongelman, jota yritämme ratkaista, ja Composite-mallin tarjoaman ratkaisun. Mutta mitkä ovat seuraukset tämän mallin käytöstä?

Yhdistetyn komposiitin käyttäminen tarkoittaa, että luokkahierarkiat sekoittavat kontti- ja muut komponentit. Yksinkertaisemmat asiakkaat käsittelevät kontti- ja muita osia yhtenäisesti. Ja uudenlaisten komponenttien tuominen käyttöliittymään on helpompaa. Komposiitti voi myös johtaa liian yleistetty malleja, mikä vaikeuttaa sellaisten komponenttien rajoittamista, jotka voidaan lisätä astiaan. Koska et voi luottaa kääntäjään pakottamaan tyyppirajoituksia, sinun on käytettävä ajonaikaisia ​​tyyppitarkistuksia.

Mitä vikaa ajonaikaisissa tarkastuksissa on?

Suorituksen tyyppitarkistuksiin sisältyy jos lausunnot ja esiintymä operaattori, mikä johtaa hauraaseen koodiin. Jos unohdat päivittää ajonaikaisen tyyppitarkistuksen sovelluksen vaatimusten kehittyessä, voit myöhemmin ottaa käyttöön virheitä.

On myös mahdollista valita sopiva suunnittelumalli ja käyttää sitä väärin. Kaksinkertaisesti tarkistettu lukitus kuvio on klassinen esimerkki. Kaksinkertaisesti tarkistettu lukitus vähentää lukon hankkimisen yleiskustannuksia testaamalla ensin lukituskriteerin ilman, että lukko on tosiasiallisesti hankittu, ja hankkimalla sitten lukon vain, jos tarkistus osoittaa, että lukitusta tarvitaan. Vaikka se näytti hyvältä paperilla, JDK 1.4: n kaksoistarkistetulla lukituksella oli piilotettuja monimutkaisuuksia. Kun JDK 5 laajensi haihtuva avainsanalla kehittäjät saivat vihdoin hyötyä kaksinkertaisen tarkistetun lukituskuvion eduista.

Lisätietoja kaksinkertaisesti tarkistetusta lukituksesta

Katso "Kaksinkertaisesti tarkistettu lukitus: älykäs, mutta rikki" ja "Voiko kaksinkertaisesti tarkistettu lukitus korjata?" (Brian Goetz, JavaWorld) saadaksesi lisätietoja siitä, miksi tämä malli ei toiminut JDK 1.4: ssä ja aikaisemmissa. Lisätietoja DCL: n määrittämisestä JDK 5: ssä ja uudemmissa, katso "The Double-Checked Locking is Broken 'Declaration" (Marylandin yliopiston tietojenkäsittelytieteen laitos, David Bacon et ai.).

Anti-kuviot

Kun suunnittelukuviota käytetään yleisesti, mutta se on tehotonta ja / tai haitallista, suunnittelukuvio tunnetaan nimellä anti-kuvio. Voidaan väittää, että JDK 1.4: ssä ja aikaisemmin käytetty kaksinkertainen tarkistettu lukitus oli anti-kuvio. Sanoisin, että se oli vain huono idea tässä yhteydessä. Jotta huono idea kehittyy anti-malliksi, seuraavien ehtojen on täytyttävä (katso Resurssit).

  • Toistuva toimintamalli, prosessi tai rakenne, joka näyttää alun perin olevan hyödyllinen, mutta tuottaa lopulta enemmän huonoja seurauksia kuin hyödyllisiä tuloksia.
  • On olemassa vaihtoehtoinen ratkaisu, joka on selkeästi dokumentoitu, käytännössä todistettu ja toistettavissa.

Vaikka JDK 1.4: n kaksinkertainen tarkistettu lukitus täytti anti-mallin ensimmäisen vaatimuksen, se ei vastannut toista: vaikka voit käyttää synkronoitu ratkaistakseen laiskan alustuksen ongelman monisäikeisessä ympäristössä, niin tekemällä se olisi voittanut syyn käyttää kaksoistarkistettua lukitusta.

Lukkiutumattomat anti-kuviot

Anti-mallien tunnistaminen on edellytys niiden välttämiselle. Lue Obi Ezechukwun kolmiosainen sarja, jossa on johdatus kolmeen anti-malliin, jotka ovat kuuluisia umpikujan aiheuttamisesta:

  • Ei välimiesmenettelyä
  • Työntekijöiden yhdistäminen
  • Asteittainen lukitus

Suunnittelumallihistoria

Suunnittelumallit ovat peräisin 1970-luvun lopulta Kuviokieli: kaupungit, rakennukset, rakentaminen arkkitehti Christopher Alexander ja muutamat muut. Tämä kirja esitteli suunnittelumallit arkkitehtonisessa yhteydessä ja esitteli 253 kuviota, jotka muodostivat yhdessä sen, mitä kirjoittajat kutsuivat kuvion kieli.

Suunnittelumallien ironia

Vaikka ohjelmistosuunnittelussa käytetyt suunnittelumallit jäljittävät niiden alun Kuviokieli, tähän arkkitehtoniseen työhön vaikutti silloin syntynyt kieli kuvaamaan tietokoneohjelmointia ja suunnittelua.

Kuviokielen käsite syntyi myöhemmin Donald Normanin ja Stephen Draperin käsitteissä Käyttäjäkeskeinen järjestelmän suunnittelu, joka julkaistiin vuonna 1986. Tässä kirjassa ehdotettiin kuviokielien käyttöä vuorovaikutussuunnittelu, joka on käytäntö suunnitella interaktiivisia digitaalisia tuotteita, ympäristöjä, järjestelmiä ja palveluja ihmisille.

Samaan aikaan Kent Beck ja Ward Cunningham olivat alkaneet tutkia malleja ja niiden sovellettavuutta ohjelmistosuunnitteluun. Vuonna 1987 he käyttivät sarjaa kuvioita auttaakseen Tektronixin Semiconductor Test Systems Groupia, jolla oli vaikeuksia viimeistellä suunnitteluprojektia. Beck ja Cunningham seurasivat Aleksanterin neuvoja käyttäjäkeskeisessä suunnittelussa (antamalla projektin käyttäjien edustajien määrittää suunnittelun lopputulos) ja samalla heille joitain suunnittelumalleja työn helpottamiseksi.

Erich Gamma huomasi myös toistuvien suunnittelumallien merkityksen väitöskirjansa parissa. Hän uskoi, että suunnittelumallit voivat helpottaa uudelleenkäytettävien olio-ohjelmistojen kirjoittamista, ja pohti, kuinka dokumentoida ja kommunikoida tehokkaasti. Gamma ja Richard Helm alkoivat kuvastaa malleja ennen vuotta 1991 pidettyä olio-ohjelmoinnin konferenssia.

Vuonna 1991 pidetyssä OOPSLA-työpajassa Gamma ja Helm liittyivät Ralph Johnsonin ja John Vlissidesin kanssa. Tämä Neljän jengi (GoF), kuten he myöhemmin tunnettiin, kirjoitti edelleen suosittua Suunnittelumallit: Uudelleenkäytettävien olio-ohjelmistojen elementit, joka dokumentoi 23 suunnittelumallia kolmessa kategoriassa.

Suunnittelumallien moderni kehitys

Suunnittelumallien kehitys on jatkunut alkuperäisen GoF-kirjan jälkeen, varsinkin kun ohjelmistokehittäjät ovat kohdanneet uusia haasteita, jotka liittyvät laitteisto- ja sovellusvaatimusten muuttamiseen.

Vuonna 1994 yhdysvaltalainen voittoa tavoittelematon järjestö, joka tunnetaan nimellä Hillside Group, vihittiin käyttöön Ohjelmasuunnittelukielet, ryhmä vuosittaisia ​​konferensseja, joiden tavoitteena on kehittää ja parantaa ohjelmistosuunnittelumallien taidetta. Nämä käynnissä olevat konferenssit ovat tuottaneet monia esimerkkejä toimialakohtaisista suunnittelumalleista. Esimerkiksi suunnittelumallit samanaikaisuuden yhteydessä.

Christopher Alexander OOPSLA: ssa

OOPSLA 96: n pääpuheen piti arkkitehti Christopher Alexander.Alexander pohti työstään ja siitä, kuinka olio-ohjelmointiyhteisö oli osunut ja jättänyt merkin omaksumalla ja mukauttamalla kuvakieliä koskevat ajatuksensa ohjelmistoihin. Voit lukea Aleksanterin puheen kokonaisuudessaan: "Kuvioteorian alkuperä: teorian tulevaisuus ja elävän maailman luominen".

Vuonna 1998 Mark Grand julkaisi Java-mallit. Tämä kirja sisälsi suunnittelumalleja, joita ei löydy GoF-kirjasta, mukaan lukien samanaikaisuusmallit. Grand käytti myös Unified Modeling Language (UML) -mallia kuvailemaan suunnittelumalleja ja niiden ratkaisuja. Kirjan esimerkit on ilmaistu ja kuvattu Java-kielellä.

Ohjelmistosuunnittelumallit luokituksen mukaan

Nykyaikaiset ohjelmistosuunnittelumallit luokitellaan pääpiirteittäin neljään luokkaan niiden käytön perusteella: luovuus, rakenne, käyttäytyminen ja samanaikaisuus. Keskustelen kustakin luokasta ja sitten luetelen ja kuvaan joitain merkittävimpiä malleja jokaiselle.

Muuntyyppiset suunnittelumallit

Jos ajattelet, että malleja on enemmän, olet oikeassa. Tämän sarjan myöhemmässä artikkelissa käsitellään muita suunnittelumallityyppejä: vuorovaikutus-, arkkitehti-, organisaatio- ja viestintä- / esityskuviot.

Luovuusmallit

A luova malli tiivistää ilmentymisprosessin erottaen kuinka objektit luodaan, muodostetaan ja esitetään niistä riippuvasta koodista. Luokan luontikuviot käyttää perintöä vaihtelemaan luokat, jotka ovat instantisoituneita, ja esineiden luontikuviot delegoida instantiation muille kohteille.

  • Abstrakti tehdas: Tämä malli tarjoaa käyttöliittymän kapseloimaan ryhmän yksittäisiä tehtaita, joilla on yhteinen teema määrittelemättä niiden konkreettisia luokkia.
  • Rakentaja: Erottaa monimutkaisen kohteen rakentamisen esityksestä, jolloin sama rakennusprosessi voi luoda erilaisia ​​esityksiä. Kohteen rakentamisen vaiheiden tiivistäminen antaa vaiheiden erilaisille toteutuksille mahdollisuuden rakentaa esineiden erilaisia ​​esityksiä.
  • Tehdasmenetelmä: Määrittää käyttöliittymän objektin luomista varten, mutta antaa aliluokkien päättää, minkä luokan instantisoida. Tämän mallin avulla luokka voi lykätä alustamista alaluokiin. Riippuvuusinjektio on siihen liittyvä malli. (Katso Resurssit.)
  • Laiska alustus: Tämä malli antaa meille mahdollisuuden viivästyttää objektien luomista, tietokannan hakua tai muuta kallista prosessia, kunnes tulos tarvitaan ensimmäistä kertaa.
  • Multiton: Laajentaa singleton-konseptia nimettyjen luokan esiintymien kartan hallitsemiseksi avainarvopareina ja tarjoaa yleisen pääsypisteen niihin.
  • Kohdeallas: Pidä alustettujen objektien joukko käyttövalmiina sen sijaan, että ne voidaan allokoida ja tuhota tarpeen mukaan. Tarkoitus on välttää kalliita resurssien hankkimista ja hyödyntämistä kierrättämällä esineitä, jotka eivät ole enää käytössä.
  • Prototyyppi: Määrittää prototyyppisen esiintymän avulla luotavien objektien tyypit ja luo sitten uusia objekteja kopioimalla tämä prototyyppi. Prototyyppinen esiintymä kloonataan uusien objektien luomiseksi.
  • Resurssien hankinta on alustusta: Tämä malli varmistaa, että resurssit alustetaan ja palautetaan automaattisesti ja asianmukaisesti sitomalla ne sopivien esineiden elinikään. Resurssit hankitaan objektin alustamisen aikana, kun niitä ei ole mahdollisuutta käyttää ennen kuin ne ovat käytettävissä, ja vapautetaan samojen esineiden tuhoutumisella, mikä taataan myös virheiden tapauksessa.
  • Singleton: Varmistaa, että luokassa on vain yksi esiintymä, ja tarjoaa yleisen pääsypisteen tälle esiintymälle.