Gladh:
>Antalet kodrader är helt ointressant eftersom man kan skriva samma kod på >1 kodrad, eller 10 rader, helt beroende på hur lättförståligt man vill att sin >kod skall vara...
Ibland blir man lite mörkrädd när man hös massa (dumma) argument.
För det första handlar det ju självklart om rader kod men det handlar ju oxå om VAD man har på varje rad. En rad skall helst inte bryta mot ex LoW (Law of Demter) dvs train chain kod. Regeln går ut på att anropa metoder m.m. genom att bara nyttja en . och inte flera.
dog.body.tail.MoveLeft() <--- BAD IDEA
behövs flera skapar man istället en beskrivande metod på ens huvd klass.
dog.WagTheTail(): <--- Mer beskrivande och tydlig...
en rad kod skall alltså bara göra typ helst en sak och då även bara en sak. På så få tecken som möjligt utan att skada självbeskrivningen, ex använd inte förkortningar utan hellre längre beskrivande namn. Kod skall vara tydlig och lättläst.
Mer rader kod ökar risken till svårläst kod och skapa problem med underhåll, där av refactorering. Och då är det bra att ha ett mål ang rader kod.
Man brukar säga, gör så liten metod du bara kan, sen gör det ännu mindre då har du bra kod.
Så antal rader är en viktig ingrediens för bra kod ihop med dess längd så klart. När man pratar antal rader pratar man inte idiotrader som är omöjliga att läsa.
Om en metod överskrider 10 rader så ökar risekn till redundant kod, just redundant kod ökar risken till redundatna fel på flera olika ställen, och mer underhåll vilket självklart medför mer jobb och skapar oftast svårläst kod m.m. Svårläst kod skapa massa onödiga kommentarer i kod (som man bör undvbika i högsta grad.)
Ta denna koden: (13 rader för att returnera en användare)
private User CreateUser(int identifier, string firstname, string lastname)
{
User user = new User();
user.Identifier = identifier;
user.FirstName = firstname;
user.LastName = lastname;
if(!string.IsNullOrEmpty(firstname) && !string.IsNullOrEmpty(lastname))
{
StringBuilder sb = new StringBuilder();
sb.Append(Lastname).Append(", ").Append(lastname);
user.DisplayName = sb.ToString();
}
return user;
}
Här finns genast en tydlig bugg. Först kollar man input parametrarna efter man satt dem i en klass. Vilket genast tillåter koden göra mer än vad den borde. ett fel bör kastas med en gång. Allt i IF-satsen är själv en medot, man utför en annan operation här vad gör man förnågot? If satsen säger inget till den som läser koden. Koden säger inte så mkt förrän man läst sig till sista raden.
Single responsability Principle och Single responsability rules är två saker att ta stor hänsyn till då man vill skapa bra kod.
Mer rätt borde vara:
public class User
{
... proppar ..
public string DisplayName
{
get { return CreateDisplayName(); }
}
private string CreateDisplayName()
{
StringBuilder displayNameBuilder = new StringBuilder();
displayNameBuilder.Append(FirstName)
displayNameBuilder.Append(", ")
displayNameBuilder.Append(Lastname);
return displayNameBuilder.ToString();
}
}
... någon annan klass (UserFactory kanske?) (5 rader för returnera användare)
private User CreateUser(int identifier, string firstname, string lastname)
{
CheckIfNotNullOrEmpty(firstName,"FirstName");
CheckIfNotNullOrEmpty(lastname,"lastName");
User user = new User(identifier,firstname,lastname);
return user;
}
... Kan ligga i en generall kontroller klass ...
public void CheckIfNotNullOrEmpty(string inParam,string paramName)
{
if(string.IsNullOrEmpty(inParam))
throw new ArgumentNullException("Input parameter " + paramName + "cannot be null or empty string")
}
Skapar man en User vill man ju gärna att dess displayname alltid ger resultat, i förra koden får man null och måste hela tiden själv skriva kod för att sätta ett displayname (reduntandkod) att själv behöva sätta den är något en utvecklare helst inte skall behöva göra där av ber masn User direkt skapa displayname då man väl behöver hämta det.
Felkontrollen borde vara tydlig så man vet vilken input som var felaktig. Att skapa en if som kollar två saker men inte säger ifrån ger ingen tydlig kod och bryter mot ex Defensive Programming och Design by Contract. I detta fall bör varje input ha sitt meddelande och sin kontroll. Då det blir redundant kod att ha flera kontroller kan man refactorera det till en metod som tar en extra input dvs inputparams namn så som i koden. Ännu snyggare vore att i C# skapa extenstion metoder som har dessa kollar i en o samma klass, eller skapa checkklasser (små util klasser) som har kontrollkod i sig.
Tack vare detta undviker jag ha samma kod på flera 1000 ställen. Om reglens för exception skulle ändras har jag tack o lov ett ställe att justera och inte 1000...
Bara här inser man nog varför få rader är bra. Du gör mer redundant kod än du vet. genom att försöka minska en metod och sen försöka göra den ännu mindre så minskar du redandansen, ökar löskopplingen och minimerar antal ställen för justering om något måste ändras.
Mvh Johan