Antisuunnittelumalli

Suunnittelumalleja voidaan myös esittää **antisuunnittelumalleina**, jolloin tavoitteena on tunnistaa annetun kuvauksen perusteella jokin ohjelmiston, projektin tai prosessin rakenteessa oleva perustavanlaatuinen ongelma johon antisuunnittelumalli esittää korjausehdotuksen tai tavan vähentää ongelman kriittisyyttä. Teoksen määritelmä antisuunnittelumallin käsitteelle on laajempi kuin Erich Gamman suunnittelumallien käsite, koska se sisältää itse ohjelman arkkitehtuurista riippumattomia ongelmakokonaisuuksia, kuten ongelmat ohjelmistotuotantoprosessissa ja projektin johdossa.

Antisuunnittelumallien ymmärtäminen voi olla joskus hyödyllisempää kuin varsinaiset suunnittelumallit, koska niiden perusteella kehittäjät voivat löytää sovelluksestaan toteutustapoja joita he eivät ole aikaisemmin ymmärtäneet ongelmallisiksi. Antisuunnittelumallit antavat hyödyllisiä vinkkejä, kun olemassa olevaa ohjelmistoa tulee parantaa tai kehittää edelleen.

## Esimerkkejä antisuunnittelumalleista
### Organisatorisia antisuunnittelumalleja
* Analyysihalvaus (analysis paralysis): Uhrataan suhteettoman suuri panos projektin analyysivaiheeseen.
* Jatkuva vanhentuminen (continuous obsolescence): Uhrataan suhteettoman suuri panos järjestelmän viemiseksi uusiin ympäristöihin.
* Kasautuvat ominaisuudet (creeping featurism): Ohjelmaan lisätään "muutamia pieniä" ominaisuuksia, eikä osata lopettaa ajoissa.
* Komiteasuunnittelu (design by commitee): Väärä suunnittelu johtuen yhtenäisen vision puutteesta.
* Liiallinen sitoutuminen (escalation of commitment): Kykenemättömyys kumota päätös sen osoittautuessa vääräksi.
* Sankarityyli (hero-mode): Tapa luottaa jatkuvasti henkilökunnan sankarillisiin panoksiin jotta saavutettaisiin mahdottomat aikarajat jättäen samanaikaisesti huomiotta se, mitä huonolaatuisen ohjelman kehittäminen on tullut alun perin maksamaan.
* Minähän sanoin (I told you so): Kun asiantuntijan antama mutta laiminlyöty varoitus osoittautuukin oikeaksi, tulee asiantuntija jälleen huomion keskipisteeksi.
* Luvuilla pelailu (management by numbers): Painotetaan liiaksi vain määrällisiä hallintakriteereitä, vaikka ne olisivat epäolennaisia tai maksaisivat liikaa.
* Junttaus (management by perkele): Armeijamainen hallitseminen sallimatta eriäviä mielipiteitä.
* Moraalikato (moral hazard): Eristetään päätöksentekijä päätöksensä seurauksista.
* Herkkusienijohtaminen (mushroom management): Ei välitetä tiedottaa työntekijöille ja hyväksikäytetään heitä, ja koetaan pätevät työntekijät uhkana omalle arvovallalle (pidetään pimeässä ja kylmässä, ruokitaan lannalla - ja kun on kasvanut tarpeeksi isoksi, leikataan pää poikki).
* Me emme keksineet sitä (Not Invented Here syndrome): Kieltäydytään liiketoiminnallisista, organisatorisista tai poliittisista syistä käyttämästä organisaation tai yksikön ulkopuolisten kehittäjien tekemää teknisessä mielessä täysin toimivaa ratkaisua.
* Paisuminen (scope creep): Sallitaan projektin laajuuden kasvaa ilman kunnollista hallintaa.
* Valmistajariippuvuus (vendor lock-in): Järjestelmä riippuu liikaa ohjelman ulkopuolella toimitetusta osasta.
* Viulunkieliorganisaatio (Violin string organization): Tiukaksi viritetty ja trimmattu organisaatio, jossa ei ole joustavuutta.

### Projektin hallinnan antisuunnittelumalleja
* Kuolonmarssi (Death March): Jokainen tietää, että projekti päätyy tuhoon -- paitsi pääjohtaja. Totuus jää kuitenkin piiloon ja sitä pidetään keinotekoisesti elossa kunnes päättöpäivä lopulta tulee ("Big Bang").
* Paisuminen (software bloat): Ohjelma kasvaa liian suureksi, siinä on liikaa ominaisuuksia ja sen käyttö kuluttaa liikaa resursseja.
* Illuusio (Smoke and mirrors): Esitellään miltä toteuttamattomat toiminnot tulisivat näyttämään.

### Tiiminhallinnan antisuunnittelumalleja
* Piileskelijä (Absentee Manager): Mikä tahansa tilanne, jossa johtaja on näkymätön pitkiä aikoja.
* Jos työvälineesi on vasara, niin kaikki näyttävät nauloilta (All You Have Is A Hammer): Yksiulotteinen ajattelu, jossa samaa tekniikkaa käytetään kaikkiin alaisiin.
* Nyrkkeilijä (Cage Match Negotiator): Kun johtaja käyttää "voitto hintaan mihin hyvänsä"-lähestymistapaa hallitsemisessa.
* Kaksoisolento (Doppelgänger): Johtaja tai kollega, joka voi olla kiva ja helppo yhtenä hetkenä sekä paha ja järjetön toisena hetkenä.
* Hedelmätön kierre (Fruitless Hoops): Johtaja, joka vaatii loputtomia (ja usein merkityksettömiä) tietoja ennen päätöksentekoa.
* Suosikki (Golden Child): Kun erikoisvastuu, -tilaisuus, -tunnustus, tai -palkinto annetaan tiiminjäsenelle suhteiden perusteella, eikä henkilön tekemisten perusteella.
* Päätön kana (Headless Chicken): Johtaja, joka on aina pakokauhuisella ja tulipalokiireisellä tuulella.
* Vetäjä-ei-hallinnoija (Leader Not Manager): Johtaja, joka on hyvä vetäjä, mutta ei kykene hallinnointiin.
* Hallinnoija-ei-vetäjä (Manager Not Leader): Etevä hallinnoija, joka ei kuitenkaan kykene johtajuuteen.
* Mittaliero (Metric Abuse):  Ilkeä tai pätemätön metriikan ja mittausten hyväksikäyttö.
* Veljeilijä (Mr. Nice Guy): Johtaja, joka yrittää olla kaikkien kaveri.
* Työläissankari (Proletariat Hero): Jokapaikanhöylä jota pidetään ihanteenta, mutta joka todellisuudessa tukee vain johdon kasvavia vaatimuksia ja laajenevia tuotantokohteita.
* Nousukas (Rising Upstart): Potentiaalinen tähti, joka ei jaksa odottaa vuoroaan ja haluaa luopua välttämättömästä oppimis-, kypsymis-, ja oman paikkansa löytämisajasta.
* Selkärangaton (Spineless Executive): Johtaja, jolla ei ole rohkeutta kohdata tilanteita, ottaa vastaan hankaluuksia, tai puolustaa alaisiaan.
* Kolmipäinen ritari (Three-Headed Knight): Päättämätön johtaja.
* Perusase (Ultimate Weapon): Ilmiöt, joihin kumppanit tai organisaatio luottavat niin paljon, että niiden kautta kanavoidaan kaikkia asioita.
* Lämmittelijä (Warm Bodies): Työntekijä, joka täyttää tuskin työn miniodotukset ja jota sen vuoksi pallotellaan projektista tai tiimistä toiseen.
* Jeesmies ("Yes" Man): Johtaja, joka on aina pomonsa kanssa samaa mieltä, vaikka hän olisi sanonut toisin kun pomo ei ollut läsnä.

### Analysoinnin antisuunnittelumalleja
* Lautasliinamäärittely (Napkin Specification): Toiminnallinen/tekninen määrittely annetaan Kehitystiimille lautasliinalla-- eli epämuodollisesti, ja ilman riittäviä yksityiskohtia-- mikä vastaa sitä, että määrittelyä ei ole ollenkaan.
* Käänteismäärittely (Retro-Specification): Tekninen/toiminnallinen määrittely kirjoitetaan vasta kun projekti on julkaistu.
* Tekaistut vaatimukset (Phony Requirements): Kaikki vaatimukset on välitetty kehitystiimille pikapikaa verkkotapaamisissa tai puhelimitse ilman toiminnallista/teknistä määrittelyä tai muuta kehitystä tukevaa dokumentaatiota.

### Yleissuunnittelun antisuunnittelumalleja
* Käänteisabstraktio (abstraktion inversion): Ei paljasteta toteutettua toiminnallisuutta käyttäjille, jolloin he toteuttavat toiminnallisuuden uudelleen käyttäen korkeamman tason toimintoja.
* Monitahoiset näkökulmat (Ambiguous viewpoint): Esitetään malli (yleensä oliosuuntautunut analyysi ja suunnittelumalli) määrittämättä mallin näkökulmaa.
* Iso klöntti (Big ball of mud): Systeemi, jossa ei ole havaittavaa rakennetta.
* Syöteviritelmä (Input kludge): Kykenemättömyys määritellä ja toteuttaa mahdollisen virheellisen syötteen käsittely.
* Rajapintaähky (Interface bloat): Tehdään rajapinta niin tehokkaaksi, että se on äärimmäisen vaikea toteuttaa.
* Kyhäelmä (Stovepipe system): Hädin tuskin ylläpidettävä kokonaisuus huonosti toisiinsa sopivia komponentteja.
* Taikanappi (magic pushbutton): Ohjelmoidaan toteutuslogiikka suoraan rajapintakoodiin, ilman abstraktiota.
* Kilpajuoksu (Race hazard): Ei kyetä näkemään erilaisten tapahtumakäskyjen seurauksia.
* Liittely (re-coupling): Otetaan käyttöön tarpeeton riippuvuus toisesta oliosta.

#### Olio-ohjelmoinnin antisuunnittelumalleja
* Jumalaluokka (god class, god object): Luokka joka tekee tai tietää liian paljon, esimerkiksi toteuttaa suuren osan ohjelmasta. Nämä yhteenkasaumat tulee hajauttaa muihin luokkiin.
* Virheiden kätkentä (error hiding): Käyttäjälle ei anneta tietoa tunnistetuista virhetilanteista, eikä anneta mahdollisuutta reagoida niihin.
* Sarjaankytkentä (sequential coupling): Luokka joka vaatii, että sen metodeja kutsutaan tietyssä järjestyksessä.
* Kuopattavat oliot: Käytetään uudelleen kierrättämällä olioita, joiden rakenne ei tue uudelleenkäyttöä.

### Ohjelmoinnin antisuunnittelumalleja
* Tahaton monimutkaisuus (accidental complexity): Väärä suunnittelu tai ongelman väärin ymmärtäminen lisää ratkaisuun yllättäviä ongelmakohtia.
* Kauaskantoiset vaikutukset (action at a distance): Muutos yhteen osaan ohjelmaa aiheuttaa ongelmia aivan toisessa, ennalta arvaamattomassa kohdassa ohjelmaa.
* Ruutitynnyri (Accumulate and fire): Asetetaan alirutiinien parametrit kokoelmassa globaalejan muuttujia.
* Sinisilmäisyys (Blind faith): Jätetään tarkistamatta (a) ohjelmointivirheen korjauksen oikeellisuus tai (b) alirutiinin antama tulos.
* Ankkuroituminen (Boat anchor): Ylläpidetään järjestelmän osaa, jolla ei ole enää mitään käyttöä.
* Kärpäsmagneetti (Bug magnet): Kappale koodia, jota ajetaan/testataan niin harvoin, että se mitä todennäköisimmin ei toimi.
* Kiertää kehää (Busy spin): Kulutetaan kellojaksoja sen odottamiseen, että jotain tapahtuisi, tavallisesti tarkistamalla usein sen sijaan että viestittäisiin asian vaatimalla tavalla.
* Välimuistikatkos (Caching failure): Unohdetaan alustaa uudelleen virhemuuttuja, vaikka virhe on jo korjattu.
* Lastikulttiohjelmointi (Cargo cult programming): Käytetään suunnittelumalleja ja metodeja ilman että ymmerrettäisiin miksi niitä tulisi käyttää.
* Tyypin ylitarkastus (Checking type instead of interface): Tarkistetaan olion tarkka tyyppi, kun riittäisi tarkistaa vain minkä rajapinnan se toteuttaa.
* Koodin hitaus (Code momentum): Toistetaan suuria määriä koodiriippuvuksia, jolloin päädytään yhä sitkeämpään riippuvuuteen ja mahdollinen suunnanmuutos koodauksessa on yhä hankalampaa ja hitaampaa toteuttaa.
* Poikkeuskoodailu (Coding by exception): Lisätään uutta koodia, joka käsittelee aina kukin erikoistapauksen, kun sellainen on havaittu.
* Virheen kätkeminen (Error hiding): Napataan virheviesti ennen kuin käyttäjä ehtii nähdä sitä ja sen jälkeen joko ei näytetä mitään tai näytetään vain merkityksetön viesti.
* Käsittely virheiden kautta (Exception handling): Käytetään kielen poikkeuskäsittelyä normaalin ohjelmalogiikan toteuttamiseen.
* Tilkkutäkki (Full Monty): Ohjelma jota koristaa epäsuotuisa kokoelma tai sekoitus liian monia antisuunnittelumalleja.
* Sisäänkoodaus (hard code): Asioita, jotka voivat riippua ajoympäristöstä tai käyttäjän valinnoista (esim. tiedostojen nimet).
* Jämähtäminen (Lava flow): Säilytetään ei-toivottua (ylimääräistä tai huonoa) koodia vain sen vuoksi, että sen poistaminen on joko liian kallista tai tuottaa ennustamattomia seurauksia.
* Silmukka-vaihde -jakso (Loop-switch sequence): Koodataan joukko jaksollisia askeleita käyttämään toistorakennetta vaihde(switch)-rakenteen yllä.
* Taikaluvut (Magic numbers): Käytetään literaaliarvoja nimettyjen vakioiden sijaan.
* Sattumakoodaus (Programming by Accident or Debugging by Accident): Ratkaistaan ohjelmointivirheet sokeasti 'korjaamalla' asioita, kuten poistamalla välilyöntejä tai järjestämällä rivejä, sen sijaan että käytettäisiin aikaa sen selvittämiseen, mikä virheen oikeasti aiheutti---kulutetaan aikaa yrittämällä korjata virheitä sokeasti.
* Spagettikoodi (Spaghetti code): Järjestelmiä joiden rakenne on tuskin ymmärrettävissä, erityisesti koska koodirakenteita käytetään väärin.
* Lasagnekoodi (Lasagna code): Järjestelmä, joka on rakennettu niin kiinteäksi kokonaisuudeksi, että sitä on mahdotonta muuttaa tuhoamatta sen toiminnallisuutta.
* Ylisäikeistys (Superthreading): Uskotaan että koodi on nopeampaa, jos säikeiden määrää lisätään.
* Tarpeeton virheenkäsittely (Useless exception handling): Syötetään ehtoja, jotta vältyttäisiin ajonaikaisilta virheiltä, mutta heitetään poikkeus, jos ehto ei täyty (`'''if''' A not null '''then''' process(A) '''else''' throw null-exception '''endif'''`)

### Menetelmällisiä antisuunnittelumalleja
* Rusinoiden poiminta pullasta (Low hanging fruit): Käsitellään helpommat asiat ensin ja sivuutetaan isommat hankalammat asiat.
* Kultainen vasara (Golden hammer): Oletetaan, että suosikkiratkaisu on yleisesti sovellettavissa.
* Leikkaa ja liimaa -ohjelmointi (cut and paste programming): Ohjelmakoodin hätäinen kopiointi ja sovitus aikaisemmasta toteutuksesta sen sijaan, että koodi suunniteltaisiin uudelleenkäytettäväksi.
* Pyörän keksiminen uudelleen (reinventing the wheel): Olemassa olevaa, toimivaa ratkaisua ei osata tai viitsitä hyödyntää.
* Neliskulmaisen pyörän uudelleenkeksiminen (Reinventing the square wheel): Luodaan huono ratkaisu, kun hyväkin olisi olemassa.
* Epätödennäköisyystekijä (Improbability factor): Oletetaan, että on epätodennäköistä, että tunnettu virhe tulee ilmi.
* Liian aikainen optimointi (Premature optimization): Optimoidaan riittämättömän tiedon varassa.
* Muutteluohjelmointi (Programming by permutation): Yritetään lähestyä ratkaisua peräkkäisillä koodinmuutoksilla, jotta nähtäisiin josko koodi toimii.
* Tuotannossa testaamiseen pohjautuva ohjelmointi (Tester Driven Development): Ohjelmointiprojekti jossa uusia vaatimuksia määritellään sitä mukaa, kun virheraportteja ilmaantuu.

### Kokoonpanon hallinnan antisuunnittelumalleja
* Hallitsemattomat riippuvuudet (Dependency hell): Ongelmia vaadittujen tuotteiden versioissa.

## Lähteet

*William Brown et al., *AntiPatterns – Refactoring Software, Architectures, and Projects in Crisis*. John Wiley & Sons. Inc., 1998.