Latest Event Updates

2012 ?

Posted on

Novoletne resolucije

Evo, I’m back.. ena od novoletnih resolucij je tudi ta, da začnem ponovno in redno pisati blog. Danes bo en kratek, sicer ravno o tematiki novoletnih resolucij.

Odločanje, odločanje…

Pred dnevi sem bral en dober blog (http://www.reallifee.com/) na to temo. Če na kratko povzamem, si v kontekstu novoletnih resolucij moramo odgovoriti na naslednja vprašanja:

1.) Česa si ne želim več početi sploh ?

2.) Za katere stvari želim porabiti manj časa ?

3.) Za katere stvari si ustvarjam nepotreben pritisk ?

4.) S katerimi stvarmi osrečujem druge, vendar samemu sebi škodujem ?

5.) Za katere stvari si več ne želim, da bi se izboljšal ?

Sam sem si že pripravil odgovore, kaj pa vi ?

 

Advertisements

Preprosto preskušanje entitete JPA 2 z Netbeans 7 in Maven

Posted on

Java EE 6 je stara dobro leto dni, NetBeans 7 Beta je zunaj že kar nekaj časa, čez dva meseca bo zunaj končna različica, Maven pa pridobiva na priljubljenosti in je dobro integriran v današnje IDE, tudi v Netbeansu. Zato sta tokrat naša cilja naslednja:

  • ustvariti nov projekt Maven s pomočjo Netbeansov, ki bo preskušal na novo ustvarjeno entiteto (JPA2) prek ogrodja JUnit
  • prikazati integracijo med Netbeansi in Mavenom

Uporabili bomo podatkovno bazo PostgreSQL, aplikacijskega strežnika pa za ta namen ne bomo potrebovali. Vse skupaj bomo zaganjali na Windows XP.

Mogoče se kdo sprašuje, kakšen je smisel uporabe JUnit-a nad poljubno entiteto, saj so v njej samo metode tipa setter/getter. Vendar, ker za tovrstno testiranje ne potrebujemo transakcij JTA (torej ne potrebujemo aplikacijskega strežnika) in ker uporabljamo nad podatkovno bazo strategijo “drop and create”, lahko nad obravnavano entiteto brez velikega vložka dela preskušamo vsaj poizvedbe JPQL.

1. Priprava okolja za Maven

Uporabili bomo Apache Maven 3.0.1. Maven je bundlan v Netbeanse, vendar bomo v našem primeru uporabili ločeno inštalacijo. Maven lahko snamete tule: http://maven.apache.org/download.html in ga odpakirate v poljuben direktorij, npr. f:/apache-maven-3.0.1. Pri sami inštalaciji je pomebno to, da nastavimo njegov bin v spremenljivko PATH. Tedaj lahko preverimo, ali je vse v redu:

Po definiciji je Maven rešitev za buildanje projektov (in še veliko več …). Pri svojem delu uporablja datoteko POM – to je datoteka XML, v kateri je opredeljen naš projekt. Projekt običajno potrebuje več t. i. artifaktov – zunanjih modulov, od katerih je odvisen. To so t. i. dependencies, ki so prav tako opredeljene v datoteki POM. Ker je tudi sam projekt nek artifakt, rečemo, da je Maven orodje za upravljanje artifaktov.

Artifakti se sprva nahajajo v oddaljenih repozitorijih in se med buildanjem projekta običajno  prenesejo v lokalni repozitorij. Zato Maven potrebuje tudi povezavo do spleta. Privzeta nastavitev za lokalni repozitorij je /Documents and Settings/User/.m2/repository. Ta je v tem trenutku še prazen.

Ker Mavena ne bomo uporabljali command line, moramo v Netbeansih nastaviti določene parametre. Znotraj Tools => Options => Miscellaneous, zavihek Maven, nastavimo pot do nameščenega Mavena in pot do lokalnega repozitorija:

2. Priprava podatkovne baze

Uporabili bomo PostgreSql, kjer bomo ustvarili novo podatkovno bazo po imenu MyAppTest. Test smo dali v ime zato, ker bomo ob zaganjanju aplikacije v tej bazi sproti brisali in ustvarjali tabele.

3. Ustvarjanje projekta

Gremo v Netbeanse in izberemo New Project, kjer potem izberemo Maven => Java Application.

Nato izpolnimo naslednje parametre:

Tako ustvarimo nov projekt  glede na archetype: maven-archetype-quickstart:1.1. Prav tako se v lokalni repozitorij naloži nekaj osnovnih potrebnih modulov (npr. maven plugin api). Sedaj smo dobili osnovno strukturo projekta:

Vidimo, da je projekt razdeljen na več delov: del, v katerem so izvorne datoteke, del v katerem so testi, del za (Test) Dependencies in del za datoteko POM, ki v tem trenutku vsebuje naslednje:

<groupId>blog.milanpevec</groupId>
 <artifactId>MyApp</artifactId>
 <version>1.0-SNAPSHOT</version>
 <packaging>jar</packaging>

 <name>MyApp</name>
 <url>http://maven.apache.org</url>

 <properties>
   <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
 </properties>

 <dependencies>
   <dependency>
     <groupId>junit</groupId>
     <artifactId>junit</artifactId>
     <version>4.8.2</version>
     <scope>test</scope>
   </dependency>
 </dependencies>

Vidimo, da je edini artifakt junit, namreč ta modul bomo potrebovali za preskušanje. Dodatno pri artifaktu popravimo različico na vrednost 4.8.2, kajti Netbeansi kot privzeto uporabljajo različico 3.

Zaradi uporabe JPA2 dodamo v datoteko še naslednje vrstice:

<build>
  <plugins>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-compiler-plugin</artifactId>
      <version>2.3.2</version>
      <inherited>true</inherited>
      <configuration>
        <source>1.6</source>
        <target>1.6</target>
      </configuration>
    </plugin>
  </plugins>
</build>

S tem povemo, naj Maven v življenjskem ciklu prevajanja (compile) uporabi plugin za prevajanje Java SE različice 1.6. V nasprotnem bi se nam kasneje pri delu z JPA2 pojavljala opozorila.

4. Izdelava entitete JPA2

Izberemo File => New => Persistance => Entity Class. Obrazec izpolnimo z naslednjimi podatki:

Nastavili smo, da se entiteta po imenu Auser ustvari znotraj paketa blog.milanpevec.entities. Ostalo smo pustili privzeto. Pomembno je to, da spodaj obkljukamo “Create Persistance Unit”, da lahko v naslednjem koraku hkrati opredelimo še PU:

Za t. i. persistance providerja izberemo EclipseLink, izberemo novo povezavo do baze (ali jo ustvarimo, če je še nimamo) in izberemo strategijo “Drop and Create”, saj hočemo, da se ob preskušanju vedno pobriše shema in se na novo ustvarijo bazni objekti.

Zaradi integracije Mavena z Netbeansi so sedaj v datoteki POM samodejno opredeljeni novi artifakti, od katerih je odvisen naš projekt:

<dependency>
 <groupId>org.eclipse.persistence</groupId>
 <artifactId>eclipselink</artifactId>
 <version>2.2.0-M4</version>
</dependency>
<dependency>
 <groupId>org.eclipse.persistence</groupId>
 <artifactId>javax.persistence</artifactId>
 <version>2.0.0</version>
</dependency>

Gre za dva artifakta, ki sta uvrščena v isto skupino (org.eclipse.persistance). Artifakt Eclipselink je definiran zaradi PU, javax.persistance pa zaradi entitete JPA2. Ker bo PU uporabljal JDBC, moramo tudi zanj dodati artifakt:

<dependency>
 <groupId>postgresql</groupId>
 <artifactId>postgresql</artifactId>
 <version>9.0-801.jdbc4</version>
</dependency>

Ker omenjenih artifaktov še nimamo v lokalnem repozitoriju, nam Netbeansi prikažejo opozorila:

Zgornje lahko rešimo na več načinov. Lahko bi sprožili build in bi nam takrat naložilo vse potrebne artifakte. Lahko pa iz kontekstnega menija našega projekta izberemo “Show and resolve problems”, “Download Dependencies”:

Vendar je pred tem treba povedati, kje v oddaljenem repozitoriju se nahaja artifakt eclipselink. Netbeansi nam v datoteko POM privzeto nastavijo naslednje:

<repositories>
 <repository>
   <url>ftp://ftp.ing.umu.se/mirror/eclipse/rt/eclipselink/maven.repo</url>
   <id>eclipselink</id>
   <layout>default</layout>
   <name>Repository for library Library[eclipselink]</name>
 </repository>
</repositories>

Toda zaradi FTP-ja lahko pride do težave. Zato zgornjo vrstico nadomestimo z naslednjim:

<url>http://www.eclipse.org/downloads/download.php?r=1&amp;nf=1&amp;file=/rt/eclipselink/maven.repo</url&gt;

Sedaj Netbeansi sami naložijo manjkajoče artifakte v lokalni repozitorij.

Da bi bilo lažje slediti, kaj se dogaja med postopkom preskušanja, dodamo v PU novo lastnost (znotraj datoteke persistance.xml). Želimo, da se nam izpisujejo vse poizvedbe nad bazo. Zato dodamo lastnost eclipselink.logging.level z vrednostjo FINE:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
 <persistence-unit name="blog.milanpevec_MyApp_PU" transaction-type="RESOURCE_LOCAL">
   <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
   <class>blog.milanpevec.entities.Auser</class>
   <properties>
     <property name="javax.persistence.jdbc.url" value="jdbc:postgresql://localhost:5432/MyAppTest"/>
     <property name="javax.persistence.jdbc.password" value="postgres"/>
     <property name="javax.persistence.jdbc.driver" value="org.postgresql.Driver"/>
     <property name="javax.persistence.jdbc.user" value="postgres"/>
     <property name="eclipselink.ddl-generation" value="drop-and-create-tables"/>
     <property name="eclipselink.logging.level" value="FINE"/>
   </properties>
 </persistence-unit>
</persistence>

Iz zgornjega je razvidno, da bomo uporabili transakcije RESOURSE_LOCAL, saj bomo preskušanje zaganjali mimo aplikacijskega strežnika.

Pozor! EclipseLink potrebuje eksplicitno določena imena entitet, s katerimi upravlja, zato moramo dodati zgoraj znotraj <class> še ime entitete. V nasprotnem primeru dobimo “JPA exception: Object: … is not a known entity type.”

5. Izdelava testa

Najprej v našo entiteto dodamo dve lastnosti: firstname in lastname ter določimo, da primarni ključ tabele določa sekvenca auser_id_auser_seq. Prav tako opredelimo t. i. named query, ki poišče vse entitete Auser v podatkovni bazi. To poizvedbo bomo kasneje tudi preskusili.

@Entity
@NamedQuery(name=Auser.findAll,query="SELECT a FROM Auser a")
public class Auser implements Serializable {

 public final static String findAll = "entities.Message.findAll";    
 private static final long serialVersionUID = 1L;

 @Id
 @GeneratedValue(generator = "ContSeq")
 @SequenceGenerator(name = "ContSeq", sequenceName = "auser_id_auser_seq", allocationSize = 1)   
 private Long id;    
 private String firstname;    
 private String lastname;
 
 public Long getId() {
   return id;
 }
 public void setId(Long id) {
   this.id = id;
 }    
 public String getFirstname() {
   return firstname;
 }
 public void setFirstname(String firstname) {
   this.firstname = firstname;
 }
 public String getLastname() {
   return lastname;
 }
 public void setLastname(String lastname) {
   this.lastname = lastname;
 }
}

Sedaj pa si poglejmo, kako bomo sestavili test za našo entiteto. Napisali bomo testno metodo (anotacija @Test), ki se zažene samodejno zaradi omenjene anotacije. Znotraj nje bomo preskusili shranjevanje entitete v podatkovno bazo in edino opredeljeno poizvedbo. Uporabili bomo fixture @Before, ki označuje metodo, ki se zažene pred vsakim testom. V njej bomo implementirali pridobivanje trenutne transakcije. Dodatno bomo uporabili fixture @BeforeClass in @AfterClass, s katerim bomo ustvarili in zaprli naš EntityManager:

public class AuserTest  {
 
 private static EntityManagerFactory emf; 
 private static EntityManager em; 
 private static EntityTransaction tx; 
 
 @BeforeClass 
 public static void initEntityManager() throws Exception { 
   emf = Persistence.createEntityManagerFactory("blog.milanpevec_MyApp_PU"); 
   em = emf.createEntityManager(); 
 } 
 
 @AfterClass 
 public static void closeEntityManager() throws SQLException { 
   em.close(); 
   emf.close(); 
 } 
 
 @Before 
 public void initTransaction() { 
   tx = em.getTransaction(); 
 } 
 
 @Test 
 public void createAuser() throws Exception { 
 
   // Creates an instance of auser
   Auser auser = new Auser(); 
   auser.setFirstname("Janez");
   auser.setLastname("Novak"); 
 
   // Persists the auser to the database 
   tx.begin();  
   em.persist(auser); 
   tx.commit(); 
   assertNotNull("ID should not be null", auser.getId()); 
 
   // Retrieves all users from the database 
   List<Auser> ausers = em.createNamedQuery(Auser.findAllAusers).getResultList(); 
   assertEquals(1, ausers.size()); 
 } 
}

Uspešno izvedeno preskušanje ima naslednji izhod:

Zgoraj smo tako pokazali, da je mogoče zelo hitro in preprosto pripraviti okolje za preskušanje entitet. Če bi kdo želel celotno kodo projekta, mi lahko piše. Do naslednjič …

Vloga managementa pri iterativnem razvoju

Posted on

Vemo, da je vsaka posamezna iteracija videti kot en mini projekt. S stališča programerja – razvoja – vsebuje vse aktivnosti RADIT (Requirements, Analysis, Design, Implementation, Test). Kaj pa s stališča managementa? Kakšna je njegova vloga pri iterativnem razvoju?

Ponavadi se razmišlja v naslednji smeri:

  • management samo zaustavlja birokracijo (oz. neke ovire), da ne pride do razvojne ekipe, ta pa dejansko (edina) naredi celotno delo;
  • management skrbi samo za budget in za spremljanje načrta dela;
  • management dejansko ni potreben;

Takšno razmišljanje ponavadi privede do neuspeha. Management mora storiti več.
Razmišljamo lahko dvoravensko. Na nižji ravni mora management poskrbeti, da bo vsaka iteracija imela:

  • jasne cilje (koliko novih funkcionalnosti bo razvitih, koliko manj bugov glede na prejšnjo iteracijo bo proizvedenih, koliko nalog iz t. i. risk list bo rešenih ipd.). Glej tudi OPOMBO 1.
  • merljive kriterije za oceno uspešnosti
  • ekipo, ki se zaveže, da bo dosegla cilje
  • definiran začetek in konec ter njena umestitev v razvoj celotnega projekta
  • začrtane dejavnosti glede na resurse
  • ocenjevanje uspešnosti ob njenem koncu

OPOMBA 1: Česar nismo omenili zgoraj (ker je samoumevno), je naslednje: osnovni cilj vsake iteracije je release – delujoča različica programske opreme. Ta je v osnovni obliki lahko samo t. i. Proof of Concept, lahko je delujoč prototip, različica beta ipd.

Zgornje bi lahko ponazorili s ciklom: Agree – Execute – Assess.

Na višji ravni pa mora management prevzeti vlogo leadershipa. Tako mora:

  • poskrbeti mora za dolgoročno osredotočanje in usmerjanje ekipe. Tu ne gre za usmerjanje znotraj posamezne iteracije, ampak za usmerjanje glede na celoten projekt. Razvoj ne sme potekati po naključni poti. Treba je vedeti, koliko resursov bo še potrebno do konca in kdaj bodo ti resursi potrebni.

To lahko ponazorimo s ciklom: Monitor – Control Direction – Focus. Velja, da se oba omenjena cikla ponavljata nenehno skozi celotni razvoj.

Zaradi opisane pomembnosti managementa lahko njegovo dejavnost dodamo med iterativne dejavnosti. Zato ne govorimo več o dejavnostih RADIT, ampak o dejavnostih MRADIT (Management, Requirements, Analysis, Design, Implementation, Test).

 

Odnos med zbiranjem funkcionalnosti in njihovim razvojem

Posted on

V kakšnem razmerju sta zbiranje funkcionalnosti (dejavnosti Requirements, Analysis) in njihov razvoj (dejavnosti Design, Implementation, Test) ? Poglejmo si štiri modele.

1.) Vse funkcionalnosti so zbrane pred začetkom razvoja.
Pri tem modelu lahko sklepamo, da bo zbranih nekaj funkcionalnosti, ki nikoli ne bodo razvite ali ne bodo razvite tako, kot si to predstavlja naročnik. Zakaj? Ker je ekipa, ki zbira funkcionalnosti, izolirana od ekipe, ki jih bo razvila – slednja ne podaja povratnega mnenja. Namreč lekcije, ki se jih naučijo pri razvoju ene iteracije, se ne upoštevajo pri zbiranju funkcionalnosti za naslednje iteracije. Ta pristop tako ustvari nerealna pričakovanja in posledično razočaranja naročnika (in tudi celotne ekipe).

Ta model delovanja ponavadi opazimo v organizacijah, kjer ekipa, ki razvija, želi uporabljati agilne metodologije, vendar te (še) niso sprejete na ravni managementa in naročnika. Pojavi se tudi v primeru, ko se razvoj outsourca ali ko management ne zaupa podanim mnenjem in odločitvam razvoja. V skrajnem primeru se lahko zgodi celo to, da je ekipa, ki zbira funkcionalnosti, nagrajena (“Ustvarili ste odlične dokumente s funkcionalnostmi.”), ekipa, ki razvija, pa kaznovana (“Zakaj ne morete razviti zadeve točno tako, kot piše v dokumentaciji?”).

2.) Nekaj funkcionalnosti je zbranih pred začetkom razvoja, ostale se zbirajo med razvojem.
Gre za izboljšavo prvega modela, kjer se množica dovolj stabilnih funkcionalnosti začne razvijati, predenj se zberejo vse funkcionalnosti. Ampak model še vedno ohranja slabost, da sta ekipa, ki zbira funkcionalnosti, in ekipa, ki jih razvija, ločeni s strani managementa (spet lahko pride do nagrajevanja enih in kaznovanja drugih).

3.) Celotna vzporednost zbiranja funkcionalnosti in razvoja.
Gre za še dodatno izboljšavo drugega modela, kjer ekipa zbira funkcionalnosti za naslednjo iteracijo, ekipa za razvoj pa jih razvija, takoj ko je zbiranje za izbrano iteracijo končano. Pri tem modelu lahko pride do težave v zvezi z izgubo fokusa, namreč ena ekipa je z mislimi že pri naslednji iteraciji, medtem ko je druga ekipa še pri prejšnji iteraciji. Ker sta ekipi zopet (delno) ločeni, ni takšnega uspeha, kot bi lahko bil. Treba je paziti tudi na to, da se razvija samo ena iteracija hkrati.

Običajno se tak pristop izbere (kot nujno zlo) v primeru, ko so resursi omejeni (ker primanjkuje razvijalcev, poteka razvoj prepočasi, ekipo za zbiranje funkcionalnosti pa želimo čim bolj uporabiti in zato začne z delom za naslednjo iteracijo).

4.) Zbiranje funkcionalnosti in razvoj sta v celoti prepletena.
Ta model je najbolj fleksibilen in najbolj ustreza iterativni in inkrementalni praksi. Ekipi nista ločeni, fokus je velik, do rezultatov se pride hitreje, manj je konfliktov, saj obe ekipi tesno sodelujeta za dosego istih ciljev ene iteracije. Ni prelaganja odgovornosti, skupaj so dogovorni za uspeh iteracije. Dejansko se končna verzija zbranih funkcionalnosti ustvari ob koncu iteracije, skupaj z releaseom (izdelano, stestirano, integrirano programsko opremo). Gre za t. i. zbiranje funkcionalnosti just-in-time. Sedaj tudi razumemo, zakaj je pomebno, da je naročnik del ekipe.

Prikazali smo pomembnost tesnega odnosa med zbiranjem funkcionalnosti in njihovim razvojem ter dodatno tudi med naročnikom. Še več, tudi management mora testno sodelovati. Kakšna je njegova vloga, pa si bomo pogledali v enem od naslednjih zapisov.

Agile or not? (here we come) – 2. del

Posted on Updated on

V prejšnjem zapisu smo ugotovili, da potrebujemo drugačen pristop k razvoju programske opreme. Rešitev smo našli v t. i. agilnih metodah razvoja. Temelj je dokument oz. manifest iz leta 2001, ki so ga sestavile nekatere največje avtoritetete na področju razvoja programske opreme (npr. Martin Fowler, Ken Schwaber idr.). Govori o štirih temeljnih vrednotah (values), ki jih bomo poskusili prenesti v slovenski jezik:

  • Posamezniki in sodelovanje so pomembnejši od procesa in orodja.

Treba je vedeti, da agilne metode (razen izjem) ne podajajo natančnega recepta, postopka izdelave programske opreme, ampak vzpostavijo samo okvir (framework), podrobnosti pa so prepuščene posameznikom. Ti se morajo sami odločiti (za vsak projekt posebej in glede na okoliščine), katere procese in orodja bodo uporabljali – ti zato niso definirani. Lahko na primer uporabljamo navadno tablo (white board), na katero rišemo (poljubne) diagrame, v drugi skrajnosti pa diagrame ustvarjamo s kakšnim od orodij UML, in sicer strogo v skladu s specifikacijo UML. Zato je izbira posameznikov in njihovo dobro sodelovanje pomembnejše od izbire orodja in natančno opredeljenega procesa.

  • Delujoča programska oprema je pomembnejša od natančne dokumentacije.

Če upoštevamo prejšnje načelo, je raven t. i. ceremonije (tj. kako natančna je specifikacija) prepuščena posameznikom. Ne pozabimo, da je primarni cilj izdelava delujoče programske opreme, ne pa izdelava natančne dokumentacije.

  • Sodelovanje z naročnikom je pomembnejše od pogajanja o pogodbi.

Ker se razvoj začne “takoj”, v pogodbo ni mogoče napisati natančne specifikacije (dejansko tudi če bi jo hoteli, to ni mogoče, kar smo prikazali v prejšnjem blogu). Zato je z naročnikom treba vzpostaviti zaupanje, ki je osnova za tesno sodelovanje. Iz prakse je slednje lahko zelo težko, še zlasti na samem začetku, saj so na našem balkanskem območju naročniki zelo nezaupljivi. Če se oceni, da zaupanja ni mogoče vzpostaviti takoj na začetku, se zopet vrnemo k prvemu načelu in uberemo malce drugačno, “mešano” pot, kjer v pogodbi vseeno dovolj podrobno opišemo funkcionalnosti, tako da damo naročniku moč morebitnega kasnejšega pogajanje glede pogodbe. Po določenem času po začetku razvoja  pa se zaupanje kljub temu vzpostavi, in sicer z dovolj veliko transparentnostjo poteka razvoja – naročnik (ali njegov proxy) tako postane del razvojne ekipe in ima (med drugim) dovolj velik vpogled v to, kako se nalaga (in ne zapravlja) njegov denar.

  • Odziv na zahteve po spremembah je pomembnejši od sledenja načrtu.

Veliki vnaprej določeni načrti delujejo samo v nadzorovanih okoljih (spremembe so tam predvidljive), kar pa konkurenčni trg gotovo ni (vse, kar je mogoče predvideti, je to, da spremembe bodo). Zato se veliko razvoja za javni sektor vseeno izdeluje po “starih načelih”, ker je okolje nadzorovano. Ampak to ne pomeni, da nimamo velikega načrta. Ta obstaja, vendar mora v njem biti dovolj prostora za spremembe, zato tudi nima smisla izgubljati preveč časa z njegovo natančno izdelavo. Kot bomo videli kasneje, se izdela natančni načrt samo za naslednjo iteracijo. Sprememba ni slaba, treba jo je sprejeti kot nekaj običajnega. Strah pred spremembo je običajno samo opomnik na to, da je programska oprema izdelana slabo in bodo zaradi sprememb nastale velike težave. S pravimi praksami kodiranja (npr. integracijskimi testi, ki jih omogoča npr. Arquillian http://www.jboss.org/arquillian) postanejo spremembe obvladljive.

Za bolj poglobljeno razlago o tem, kaj je agilnost, so avtorji manifesta sestavili tudi seznam dvanajstih načel (principles), ki si jih je vredno natančneje ogledati:http://agilemanifesto.org/principles.html

Slika 1: Prakse tradicionalnih metod v primerjavi z agilnimi (VIR: http://www.alistapart.com/articles/gettingrealaboutagiledesign/)

Sedaj ko imamo predstavo o vrednotah in načelih, si poglejmo še prakse (practices) agilnih metodologij. Poleg skupnih praks, doda vsaka posamezna metodologija (npr.: eXtreme programming, SCRUM) še svoje prakse. Poglejmo si najprej skupne prakse:

  • Iterative & incremental development

Celoten življenjski cikel je razdeljen na več iteracij, ki si sledijo. Razvoj poteka inkrementalno, v vsaki iteraciji se razvijejo dodatne funkcionalnosti. Iteracija je zaključena celota, kar pomeni, da se v njej dogajajo vse aktivnosti – tudi testiranje in predstavitev naročniku.

  • Evolutionary & adaptive development

Gre za to, da nimamo velikega načrta za celoten razvoj, ampak se načrt sproti spreminja. Natančen načrt se sestavi samo za naslednjo iteracijo. Ker vsebuje iteracija tudi predstavitev naročniku in ker je ta del razvojne ekipe, ta poda svoje povratne informacije, ki se upoštevajo pri naslednjih iteracijah. Nujen je tudi skupen pregled opravljenega dela v posamezni iteraciji s celotno ekipo, da se ugotovi, kaj je potekalo pravilno in kaj ne, da se pridobljeno znanje prilagodi razvojnemu ciklu in upošteva pri nadaljnjem razvoju.

  • Risk-driven & client-driven iterative planning

Za funkcionalnosti v naslednji iteraciji se odločimo na podlagi želja naročnika in na podlagi ocene ekipe glede na to, kako zahtevna (in posledično tvegana) je posamezna funkcionalnost.

  • Evolutionary requirements analysis

Vsaka iteracija ima na začetku t. i. requirement workshop. Število analiziranih funkcionalnosti narašča iz iteracijo v iteracijo. Tako pri prvi iteraciji ponavadi analiziramo arhitekturno pomembne funkcionalnosti, ki predstavljajo cca. 10 % skupnih funkcionalnosti. V naslednji iteraciji analiziramo nove funkcionalnosti, tako da je skupno pokritih približno 30 % funkcionalnosti. Odstotek narašča do 90 %, kar pomeni naslednje: če je razvoj dolg 10 iteracij, je 90 % funkcionalnosti obdelanih v prvih 3 do 4 iteracijah. Naslednje iteracije so namenjene kodiranju in prilagajanju.

  • Timeboxing

Gre za to, da je dolžina posamezne iteracije določena vnaprej – na končno število dni (npr. 20), ki se ne spremeni. Morebitne nove, sproti odkrite želje naročnikov, se premaknejo v naslednje iteracije.

  • Adaptive planning

Kdaj je naročniku sploh mogoče podati dovolj dobro oceno, kako dolgo bo projekt trajal? Ponavadi  je to mogoče oceniti že po prvih dveh iteracijah. Kaj pa če naročniki želijo to oceno že takoj na začetku? V takem primeru je mogoče uporabiti t. i. “two fixed-price contract”, kjer se poda ocena za prvi dve iteraciji, po njunem zaključku pa se postavi cena še za preostali del.

Podrobnosti in lastne izkušnje o posameznih praksah bodo natančneje opisane v naslednjih zapisih. Stay tuned…

Agile or not? (here we come) – 1.del

Posted on Updated on

If agile methods have a motto, it is embrace change. If agile methods have a strategic point, it is maneuverability. (Vir: Agile and Iterative Development: A Manager’s Guide)

Razvoj programske opreme je kompleksen proces, je zelo nepredvidljiv. Uspešno predvidevanje je praktično nemogoče, tveganje je ogromno. Kakšno metodologijo razvoja izbrati, katere prakse implementirati in katere vrednote upoštevati za čim večjo uspešnost projekta?

Predstavljajmo si, da smo pred začetkom razvoja projekta. Poskusimo odgovoriti na naslednja vprašanja:

  • Ali je mogoče že vnaprej natančno opredeliti specifikacije, ki se pod nobenim pogojem ne bodo spremenile?
  • Ali je mogoče že na začetku podati natančen datum konca razvoja?
  • Ali je mogoče že na začetku opredeliti, organizirati, prioritizirati vse dejavnosti celotnega razvoja?

Odgovor je jasen: ne, ni mogoče. Razlogov je več, pa jih naštejmo nekaj:

  • stranke redko natančno vedo, katere funkcionalnosti želijo;
  • stranke težko razložijo, kaj želijo;
  • ko jih vprašamo o podrobnostih, stranke ne vedo natančno, kaj bi naj funkcionalnost, ki jo želijo, počela;
  • stranke si med samim razvojem (upravičeno) premislijo glede določenih funkcionalnosti.

Nekdo bo rekel, zakaj potem skupaj s stranko ne pripravimo natančnih odgovorov na zgornja vprašanja oz. zakaj si ne vzamemo nekaj mesecev za pripravo natančnih specifikacij (t. i. waterfall principle)?

Takšno razmišljanje je zastarelo. Čas je predrag, da bi ga porabili (samo) za omenjeno dejavnost. Kot bomo videli v kasneje, je dejavnosti mogoče paralelizirati in tako bolje izkoristiti čas. Poleg tega se v močno konkurenčnem okolju funkcionalnosti sproti tako hitro spreminjajo, da se tudi želje strank med razvojem bistveno razlikujejo od tistih pred začetkom projekta. Le zakaj? Postavimo si še dodatno vprašanje:

  • Kaj je sploh uspešen razvojni projekt? Ali je to projekt, kjer se razvoj zaključi pravočasno (in brez hroščev), kjer smo razvili vse na začetku zastavljene funkcionalnosti?

Lahko se zgodi, da razvoj projekta uspešno zaključimo, vendar takoj ob koncu ugotovimo, da je projekt neuspešen. Zakaj? Zaradi poslovnega vidika, zaradi katerega se je razvoj sploh začel: zahteve trga so se spremenile in naš projekt jih več ne pokriva (npr. na trgu se je pojavila konkurenca, nova tehnologija, zakonodaja se je medtem spremenila …), ni se pravočasno prilagodil.

Zato je potreben drugačen pristop, in sicer na vseh ravneh, ne samo na ravni  razvijanja – kodiranja, ampak tudi na nivoju menedžmenta in pri odnosu do stranke. Rešitve so v iterativnih in evolucijskih metodah, katerih podmnožica so agilne metode razvoja.