söndag 29 mars 2009

Varför man ska följa Liskov Substitution Principle

Liskov Substitution Principle (LSP) säger följande

"What is wanted here is something like the following substitution property:
If
for each object o1 of type S there is an object o2 of type T such that for all programs P defined in terms of T, the behavior of P is unchanged when o1 is substituted for o2 then S is a subtype of T."
BarbaraLiskov, Data Abstraction and Hierarchy, SIGPLAN Notices, 23,5 (May, 1988).

Med andra ord så ska en subklass ha samma betende som sin superklassen detta kan annars leda till märkliga beteende och kan vara svårt att hitta vad som egentligen orsakar felet i ett program.

Detta fick jag och en kollega nyligen erfara när vi jobbar med en produkt som använder sig av .net remoting och en egen implementerad IServerChannelSink för att kryptera data som skickas mellan klient och server.

Vårt problem var att vi fick ett MethodNotSupportedException när vi gjorde anrop från klienten till servern. Till en början trodde vi att det berodde på att .net cachade proxyn vi använde då vi oftast fick fellen i samband vi gjorde förändringar i kontraktet. Felet kunde helt plötsligt uppstå och sedan försvinna helt utan anledning. Om man debugade så kunde det först smälla och om man körde samma metod en gång till direkt efter så fungerade det. Vi testade att först anropa metoden och sedan fånga exceptionet för att sedan göra samma anrop en gång till som för det mesta gick igenom utan något problem.

Till slut kom vi fram till att det uppstod när metoden man anropades namn och hur parametrarna man skickade in såg ut. Så tex. om vi skickade in en 8 tecken lång sträng till en metod så slutade den fungera och vi fick MethodNotSupportedException. Om vi anropade samma metod med sju eller nio tecken låg sträng så fungerade det, vi kunde också byta namn på metoden så började det fungera igen. Vi märkte också om man stängde av krypteringen så fungerade det helt felfritt vilket ledde oss till att tro att det var något med krypteringen som ställde till det.
Efter att ha undersökt hur krypteringen fungerar och kommit fram till att vi fick samma resultat på båda klienten och server sidan så vi kunde konstatera att det inte var något med krypteringen i sig. Efter ytterligare testningar så kom vi fram till att det var CryptoStream som kastade exceptionet när en del metoder och propertys anropades på den. Eftersom vi skickade in den som en Stream till ProcessMessage i System.Runtime.Remoting.BinaryServerFormatterSink så antar den att den kan använda strömen som en vanlig Stream. Vi gjorde ingen vidare efterforskning till varför det bara inträffade vid vissa tillfällen utan löste problemet med att läsa över CryptoStreamen till en MemoryStream.

Att CryptpStrem inte har samma beteende som sin superklass Stream är ett tydligt exempel på att bryta mot LSP och i detta fallet kostade swt oss säkert 20+ timmar och mycket irritation.



Bild av Derick Bailey

lördag 14 mars 2009

Första intryck av Git

Jag har bestämt mig för att se vad allt detta pratet om Git är. Git är ett versions hanterings system (VCS) så som subversion eller CVS. Men med en stor skillnad mot ett vanliga VCS är att man inte har ett centralt repository utan det är distribuerat vilket innebär att alla har ett eget repository lokalt på sin dator sedan kan man synka det med hjälp av en central server. Detta innebär att du inte behöver vara uppkopplad mot någon server för att komma åt en tidigare version av koden du jobbar med. Git hanterar inte filer som vanliga VCSer utan innehållet istället, vilket innebär att den kan följa om en metod har flyttat från en fil till en annan.

Att installera Git lokalt är busenkelt. Eftersom jag till största del är Windows användare så använde jag MSysGit för att installera.
De konfigurationer man behöver göra är sätta namn och email.

prompt>git config --global user.name "Marcus"
prompt>git config --global user.email "myMail@solidkod.nu"

För att verifiera inställningarna

prompt>git config --global --list

Om man vill ha färgkodning på outputen från Git, fungerar inte i cmd utan man behöver köra Git Bach

prompt>git config --global color.ui "auto"

För att skapa ett repository så ställer man sig på katalogen man vill ha som rot och skriver

prompt>git init

Och det är allt som behövs för att skapa ett repository =)

Så till lite grundläggande kommandon

För att lägga till en fil och commita den till repositoryt

prompt>git add myfile.txt
prompt>git commit -m "komentar"

För att få ut log från Git

prompt>git log

eller om man bara vill ha ut de sista

prompt>git log 1

Än så länge har jag bara kört Git med lokalt repository och det har varit en trevlig upplevelse.
Kommer mer om mina framsteg och upplevelser av Git i senare inlägg.

/Marcus

fredag 6 mars 2009