Coding Dojo – Az “inversion of control” szellemében

Posted by | · · · · | Szoftverfejlesztés | Nincs hozzászólás a(z) Coding Dojo – Az “inversion of control” szellemében bejegyzéshez

Az elmúlt szombaton megesett az idei év első Coding Dojo eseménye a Webstar-nál. Mint mindig, most is valami kis aprósággal szerettem volna feldobni az eseményt, és ez most az “inversion of control” elgondolás volt.

Inversion of Control

Mindennapjaink során lépten-nyomon az inversion of control-lal találkozunk, és úgy érzetem ezt nem lehet kihagyni egy coding dojo-ról sem.

 

De mi is ez az “inversion of control”? A Wikipedia-n a következőt olvashatjuk:

In software engineering, inversion of control (IoC) describes a design in which custom-written portions of a computer program receive the flow of control from a generic, reusable library. A software architecture with this design inverts control as compared to traditional procedural programming: in traditional programming, the custom code that expresses the purpose of the program calls into reusable libraries to take care of generic tasks, but with inversion of control, it is the reusable code that calls into the custom, or task-specific, code.

“Jól hangzik, de ez mit is jelent?” – fordult meg talán a fejedben. Vegyünk egy mindennapi esetet a könnyebb érhetőség kedvéért: megírjuk azt a metódust, amely akkor fut le, ha a felhasználó rákattint egy gombra, vagy megváltoztatja az egyik mező értékét. Ismerős? Ez is az inversion of control egyik megjelenési formája. GUI framework-öt használva a felhasználói interakció által létrejött eseményre iratkozhatunk fel. Egy esemény dobása és egy eseményre való feliratkozás nevén szólítva: observer design pattern. Az ODP megvalósítja az IoC-t.

Most újraolvasva a wikipedia-n szereplő definíciót, máris érthetőbb az IoC.

 

Ami szerintem tömör formában nagyon jól megragadja az IoC lényegét, az a Hollywood elv:

Don’t call us, we’ll call you.

Dependency injection

Az OOP egyik alapelve a “Single Responsibility Principle” – egy osztálynak csak egy felelőssége legyen. Azonban minden jó szándékunk ellenére mégiscsak megszeghetjük ezt az elvet, amennyiben az osztály a függőségeit példányosítja. Ekkor ugyanis az osztály már két dolgot végez: elvégzi azt, amiért létrehoztuk és maga hozza létre függőségeit.
A függőségek példányosításának egyik nagy hátránya, hogy az osztály tesztelhetőségét megnehezítheti vagy akár el is lehetetlenítheti. Gondoljunk csak bele, a unit tesztnek a lényege: egy egység tesztelése függetlenül a rendszer többi részétől. Ha az osztályunk a függőségeit maga hozza létre, akkor a teszt során akaratlanul is, de a függőségek működését is teszteljük. Tehát a tesztünk sikeressége a függőségek működésétől is függ.
A másik hátrány a szoftver karbantarthatóságában jelenik meg: egy osztály lecserélése más implementációra, vagy más konfigurációval való példányosítása azzal jár, hogy az egész kódbázison végig kell vezetni az implementációra váltást, vagy ahol példányosítjuk, ott is át kell alakítani a kódot. Egy kis módosítás az egész rendszerre kihathat.
A harmadik hátrány az újrafelhasználhatóság eliminálásában jelenik meg. Egyszerűen nincs lehetőség arra, hogy az osztályt más környezetben is felhasználjuk, nem tudjuk konfigurálni. Mondhatni kőbevésett.

 

A dependency injection-nel mindez elhárítható.

Dependency injection means giving an object its instance variables.
Really. That’s it.

– James Shore

A dependency injection azt jelenti, hogy egy osztály a függőségeit nem példányosítja, hanem megkapja (inversion of control).

 

Jogosan merül fel a következő kérdés: ha kívülről adjuk be függőségeit, akkor az nem azt jelenti, hogy egy szinttel feljebb példányosítjuk a függőségeket és magát az osztály példányt is? Ezzel csak kitoljuk a felelősséget, de ott ugyanez a probléma lép fel. Ezt hogy oldjuk meg?
Erre két megoldást tudok adni:

  • factory-kat használunk osztályok példányosítására
  • dependency injection framwork-ot használunk

Guice

Az IoC-t a coding dojo-ra a dependency injection formájában kívántam behozni, s ezért egy DI framework-öt kerestem és a Guice formájában leltem meg.
A Guice (ejtsd: “juice”) a google által fejlesztett dependency injection framework.

 

Azért döntöttem egy DI framework használata mellet, mert így teljesen függetlenedhetünk az osztályok példányosításától, azt majd a container elvégzi helyettünk, és koncentrálhatunk a lényegre: az egy felelősségi kör elvre, a jól karbantartható és tesztelhető kód írására.
Ahogy a Guice oldalán olvashatjuk is:

@Inject is the new new

Aki nem ismeri a @Inject annotációt, azoknak így foglalnám össze a használatát és működését:
A @Inject annotációval ellátott függőségeket a DI container hozza létre és állítja be az osztályunk példányosításakor (az osztályunk példányosításáért is a DI container felelős).

Conway’s game of life

A coding dojo-ra feladatként a már talán klasszikussá vált “az élet játékát” hoztam.

 

A “játék” nem igényel játékost, fejlődése a kezdeti állapotától függ.

Szabályok

A játék univerzuma egy kétdimenziós négyzetrács, ahol minden egyes cella két állapot valamelyikében lehet: élő vagy holt. Minden egyes cella a nyolc szomszédjával (vízszintesen, függőlegesen és átlósan határos cellák) kölcsönhatásban van. Minden egyes időpillanatban a következő átmenetek lehetségesek:

Alulnépesedés

Minden élő cella kevesebb, mint 2 élő szomszéddal meghal.

image02

Életben maradás

Minden élő cella 2 vagy 3 élő szomszéddal továbbél.

image01

Túlnépeseéds

Minden élő cella 3-nál több élő szomszéddal meghalt.

image04

Szaporodás

Minden halott cella pontosan 3 élő szomszéddal életre kell.

image00

 

Egy kis ráhangoló videó

Keret alkalmazás

Készítettem egy keret alkalmazást, amely a megjelenítési részét végzi el a játéknak. Ez elérhető GitHub-on. Bárki, aki ki szeretné próbálni, fork-olhatja a repot. A keret alkalmazás a megjelenítés mellet még a Guice container inicializálását is tartalmazza. Szóval a játék algoritmusának fejlesztéséhez a keret adott.

Screenshot from 2016-02-10 21:55:01

Az ábrán a keret alkalmazást láthatjuk egy “Gosper glider gun” nevű mintával, amelyből a szabályok helyes implementálása következtében érdekes viselkedést tapasztalhatunk majd.

Végszó

Egy nagyszerű, lelkes és vidám csapat gyűlt össze. Érdekes és új szemléletmódokkal ismerkedhettem meg. Köszönöm szépen!

 

Várlak benneteket a következő eseményre is!


No Comments

Leave a comment