Archive for September, 2009

Stockholm Agile and Integration Seminar

Idag kunde man gå på ett gratisseminarium, som handlade en del om agil utveckling och en del om DSL:er. Martin Fowler var det stora dragplåstret, och anledningen till att jag gick dit. Seminariedelen bestod av tre presentationer. Nedan följer mina reflektioner.

“Alternative Languages”, Ola Bini
Ola pratade som vanligt om att man borde använda fler programmeringsspråk, och leta efter det språk som bäst lämpar sig för problemdomänen. Han hade faktiskt en poäng med att vi edan idag använder HTML, CSS, JavaScript, Ant, Maven och kanske något skriptspråk för att köra våra vanliga projekt. Annars kan man ju tycka att det försvårar för alla om systemet är skrivet i en massa olika språk.
Som vanligt frågade han om folk visste vad turing-komplett är, och det var ungefär tre av hundra som visste. Lite mörkrädd blir man. Han bemötte också mitt vanliga argument mot Rubys dåliga prestanda med att konstatera att många av dagens språk inte behöver vara superoptimerade, eftersom de ändå kommer att exekvera
webbapplikationer, vars flaskhalsar i alla fall består av databas- och nätverks-I/O. Tyvärr sant. Tragiskt.

Jag har hört den där presentationen några gånger i några olika varianter, men idag var den helt ok, då Ola hade slipat sina argument.

“Software Design in 21th Century”, Martin Fowler
Martin Fowler höll tre minipresentationer på lite olika ämnen. Alla var bra på sitt sätt, om än inte helt strukturerade:

Varför design spelar roll
I sin första presentation försökte Martin beväpna utvecklare med argument för varför design är viktigt. Alltså varför man ska lägga extra tid på det underliggande, trots att applikationen verkar fungera och verkar vara buggfri. Argumenten var inte helt nya, men det var värt att höra dem igen.
Han använde en modell som hette Design stamina hypothesis: två kurvor som visar var kostnaden för mjukvara utan design börjar överstiga den för mjukvara med korrekt underliggande design. Så som kurvorna var ritade fanns ett område där det faktiskt var billigare att skriva mjukvara utan en bra design. Detta område var dock litet, och man kom förbi payofflinjen inom några veckor, menade Fowler.

Genom att bevara god design håller man ner cost of new feature, vilket är ett påstående grundat på ekonomisk kalkyl. Att siffersätta detta exakt blir dock svårt, eftersom man oftast bara kan estimera kostnader och vinster. För övrigt kallas kostnadsskillnaden mellan att införa ny funktionalitet i ett system med god design och ett med dålig (som man först måste förstå och massera) för teknisk skuld. Ett kärt och ofta använt begrepp, men det är trevligt att höra Fowlers definition.

Fowler kommenterade också ett auktuellt blogginlägg av Uncle Bob.

Han menade att “mess”faktiskt är teknisk skuld om man använder en mer detaljerad modell med fyra dålighetskategorier:

Prudent: Noggrannt övervägande leder till en suboptimal, men fungerande design. Man vet att man inför skuld, men accepterar det.
Irresponsible: Okunniga utvecklare, som inte har koll på designprinciper, bilbiotek eller språket inför sådan teknisk skuld.
Inadvertable: Bra arbetsmetodik och kunskap, men man missar nåt i alla fall. Händer den bäste.
Deliberate: Man skiter blankt i att göra bra.

Jag hoppas att jag lyckades återge modellen rätt…

Event sourcing
Med denna presentation ville Fowler få oss att tänka mera på denna designteknik. Event sourcing handlar om att representera data i applikationer genom ett basdata, som sedan kompletteras med förändringar av typen Command eller Event. Han föredrog den senare analogin. I praktiken handlar det att lagra deltan.

Han menade att utvecklare arbetar med denna typ av program varje dag, och syftade på revisionskontrollsystem. Varför skulle inte vanliga “business users”
få möjligheten att göra tidsresor i sitt data?

Genom event sourcing kan man alltså alltid gå tillbaka i tiden i sitt data och köra diffar på olika version. Vidare underlättas implementationen av dristribuerade system, framför allt de som skalar horisontellt, eftersom ett event kan skickas till flera mottagare, som så småningom blir synkroniserade. Som en sista fördel nämnde han “alternative realities”, d v s möjligheten att gå tillbaka i data lägga in ett extra event, som kanske grenar datat och lägga på några events senare för att på sådant sätt skapa en alternativ verklighet.

Mina egna erfarenheter av denna programmering är inte helt positiva. Inte för vi har satsat helhjärtat, men de gånger jag varit med och testat, så har det alltid blivit något strul med delta-datat och allt rasat ihop. Tekniken äter också mycket disk/databas…

Nature of software projects
Här flummade Fowler ut på riktigt, men det var också en väldig tankeväckande presentation. Essensen av presentation kan nog kokas ner till att mjukvarubranschen går i bräschen för hur det kommer att vara att arbeta i intellktuellt krävande branscher i framtiden. Dynamiska team, kollaboration över lands- och kulturgränser och mer kaos kommer att bli vanligare i framtiden. Att lära arbeta i sådana organisationer är ett bra karriärsdrag. Fowler menade ockå att man borde försöka bo i olika länder för att få vidare perspektiv och bli mer kreativ.

Det är också i gränslanden (t ex mellan olika kulturer) som det skulle hända
mest spännande saker. Outsourcing ska i detta ljus ses som möjligheten att få en idéinjektion, inte som ett sätt att kapa kostnader, för löneläget i lågkostnadsländerna är bara tillfälligt i långa loppet.

I samma presentation förklarade han också skillnaden mellan mjukvara som infrastruktur och som strategisk satsning.

Mjukvara som infrastruktur ska fokusera på tillverkningskostnad och på
att inget viktigt går sönder. Denna typ av utveckling är föga sexig.

Mjukvara som strategisk satsning bygger på att nya oprövade koncept
rullas ut snabbt på markanden och testas. Man vet inte riktigt vad man
bygger, men kostnaden är inget problem, eftersom avkastningen kommer
att betala kostnaden flera gånger om! Det är också här ett bra mjukvaruutvecklings- eller konsultföretag vill positionera sig.

“Domain Specific Languages for Functional Testing”, Vivek Prahlad
Vivek Prahlad är en av utvecklarna bakom testverktyget Twist. Verktyget tar
acceptanstester ett steg längre genom att underlätta det som
FitNesse/Concordion + Selenium gör tillsammans: man kan bygga upp en
acceptanstestsvit genom att spela in interaktion (som med Selenium), ge operationerna beskrivningar i ett naturligt språk och använda dem som byggstenar. Alltså kan man ha en byggssten för att logga in, skapa en kund i systemet och logga ut. Dessa kan sedan kombineras, men också genomgå refactoring.

Under resan som motiverade Swifts existensberättigande pratade Vivek
om svårigheterna med funktionell testning och droppade några saker jag
tyckte var intressanta. T ex kände jag inte till verktyget Frankenstein.

Jag fick också reda på att det finns ett fint namn för konstruktionen där en klass modellerar en sida i ett webbgränsnitt. Klassen tillhandahåller högnivåoperationer,
vilket gör acceptanstestning lättare. Det fina namnet för detta är Page Object. Sätter man ihop flera sådana får man ett Workflow.

Helt ok presentation. om än lite mekanisk och enkel till och från.

Summa summarum var det värt att lägga några timmar på morgonen och jobbar över.

No Comments

Set based design

Man lär sig alltid någonting nytt! Jag läser för närvarande boken Implementing Lean Software Development av Poppendieckarna. Den sammanfattar agil utveckling på typ 10 sidor och innehåller en hel del visdom. Däri har jag för första gången träffat på begreppet Set based design.

Set based design handlar om att ta fram flera alternativa lösningar till ett och samma problem och låta den bästa överleva. Det är främst en riskreduceringsstrategi som är lämplig att använda om man MÅSTE leverera ett visst datum. Då föreslås det att man t ex drar igång tre parallella spår.

Spår A: minimi som kommer att funka

Spår B: bra design som kommer att fungera snyggt och långsiktigt

Spår C: bästa möjliga design, som delvis bygger på erfarenheter från spår B. 

Vid leveransdatum väljer man alltså det mest färdiga spår, som ger bäst kvalitet, samtidigt som man är garanterad att den enklaste lösningen finns implementerad som ett skyddsnät.

Givetvis kan man diskutera ekonomin i att göra “dubbelarbete”, eller om Spår A alltid blir klart. Man inser också att man naturligt hamnar i set based design om man arbetar någorlunda agilt. Det roliga är dock att ha ett namn på något man gör och en formaliserad kunskap om det. Djupare analys lämnas till framtida inlägg.

No Comments

soapUI och TcpMon

I samma veva som jag kämpade med mitt web service-strul, dammade jag av en gammal trotjänare - soapUI. Detta verktyg har en hel del funktioner som underlättar när man arbetar med web services. Bland annat har det integrerat stöd för att generar klientstubbar m h a en massa web service-ramverk.

Dock var det främst vid debugning som det visade sig vara användbart: Man kunde enkelt peka det mot en endpoint, skicka en fråga och få se svaret, både som XML och rå HTTP payload.

Värt att nämna är att soapUI har en IDEA-plugin för enklare integration.

TcpMon går hand i hand med soapUI vid debugning av web services, och kan i detta sammanhang agera proxy, genom att intercepta trafik till web services och skriva ut såväl requesten som svaret. Mycket användbart när man inte har kontroll över den SOAP som skickas.

No Comments

Respekt för XML och web services

Detta ska bli ett riktigt blogginlägg, alltså ett inlägg där bloggaren i fråga hittar något fånigt att klaga på och gör det utan substans i sina argument. Here we go!

Här om veckan fick jag äran att konsumera en web service! Party utan like.

Web services är ju så 90-tal, men det verkar vara det bästa vi har för interoperabilitet, så det vara bara att hugga in. Axis kändes också 90-tal, men det var vad jag kände till, så valet föll naturligt. Jag skulle anropa tre olika metoder, varav en var av karaktären “Hello World”, en krävde korrekt stöd för komplexa datatyper, medan den tredje erfordrade hantering av attachments.

Som vanligt, med open source, gick det alldeles utmärkt att göra anrop ett och två. Sedan vart det väggen! Jag kunde absolut inte få Axis 1.4 att klara attachements. Testade 1.5 utan framgång, och det enda man fick var konstiga odokumenterade fel, som inte vill låta sig googlas särskilt väl. Det fina med det hela var frihetsgraderna. Axis kan generera klinetstubbar på inte mindre än tre olika sätt, plus att man kan gå direkt via egna SOAP-meddelanden (typ).

Nu är det som så att jag är säker på att attachements kan klaras av både Axis 1 och 2, och poängen med inlägget är inte att skryta med hur dålig jag är på Axis. Poängen är att berätta om något annat, nämligen att man ska vara försiktig med att skriva att man kan XML i sitt CV.

Ett tag försökta jag förkasta Axis helt och försökte mig på JAX-WS. Det gick nästan, men jag fick namnkonflikter mellan komplexa typer och element – en situation tydligen ganska vanlig om man arbetar med .Net-genererade web services. Googling gav att man skulle använda en “binding file” för att suffixera elementen och därmed lösa namnkonflikten. Jag hittade inga direkt bra exempel och började surfa XML. Under tiden hittade jag följande godbitar:

<jxb:bindings version="1.0" 
  xmlns:jxb="http://java.sun.com/xml/ns/jaxb" 
  xmlns:xs="http://www.w3.org/2001/XMLSchema" 
  xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc" 
  jxb:extensionBindingPrefixes="xjc">
    <jxb:bindings schemaLocation="po4.xsd" node="/xs:schema">
      <jxb:globalBindings>
        <xjc:superClass name="com.syh.Shape"/>
        <xjc:serializable uid="12343"/>
      </jxb:globalBindings>
    <jxb:bindings node="//xs:element[@name='Widgets']//xs:complexType//xs:choice">
      <jxb:property name="Shapes"/>
    </jxb:bindings>
   </jxb:bindings>
</jxb:bindings>

Eller den här:

...
<package name="services.datastaging">
  <jxb:javadoc>
    <![CDATA[<body>Package level documentation for generated package services.datastaging.</body>]]>
  </jxb:javadoc>
</package>
...

Jag brukar sällan skryta med okunnighet, men första blocket ovan är ren rappakalja och det andra visar att någonting som borde vara enkelt kan göras svårt. Det var den här typen av googlande som lärde mig följande läxor:

1. Jag kan inte XML

2. Jag VILL inte kunna XML

3. Jag vill träffa dem som kom på det här

4. Det bästa vi har för att skicka små textmeddelanden mellan datorer hanteras av en, för en normal person, obegriplig gegga.

Man lär så länge man lever.

1 Comment

Code review vs parprogrammering

Vilket är bäst för kunskapsöverföring? Parprogrammering eller code review?
Tanken väcktes efter dagens code review, som innehöll ovanligt många bra diskussioner.

Idag hade vi en code review på ett ganska enkelt stycke kod som ändå hade tillräckligt många guldkorn i sig för att hålla oss syssellsatta. Dessa var:

* Integrationstest av triviala DAO-klasser: Ja eller nej? Spring? Tömma databasen eller lita på rollback?
* XML-serialisering, och vem har ansvaret.
* Ingen domänmodell, och vad gör vi under tiden?
* “Objektorientering”
* Och en massa annat 

Dylika ämnen är representativa för vad vi brukar avhandla och diskutera. Med handen på hjärtat, blir diskussionerna lite väl teoretiska ibland, men det är samtidigt otroligt givande att höra 5+ erfarna utvecklare argumentera för eller emot olika lösningar. Tyvärr blir svaret sällan svart på vitt…

Så som jag väljer att se det är en code review ett överlägset verktyg för inbördes synkronisering och kunskapsöverföring av följande skäl:

1. Gruppen synkroniserar sig i avseende på triviala arbetstekniska detaljer som code conventions.
2. Kunskap om nya verktyg och lösningar bubblar upp, för någon vill alltid styla. 
3. Den vars kod blir granskad får otroligt kvalificerad feedback på det han har gjort. 
4. Guidelines för framtida best practices kan lätt uppkomma under en code review.
5. Alla inblandade lär sig att arbeta med transparens och vänjer sig vid att få sitt arbete granskat. Detta underlättar agilt arbete och kollektivt ägande av kod.
6. Man snappar alltid upp något smart trick ens kollega har implementerat.

Alternativet är parprogrammering, som innehåller alla ovanstående element, men mindre av allting. Självklart löser de som programmerar i par ett konkret problem, istället för att käbbla om teoretiska abstraktioner, men hur man än vänder och vrider på det, så tycker jag att man får mer hävstång i en code review.

Jaja… Det viktiga med inlägget var inte att trasha parprogrammering, utan att promota code reviews. De som inte håller dem regelbundet måste testa!

No Comments

Mjukstart efter semestern

Det är inte alltid lätt att skriva i en blogg som inte går ut på att trivialt sammanfatta eller kommentera någonting man har läst. Därför behöver även en blogg lite semester. Ny termin – nya möjligheter. Vi mjukstartar med en snippet jag har sparat för just ett sådant tillfälle. Har så klart ändrat lite på variabel- och metodnamnen… 

Kommentar överflödig!

public void testFindPlayerIdForSomething() {
    final Long expectedPlayer = (long) 12345;
    SomeServiceImpl someService = new SomeServiceImpl();
    someService.setSomeDao(new SomeDaoImpl() {
        public List<Long> findPlayerIdForSomething(Obfuscated ticket) {
            List<Long> results = new ArrayList<Long>();
                results.add(ticket);
                return results;
        }
    });
    Long result = someService.findPlayerIdForSomething(null).get(0);
    assertEquals(expectedPlayer, result);
}

No Comments