måndag 7 mars 2011

Badare, skogshuggare och objektorienterade designers

Ibland kastas man tillbaka till skolbänken. Inte i bokstavlig mening, som i att gå en kurs, utan bildligen. Ibland blir man påmind om vad man faktiskt lärde sig där bland alla föreläsningar, fikapauser och tentor. Man blir påmind om hur lite man egentligen vet och hur spännande vårt område egentligen är.

Sitter fortfarande med samma avancerade problem som jag bloggade om förra gången. En avancerad urvalsprocess för att välja det bästa alternativet bland många. Jag vet nu vet vad som ska göras och hur det bör gå till men jag hade stora problem med att få lösningen dit jag ville. Jag ritade pilar och boxar, hittade på coola namn som "Manager", "RuleSet" och "Matcher". Problemet jag hade var att det inte kändes objektorienterat. På något vis luktade hela lösningen procedurell kod... Dessutom blev de tester jag skrev krångliga och allt för nyfikna.

Låt oss ta en avstickare och fundera lite över nyfikna tester. De är ett problem. Det är tester som vill veta lite för mycket om klassen som det testar. Istället för att testa inputs och outputs testar de istället hur klassen under test kommer fram till ett resultat. Tänk dig en metod som processar en fil. Den ska givet ett antal villkor ta olika beslut och då och då interagera med andra klasser. Det vi egentligen vill veta är att vår metod uppfyller sitt kontrakt, att den gör det den utger sig att göra. Men ett nyfiket test kollar istället på vilket sätt den interagerar med omvärlden och "tjuvlyssnar" på algoritmens inre logik. Visst, du kanske har snott ihop världens tajtaste algoritm, men jag kan lova dig att det finns någon där ute som kan göra det annorlunda och troligen bättre. Om denne någon fick i uppdrag att modifiera din algortim skulle de nyfikna testerna stå ivägen och bara orsaka svordomar. De skulle faila bara för att man ändrade på algoritmens struktur, fastän det förväntade beteendet var oförändrat. Varje gång vi använder mocks och inte stubs bör vi därför ställa oss frågan: "är jag för nyfiken".

Ok, det var ett sidospår. Jag satt alltså där med en lösning på gång, men med en lukt av gammal unken Pascal.

Återigen ett samtal med en kollega. Återigen en ny syn på saken, men denna gång en sanning jag har kunnat men glömt bort. Frågan han ställde var enkel och förtjänar fet stil i stor font


"Hur skulle det du försöker göra fungera om det gjordes manuellt, i verkligheten?".

En alldeles lysande fråga! Jag tänkte bort alla artificiella saker jag uppfunnit där på min kammare. Jag började förklara flödet och beskrev deltagarna i mitt scenario som personer. Dessa personer hade inga collections eller managers till sin hjälp. De hade böcker, offerter, anteckningar och andra verkliga saker. De interagerade inte med repositories eller factories. De interagerade med andra personer. En skiss dök upp. Pilar fortfarande, men nu streckgubbar och dokument. Regelböcker och arkivmappar.



Det fantastiska med det här var att jag genast fick en objektorienterad lösning. En lösning som modellerade något verkligt och som efterliknade verklig kommunikation och interaktion. Inga Managers, Coordinators eller Services. Helt plötsligt föll sig också kollaboratörernas respektive ansvarsområden och förmågor på plats.

Jag hade helt glömt att objektorientering mår bäst när den modellerar något verkligt. Den mår bäst av att vi inte hittar på massa abstraktioner och flummiga tekniska begrepp. Den mår bäst när vi använder vårt eget språk som vi skulle använda för att beskriva för vem som helst. En snabb tur till Google ger snart denna mening som förtjänar att dammas av: "Software objects are often used to model the real-world objects that you find in everyday life."[källa] Det tål att tänkas på när vi springer iväg med vårt design-pattern-influerade, tekniktörstande ego...

 Vad gäller nyfikna tester slapp jag även dem. Eftersom varje klass nu fick ett tydligt ansvar och tydliga metoder blev det enkelt att testa. Om varje klass får ett tydligt kontrakt är det enkelt att sätta förväntningar och se att de infrias av klassen. Jag tror att nyfikna tester är en indikation på att man pysslar med procedurell kod. Det funkar inget vidare. Tydligen gillar TDD objektorienterad kod bättre än Pascal.

Och så till rubriken. Vad har någon som badar eller kör motorsåg gemensamt med den som sysslar med objektorienterad design? Tja, jag gillar ju både bad och motorsågar (kanske inte i kombination...) men jag är inte den gemensamma nämnaren.

Nä, svaret är enkelt: de är alla saker vi inte bör göra ensamma.

Over and out!
[Dagens kodarmusik: Blow - Ke$ha]