[alg/OO]Tot hoever methodes opsplitsen.

Pagina: 1
Acties:

  • 4of9
  • Registratie: Maart 2000
  • Laatst online: 15-04 15:52
Hallo,

Ik vroeg me af of jullie bepaalde guidelines handteren bij het maken classes en het opsplitsen van code.

ik heb bijvoorbeeld een stukje code (een methode) en vroeg me af of het zinvol is, en wanneer het zinvol is om zo'n methode nog verder op te delen in kleinere blokjes, en welke regels daar voor aan te houden zijn.

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
        private bool GetUpdateEngineStatus()
        {
            bool retval=false;
            int lastnumberinqueue=0;
            int currentnumberinqueue=0;

            lastnumberinqueue = GetAdlizardErrorQueue();
            currentnumberinqueue = GetCurrentNoAdlizardErrors();

            SqlConnection conn = new SqlConnection(Settings.GetConnectionString());
            SqlCommand cmd = new SqlCommand();
            cmd.Connection = conn;

            if(lastnumberinqueue != currentnumberinqueue)
            {
                //schrijf status naar db
                try
                {
                    cmd.CommandText = "INSERT INTO adl_queue(dat_check,no_queue) VALUES (GETDATE()," + currentnumberinqueue + ")";
                    conn.Open();
                    cmd.ExecuteNonQuery();
                }
                catch(Exception ex)
                {
                    _eventlog.WriteEntry("error description: " + ex.Message);
                }
                finally
                {
                    conn.Close();
                }

                // schrijf error want queue loopt op
                if(currentnumberinqueue > lastnumberinqueue)
                {
                    try
                    {
                        cmd.CommandText = "INSERT INTO adl_errors(dat_error,ind_engine_error,description) VALUES(GETDATE()," + DBConversions.BoolToSql(true) + "," + DBConversions.StringToSql("Current queue: " + currentnrinqueue.ToString() + " Last: " + lastnrinqueue.ToString()) + ")";
                        conn.Open();
                        cmd.ExecuteNonQuery();
                        // error dus return true
                        retval = true;
                    }
                    catch(Exception ex)
                    {
                        _eventlog.WriteEntry("error description: " + ex.Message);
                    }
                    finally
                    {
                        conn.Close();
                    }
                }
                else
                {
                    //geen error dus return false
                    retval = false;
                }
            }
            else
            {
                //last en current zijn gelijk dus geen error en return false
                retval = false;
            }
            return retval;
        }

private int GetAdlizardErrorQueue()
{
 // returns an int
} 

private int GetCurrentNoAdlizardErrors()
{
 // returns an int
}


Dus concreet: wanneer is het zinvol/handig om code nog verder uit te splitsen?

Aspirant Got Pappa Lid | De toekomst is niet meer wat het geweest is...


  • OZ-Gump
  • Registratie: November 2002
  • Laatst online: 14-05-2024

OZ-Gump

terug van weggeweest

Volgens mij slinger je hiermee een discussie aan de het midden houdt tussen smaak, gevoel en ervaring. drie dingen die iedereen denkt te hebben ;)

Even serieus. Op mijn blog heb ik al eens een post gedaan over het commentaar schrijven bij je code. De reacties die daarop kwamen waren zo stellig, dat ik er een tweede post aan gewijd heb om een en ander te nuanceren. Volgens Fowler is de keuze echter heel makkelijk: zodra een methode commentaar nodig heeft omdat het anders niet meer duidelijk is wat die methode doet, dan moet je hem opbreken.

Overigens vind ik zelf de vraag 'ga je stukken code vaker gebruiken' ook wel een goede graadmeter. Alles wat je misschien ergens anders nog een keer nodig hebt zet je sowieso in een eigen methode. Verder heb ik volgens mij nooit methodes die langer zijn dan mijn beeldscherm weer kan geven op 1280 x 1024... maar ik houd nogal van gestructureerde code.

Edit:
Heb een beetje inhoudelijk naar je code zitten kijken, en ik zou adviseren om dat heel anders op te zetten: maak een klasse die alle databasetoegang voor je doet, maak een klasse die alle eventlog toegang voor je regelt, implementeer deze singleton via private properties (of maak een factory) en gebruik dan die klasses voor de database updates of de eventlog toegang. Op die manier hoef je bij een wijziging in je database maar één klasse aan te passen in plaats van overal in je code te duiken om SQL statements aan te passen.

[ Voor 22% gewijzigd door OZ-Gump op 21-07-2005 09:21 ]

My personal website


  • djc
  • Registratie: December 2001
  • Laatst online: 08-09-2025

djc

Zo lang de code er conceptueel simpeler op wordt kan je verder opsplitsen, daarna niet meer. Komt er dus op neer dat je kan opsplitsen als je een kleinere functie nog een hele duidelijke beschrijving kan geven (maar niet elke kleine functie met een hele duidelijke beschrijving verdient zijn eigen functie).

Rustacean


  • st0p
  • Registratie: April 2004
  • Laatst online: 19-07-2024
bij mij is het heel erg wisselend en ook afhankelijk van het type functie. met name (windows)initialisatie functies kunnen erg lang worden, tot 2 schermen vol. functies waarin ik gegevens bewerk en bereken dan wel algoritmes implementeer probeer ik te beperken tot een half scherm.

  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Ik denk dat het ook al enorm helpt als je stopt met de { op nieuwe regels plaatsen. Ik snap niet dat mensen zo kunnen werken. Je krijgt zoveel niets zeggende regels op je scherm..

Verder breek ik functies op in kleinere stukken als ze me te lang worden. Maar ik heb een beetje schijt aan de refactor 'voorschriften'. Overal waar commentaar bij staat zou je op moeten splitsen naar een functie. Gevolg -> je krijgt enorm veel methodes die alleen betekenis hebben binnen een bepaalde context. Ik heb liever dat 1 methodes misschien iets minder 'inzichtelijk' zijn dan een volledige class structuur. Tenslotte roep je een class vaker aan dan dat je hem schrijft.


[edit]
Mijn methodes zijn nooit lang (zeker geen heel scherm) en alleen in uitzonderlijke gevallen heb ik classes van meer dan 1000 regels. Ik hou dus van erg kort en erg simpel... maar pas regels met beleid toe.

[ Voor 17% gewijzigd door Alarmnummer op 21-07-2005 11:02 ]


  • st0p
  • Registratie: April 2004
  • Laatst online: 19-07-2024
ik plaats dus ook { op een lege regel, ik vind het zelf het overzicht ten goede komen. maar ik denk dat dat net zo persoonlijk is als wanneer je een functie opsplitst.

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Alarmnummer schreef op donderdag 21 juli 2005 @ 09:56:
Ik denk dat het ook al enorm helpt als je stopt met de { op nieuwe regels plaatsen. Ik snap niet dat mensen zo kunnen werken. Je krijgt zoveel niets zeggende regels op je scherm..
_/-\o_ eindelijk iemand die het met me eens is ;)

Ik zou schrijf error en schrijf status apparte functies maken. Je funtie is wel erg lang nu. Op zich kan dat alleen als je veel if/else hebt, wat je ook wel hebt, maar bedenk je hoe deze functie moet heten. Geef elke functie en object een "single, well specified task". Heeft jouw functie een enkele goed gespecificeerde taak? Maw. kan je hem een duidelijke naam geven over wat hij doet? Zou ja, dan is er geen probleem. Maar imo zijn die twee try/finally blokken ideale candidaten voor apparte functies.

(die zouden idd in een appart datalayer object oid kunnen staan, zoals jonkiexl hier onder zegt)

[ Voor 51% gewijzigd door Zoijar op 21-07-2005 10:16 ]


  • pjonk
  • Registratie: November 2000
  • Laatst online: 29-12-2025
Opsplitsen doe je op basis van het doel van je functie. Je kunt zaken verder opsplitsen in methods, maar je kunt dit nog verder doortrekken door functies weer in aparte clases te plaatsen. Voorbeeld: Het doel van een DAL (Data access layer) class is communiceren met een database. Alle methods in die class moeten hetzelfde doel nastreven.

It’s nice to be important but it’s more important to be nice


Verwijderd

Alarmnummer schreef op donderdag 21 juli 2005 @ 09:56:
Verder breek ik functies op in kleinere stukken als ze me te lang worden. Maar ik heb een beetje schijt aan de refactor 'voorschriften'. Overal waar commentaar bij staat zou je op moeten splitsen naar een functie. Gevolg -> je krijgt enorm veel methodes die alleen betekenis hebben binnen een bepaalde context. Ik heb liever dat 1 methodes misschien iets minder 'inzichtelijk' zijn dan een volledige class structuur. Tenslotte roep je een class vaker aan dan dat je hem schrijft.
Lekkere non-testable code schrijf je dan zeg. Verderr schrijf je dan klaarblijkelijk routines die niet aan die klasse toebehoren.

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Verwijderd schreef op donderdag 21 juli 2005 @ 10:23:
Lekkere non-testable code schrijf je dan zeg. Verderr schrijf je dan klaarblijkelijk routines die niet aan die klasse toebehoren.
Hoezo? Private members van een class zijn implementatie details; die test je niet appart. Je test de public interface. Verder behoort alles dat samen met een class wordt geleverd tot de class; ook de functies die buiten die class vallen (denk bv. aan de operator+ of operator<< in C++, dat zijn geen class members, maar behoren wel degelijk tot die class. Vandaar ook dat ze gevonden worden in die namespace mbv koenig lookup)

  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Verwijderd schreef op donderdag 21 juli 2005 @ 10:23:
[...]
Lekkere non-testable code schrijf je dan zeg. Verderr schrijf je dan klaarblijkelijk routines die niet aan die klasse toebehoren.
Kan je dat nog onderbouwen of loop je een eind uit je nek te lullen. *Ik ga voor de laatste optie* want klaarblijkelijk weet je absoluut niet wat je zegt.
Zoijar schreef op donderdag 21 juli 2005 @ 10:30:
[...]

Hoezo? Private members van een class zijn implementatie details; die test je niet appart.
Exact. Want bij extracten van methods krijg je bijna altijd private methods die een implementatie detail zijn van die class. En private methodes vallen slecht te testen, maar met een goeie unit testcoverage tool (clover) kan je dat ook uitstekend doorfluiten.

Ik zit trouwens meestal op een testcoverage van 70%. Alleen precondities op functies (die andere developers al nooit schrijven) die test ik niet. Anders zit ik nog hoger.

[ Voor 70% gewijzigd door Alarmnummer op 21-07-2005 10:36 ]


  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Oh overigens nog voor de TS. Die try/finally database insert blokken dupliceren ook code; maw. daar moet je zeker een functie van maken. De connectie openen en een query uitvoeren zijn dubbel, plus de error handling. Als dupliceer je maar twee regels code, dan moet je er een aparte functie voor maken. Je zou bv een ExecuteQuery(string) kunnen maken, die een gegevens query uitvoert, en op errors checked. Beter is denk ik nog een datababse layer, met functies als InsertError() en AddQueue(), die dan beiden natuurlijk een private ExecuteQuery aanroepen.
Alarmnummer schreef op donderdag 21 juli 2005 @ 10:31:
Exact. Want bij extracten van methods krijg je bijna altijd private methods die een implementatie detail zijn van die class. En private methodes vallen slecht te testen, maar met een goeie unit testcoverage tool (clover) kan je dat ook uitstekend doorfluiten.
Ik heb niet veel ervaring met testen... Maar gezond verstand zei me dat het geen nut had om private methods te testen :) En ik herinner me ook wel er ooit iets over gelezen te hebben...software engineering is niet echt mijn ding... daar hebben we jou voor hier ;)

[ Voor 37% gewijzigd door Zoijar op 21-07-2005 10:40 ]


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Ik heb niet veel ervaring met testen... Maar gezond verstand zei me dat het geen nut had om private methods te testen :)
Alle regels code kunnen fouten bevatten. Zowel private als public methodes.. dus een private methode moet net zo goed getest worden als een public methode. Maar voor private methodes kijk ik gewoon als als alle branches zijn uitgevoerd.

Het is niet zo volledig doorgetest als een publieke methode, omdat je daar ook veel combinaties van argumenten erop los gaat laten om de kantelpunten en het algemene gedrag van methodes te controleren. Maar het is beter dan niets... Ik heb in mijn code nagenoeg geen expliciete testen voor private methodes trouwens.

[ Voor 7% gewijzigd door Alarmnummer op 21-07-2005 10:47 ]


Verwijderd

Alarmnummer schreef op donderdag 21 juli 2005 @ 10:31:
Kan je dat nog onderbouwen of loop je een eind uit je nek te lullen. *Ik ga voor de laatste optie* want klaarblijkelijk weet je absoluut niet wat je zegt.
Aangezien je zelf al zegt dat je er functionaliteit in gooit die er eigelijk nietin thuis hoort encapsuleer je dus ook niet deel problemen. Zodoende test je methodes enkel als geheel niet als losse taken. En als je code niet wil encapsuleren omdat ze alleen binnen een bepaalde context passen is de context fout, daar hoef ik neem ik aan weinig aan te onderbouwen.

Verwijderd

Zoijar schreef op donderdag 21 juli 2005 @ 10:30:
Hoezo? Private members van een class zijn implementatie details;
niemand had het over private methodes, dus uit welke mouw je die nu weer tovert... :)

  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Verwijderd schreef op donderdag 21 juli 2005 @ 10:46:
[...]
Aangezien je zelf al zegt dat je er functionaliteit in gooit die er eigelijk nietin thuis
Volgens mij moet jij beter leren lezen want dat gaat je geloof ik nog niet zo goed af. Als je een methode gaat extracten uit een andere methode (omdat deze te lang is) dan heeft deze nieuwe methode alleen een betekenis binnen de context van die andere methode + deze methodes zijn bijna altijd private omdat het zo`n typisch class-nivo implementatie detail is.

Dat is mijn grootste punt van kritiek op het steeds maar extracten van methodes. Dat heeft niets met een class structuur temaken want je gaat niet voor iedere methode die je gaat extracten nieuwe structuren aanmaken. Ik adviseer je eens een refactor boek door te lezen en te kijken hoever ze hier willen gaan met extracten van methodes. Zo gauw je dit hebt gedaan zul je ook mijn argument begrijpen. Daaruit moet ik dus ook meteen concluderen dat jij dit nog niet hebt gelezen en dat je gewoon ongeargumenteerd loopt te zeuren. DUs mijn advies is: lees het boek en hou je voor de rest mooi stil.

[ Voor 5% gewijzigd door Alarmnummer op 21-07-2005 10:52 ]


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Verwijderd schreef op donderdag 21 juli 2005 @ 10:50:
[...]
niemand had het over private methodes, dus uit welke mouw je die nu weer tovert... :)
Extracten van methodes levert bijna altijd een private methode op, omdat het een methode-nivo implementatie detail is. Dit methode nivo implementatie detail rimpelt nu door als een schijnbare class nivo implementatie detail (want tenslotte heeft die class een extra methode die alleen in een bepaalde (methode) context een betekenis heeft. Dit is mijn grootste punt van kritiek op het klakkeloos extracten van methods. Op het moment dat je ook geneste methodes zou hebben (zoals je in pascal had) dan zou ik veel sneller methodes gaan extracten omdat het niet snel leid tot een vervuiling van de class.

[ Voor 21% gewijzigd door Alarmnummer op 21-07-2005 10:59 ]


Verwijderd

Alarmnummer schreef op donderdag 21 juli 2005 @ 09:56:
Ik denk dat het ook al enorm helpt als je stopt met de { op nieuwe regels plaatsen. Ik snap niet dat mensen zo kunnen werken. Je krijgt zoveel niets zeggende regels op je scherm..
Ik ben het helemaal met je eens! :) Het viel mij ook al meteen op aan de code.

Het wordt hier boven al een beetje genoemd, maar een andere noodzaak om functies op te breken is testability. 1 grote monolitische functie is moeilijker te testen dan een aantal kleinere die 1 goed gedefineerd ding doen. Of je private functies ook moet testen vind ik wel moeilijk. Natuurlijk is het een implementatie detail, maar dat betekent niet dat die details niet goed moeten werken! Via reflection zou je eventueel wel deze methods buiten de classe aan kunnen roepen, maar iets kunnen betekent natuurlijk niet dat je het ook moet doen.

Een ander simpel criteria die ik altijd volg is dat ik opsplits zodra ik merk dat ik dingen dubbel aan het opschrijven ben. Dit vergt soms een beetje ervaring, omdat dingen er op het eerste ook niet altijd identiek eruit zien, maar dat eigenlijk wel zijn.

Nog een ander criteria is als 1 enkele functie te veel verschillende "paths of execution" heeft, de zogenaamde Cyclomatic Complexity geeft dat aantal aan. Het is natuurlijk persoonlijk wat te veel is, maar over het algemeen kun je stellen dat 20 mogelijke flows door een enkele functie de volgbaarheid (leesbaarheid) niet te goede komen. Als je dan stukken opbreekt naar aparte functies, dan zijn het aantal paths van call tot return van de originele functie natuurlijk niet veranderd, maar de menselijke lezer leest de functie call als 1 brok info (zeker als deze een goede naam heeft) en dit verlaagt de complexiteit dus enorm.

Voorbeeldje in pseudo code

Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
if ( cmd == bar ) {
    ..
    if  ( condition == true ) {
         var x, var y;
         ...
        while ( x < 1 && y > 4 ) {
              ...
             if ( bla == kaz ) {
                 .....
             }
        }
   }
}
else if ( cmd == foo ) {
    var z, p;
    ...
    if  ( p  > z ) {
         var x, var y;
         ...
        for ( int i=0; i<p; ++i) {
              ...
             while  ( bla == kaz ) {
                 .....
             }
        }
   }
}


v.s.

Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
if ( cmd == bar ) {
   doBar();
}
else if ( cmd == foo ) {
   doFoo();
}


void doBar() {
   ..
    if  ( condition == true ) {
         var x, var y;
         ...
        while ( x < 1 && y > 4 ) {
              ...
             if ( bla == kaz ) {
                 .....
             }
        }
   }
}


void doFoo() {
    var z, p;
    ...
    if  ( p  > z ) {
         var x, var y;
         ...
        for ( int i=0; i<p; ++i) {
              ...
             while  ( bla == kaz ) {
                 .....
             }
        }
   }
}


In het 2de voorbeeld is je cyclometic complexity 3 en kun je de structuur van het eerste fragment goed zien. In het eerste voorbeeld van de hoofd structuur weg tegen de complexitiet van elke apart stukje in de hoofdstructuur. Bij grotere functies heb je dit effect maal 10.

Verwijderd

Alarmnummer schreef op donderdag 21 juli 2005 @ 10:51:
Volgens mij moet jij beter leren lezen want dat gaat je geloof ik nog niet zo goed af.

Ik adviseer je eens een refactor boek door te lezen en te kijken hoever ze hier willen gaan met extracten van methodes.
Volgens mij moet ij wat minder arogant worden en niet als je het even niet kan volgen de kennis van de ander in twijfel trekken. Want deze conclusie geeft wel aan dat jij er weinig kaas van hebt gegeten. Ik heb het namelijk al over de volgende stap. Dat had je met als die kennis van refactoren toch al wel begrepen hoop ik.

  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Verwijderd schreef op donderdag 21 juli 2005 @ 11:01:
[...]

Volgens mij moet ij wat minder arogant worden
Jij komt met een onbeargumenteerd kritiek op mij en haalt mijn code en manier van werken onderuit. Ik zal je dan met uitzonderlijk veel plezier (met argumenten) tot aan de hakken toe afbranden.
en niet als je het even niet kan volgen de kennis van de ander in twijfel trekken.
Ik heb duidelijk een aantal argumenten gegeven over het ongecontroleerd extracten van methodes. Ik heb aan jouw kant nog geen enkel goed argument gehoord. Jij komt meteen aanzetten dat ik ontestbare code schrijf en classes met te veel verantwoordelijkheden. Ik heb duidelijk aangegeven dat als je het boekje over refactoren en extracten van methodes volgt, dat je per definitie veel context-afhankelijke methodes krijg die veel class-ruis veroorzaakt. Het wil trouwens niet zeggen dat ik uberhaubt geen methodes extract, maar ik vraag me altijd af wat de gevolgen ervan zijn. Ik heb liever een methode van 10 of 15 regels.. dan 5 methodes van 2 of 3 regels.
Want deze conclusie geeft wel aan dat jij er weinig kaas van hebt gegeten.
Jij beschuldigd mij van het schrijven van slechte code terwijl jij niet met argumenten aankomt en ik wel. Het lijkt me wel duidelijk wie er dan wel en geen kaas van heeft gegeten.
Ik heb het namelijk al over de volgende stap. Dat had je met als die kennis van refactoren toch al wel begrepen hoop ik.
Nope.. ik ben schijnbaar niet zo slim als jou.

[ Voor 23% gewijzigd door Alarmnummer op 21-07-2005 11:09 ]


  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Verwijderd schreef op donderdag 21 juli 2005 @ 11:01:
Volgens mij moet ij wat minder arogant worden en niet als je het even niet kan volgen de kennis van de ander in twijfel trekken. Want deze conclusie geeft wel aan dat jij er weinig kaas van hebt gegeten. Ik heb het namelijk al over de volgende stap. Dat had je met als die kennis van refactoren toch al wel begrepen hoop ik.
Probeer er nou maar wat van te leren, het is geen discussie om elkaar af te vallen. Het gaat erom dat we er allemaal van leren. Als jij een goed onderbouwt punt hebt, dan zal ik dat zeker lezen en overwegen. En als ik het er dan niet mee eens ben, dan zal ik precies zeggen waarom niet. En als ik het er wel mee eens ben, dan zal ik er nog een over nadenken, en wellicht het van je aannemen. Maar tot nu toe heb je geen betere onderbouwing voor een tegen-punt gegeven.
offtopic:
realiseer je ook even tegen wat voor mensen je het hebt, de regulars hier zijn iha geen thuis-prutsers, maar professionals (op mij na dan). Die eten behoorlijke hoeveelheden kaas elke dag

  • momania
  • Registratie: Mei 2000
  • Laatst online: 19:39

momania

iPhone 30! Bam!

Bij die Cyclomatic Complexity blijft het toch ook een stukje gevoel.

Sommige stukken code worden imo nml. echt niet overzichtelijker als je ze op gaat splitsen in tig methodes om daardoor per method die complexity maar laag te houden.
Ga je dan kijken naar de public interface van een class en je moet je voor de rest van de functionaliteit nog eerst door een weg van 20 methods wanen, wordt je ook niet vrolijker.
Het opsplitsen komt imo dus niet altijd ten goed van de leesbaarheid.

Op het werk laten wij nu tijdens builds ook alle code door checkstyle controleren. Daarin kan je ook op Cyclomatic Complexity, NPath Complexity, etc laten controleren. Wij houden voor Cyclomatic Complexity een max van 15 aan en voor NPath Complexity 300, maar vaak genoeg gaan we daar ook bewust overheen. Lullige vaak bij dit soort controles is dat staments als:
Java:
1
if (log.isDebugEnabled()) log.debug("bla");

Deze statements vergroten volgens de checks wel de complexity en technisch gezien klopt dat ook, maar voor je gevoel is dat dus helemaal niet. :)

Neem je whisky mee, is het te weinig... *zucht*


Verwijderd

Alarmnummer schreef op donderdag 21 juli 2005 @ 11:05:
Ik heb duidelijk een aantal argumenten gegeven over het ongecontroleerd extracten van methodes. Ik heb aan jouw kant nog geen enkel goed argument gehoord. Jij komt meteen aanzetten dat ik ontestbare code schrijf en classes met te veel verantwoordelijkheden. Ik heb duidelijk aangegeven dat als je het boekje over refactoren en extracten van methodes volgt, dat je per definitie veel context-afhankelijke methodes krijg die veel class-ruis veroorzaakt. Het wil trouwens niet zeggen dat ik uberhaubt geen methodes extract, maar ik vraag me altijd af wat de gevolgen ervan zijn. Ik heb liever een methode van 10 of 15 regels.. dan 5 methodes van 2 of 3 regels.
Je levert helemaal geen argumenten, je doet enkel aannames. Dus niet zo hoog van de toren blazen. Jij stelt immers zelf dat "schijt" hebt aan de regels waarbij je aangeeft dat je de werking belangrijker vind terwijl je weet dat er refactoring toegepast kan worden. Daarbij is mijn enige commentaar, en terecht, dat de testabilty er op achteruit gaat.

  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Verwijderd schreef op donderdag 21 juli 2005 @ 11:17:
[...]
Je levert helemaal geen argumenten, je doet enkel aannames.
Zoals? Heb je het refactor boek wel eens doorgelezen? Weet je hoe vaak ze soms doorslaan met het extracten van methodes? Ik heb duidelijke argumenten gegeven tegen het ongecontroleerd extracten van methodes.
Jij stelt immers zelf dat "schijt" hebt aan de regels waarbij je aangeeft dat je de werking belangrijker vind terwijl je weet dat er refactoring toegepast kan worden.
Lees even goed. Ik pas het toe met beleid en ik heb schijt aan het boekje volgen. Check het Refactorboek eens van Fowler en kijk hoe lang je door zou kunnen gaan met extracten van methodes. Probeer dit eens toe te passen op je eigen classes en zie dat je een enorme zooi private methodes erbij gaat krijgen. Probeer dan eens de consequenties hiervan te zien.
Daarbij is mijn enige commentaar, en terecht, dat de testabilty er op achteruit gaat.
Argumenten aub.

[ Voor 14% gewijzigd door Alarmnummer op 21-07-2005 11:24 ]


  • 4of9
  • Registratie: Maart 2000
  • Laatst online: 15-04 15:52
Een interresante discussie waarbij ik merk dat ik door mijn onervarenheid tegen dingen aanloop die zo'n beetje iedereen een keer is tegengekomen. (das mooi dat betekend dat ik in een leer process zit ;))

Ik ga deze discussie verder volgen!
Lees even goed. Ik pas het toe met beleid en ik heb schijt aan het boekje volgen. Check het Refactorboek eens van Fowler.
Grappig mijn manager heeft me die in mijn handen gestopt gisteren :)

[ Voor 32% gewijzigd door 4of9 op 21-07-2005 11:23 ]

Aspirant Got Pappa Lid | De toekomst is niet meer wat het geweest is...


  • OZ-Gump
  • Registratie: November 2002
  • Laatst online: 14-05-2024

OZ-Gump

terug van weggeweest

@markvleth
gast, chill. Er wordt hier een discussie gevoerd, maar het lijkt erop dat het dicussieren niet iedereen gegeven is. Onderbouw je mening/standpunt eens met argumenten in plaats van alleen anderen af te zeiken, die overigens wel beargumenteren en ook nog eens meer kaas op hebben dan jij misschien ooit bij elkaar zult zien...

Overigens blijf ik erbij dat deze discussie vaak uitmondt in een die over smaak gaat, en we weten allemaal dat over smaak niet valt te twisten ;)

My personal website


  • H!GHGuY
  • Registratie: December 2002
  • Niet online

H!GHGuY

Try and take over the world...

extracten van methodes doe ik meestal niet nadien, maar tijdens het schrijven zelf. de regel die ik dan meestal hanteer is: als het doel van een stuk code de functie/procedure leesbaarder maakt door ze een naam te geven en apart te zetten, dan schrijf ik een aparte functie.
Dit is de kort door de bocht versie. soms is het natuurlijk beter om commentaar te zetten als: "dit stuk doet dat"
iets waar ik probeer rekening mee te houden: elke regel code van een procedure/functie moet zo rechtstreeks mogelijk het resultaat van de procedure/functie beinvloeden. Beetje slecht geformuleerd voor: als et maar een stom tussenresultaat is, stop et dan maar in een andere functie.
andere logische factor is natuurlijk eventueel hergebruik.

off-topic:
ik vind code beter leesbaar als de {} op aparte regels staan. zeker als je bvb iets als notepad++ of andere tooltjes gebruikt die zo'n code netjes weergeeft. Ik ben dan ook voorstander van "luchtige" code: code met veel whitespace die verschillende functioneel blokjes scheidt en zo de algemene leesbaarheid/verstaanbaarheid verhoogt.
vb:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
oink* blaat(int x, meur y)
{
  blah a();
  for (int i = 0; i < x; i++)
  {
    a.doeIets(i);
    y.doeOokIets(i);
  }

  if (y > meur.maxval)
    y = meur.maxval;

  return new oink(a,y);
}

vind ik leesbaarder dan
C++:
1
2
3
4
5
6
7
8
9
oink* blaat(int x, meur y) {
  blah a();
  for (int i = 0; i < x; i++) {
    a.doeIets(i); 
    y.doeOokIets(i);
  }
  if (y > meur.maxval) y = meur.maxval;
  return new oink(a,y);
}

ASSUME makes an ASS out of U and ME


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

HIGHGuY schreef op donderdag 21 juli 2005 @ 11:27:
extracten van methodes doe ik meestal niet nadien, maar tijdens het schrijven zelf. de regel die ik dan meestal hanteer is: als het doel van een stuk code de functie/procedure leesbaarder maakt door ze een naam te geven en apart te zetten, dan schrijf ik een aparte functie.
Dit is de kort door de bocht versie. soms is het natuurlijk beter om commentaar te zetten als: "dit stuk doet dat"
Refactoren doe ik altijd. Kom ik een stuk code tegen dat ik niet in 2 seconden begrijp (ik heb het concentratie vermogen van een kip en alles wat ik niet in een paar seconden begrijp is fout) dan refactor ik dat. Dus als ik code aan het schrijven ben, of heb geschreven, dan loop ik dat wel eens na en vis er eventuele onduidelijkheden uit (dus extract zo nu en dan methods).


Zo doe ik het.

code:
1
2
3
4
5
6
7
8
9
10
11
12
oink* blaat(int x, meur y) {
  blah a();
  for (int i = 0; i < x; i++) {
    a.doeIets(i); 
    y.doeOokIets(i);
  }

  if (y > meur.maxval) 
    y = meur.maxval;
  
   return new oink(a,y);
}


Maar ik zie vaak dit:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
oink* blaat(int x, meur y) 
{
  blah a();
  for (int i = 0; i < x; i++) 
  {
    a.doeIets(i); 
    y.doeOokIets(i);
  }

  if (y > meur.maxval)
  {
    y = meur.maxval;
  }
  
   return new oink(a,y);
}


Patat met mayonaise is lekker.. Maar te veel patat of teveel mayonaise is minder lekker. Het voorbeeld dat de ts gaf zit te veel mayonaise in. Het laatste voorbeeld dat jij gaf bevat te veel patat. Mijn 1e voorbeeld bevat (imho) de juiste verhouding tussen patat en mayonaise :)

[ Voor 98% gewijzigd door Alarmnummer op 21-07-2005 11:41 ]


  • OZ-Gump
  • Registratie: November 2002
  • Laatst online: 14-05-2024

OZ-Gump

terug van weggeweest

ik vind code beter leesbaar als de {} op aparte regels staan. zeker als je bvb iets als notepad++ of andere tooltjes gebruikt die zo'n code netjes weergeeft. Ik ben dan ook voorstander van "luchtige" code: code met veel whitespace die verschillende functioneel blokjes scheidt en zo de algemene leesbaarheid/verstaanbaarheid verhoogt.
* OZ-Gump aait HIGHGuY ;) *mee eensch is*
Behalve dan dat je na die tweede if geen brackets gebruikt, ik vind dat die er ook bij single-line statements moeten staan

Als ik kijk naar de code van de TS en wat er hier allemaal geroepen wordt denk ik dat het belangrijk is om in de gaten te houden dat de architectuur van software (en de mate waarin je je daar strikt aan houdt) duidelijk zijn stempel drukt op datgene wat er in code gebeurt. Wanneer je een klassiek multi-tier model hanteert zal code zoals die van de TS niet voorkomen, aangezien je een aparte Data Access Layer hebt, en een common-laag waar zaken zoals de eventlog entries in zitten.

Stelling: te vaak wordt van te voren niet (voldoende) nagedacht over de architectuur van een software systeem, waardoor gedurende de ontwikkeling van dat systeem verschillende vragen naar boven komen welke nogal drastische invloed zouden kunnen uitoefenen op de implementatie van het systeem.

[ Voor 7% gewijzigd door OZ-Gump op 21-07-2005 11:35 ]

My personal website


  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

offtopic:
C++ ondersteunt geen local functions ;) En dus ook geen declaratie "blah a();"

Verwijderd

OZ-Gump schreef op donderdag 21 juli 2005 @ 11:26:
@markvleth
gast, chill. Er wordt hier een discussie gevoerd, maar het lijkt erop dat het dicussieren niet iedereen gegeven is. Onderbouw je mening/standpunt eens met argumenten in plaats van alleen anderen af te zeiken, die overigens wel beargumenteren en ook nog eens meer kaas op hebben dan jij misschien ooit bij elkaar zult zien...

Overigens blijf ik erbij dat deze discussie vaak uitmondt in een die over smaak gaat, en we weten allemaal dat over smaak niet valt te twisten ;)
Ik ben gewoon 'chill', het is alarmnummer die niet tegen kritiek kan, die gaat gelijk op de persoonlijke (af)zeiktoer :/ Dus inderdaad: "het lijkt erop dat het dicussieren niet iedereen gegeven is."

Wat valt er te onderbouwen :/ Zie het anders even zwart-wit: Een methode met alle functionaliteit testen betekend dat je eerst aan een hoop randvoorwaarden moet voldoen alvorens je het juiste onderdeel in je methode kunt testen. Oftewel meer functionaleit in een methode maakt testen onherroepelijk lastiger.

Edit:
Overigens, als er juist over iets te twisten valt is het wel smaak ;)

[ Voor 5% gewijzigd door Verwijderd op 21-07-2005 11:40 ]


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Verwijderd schreef op donderdag 21 juli 2005 @ 11:39:
Ik ben gewoon 'chill', het is alarmnummer die niet tegen kritiek kan, die gaat gelijk op de persoonlijke (af)zeiktoer
Zoals ik al zei.. iedereen die ongefundeerd kritiek uit die brand ik tot de hakken toe af. Verder heb ik duidelijke argumenten gegeven.
Wat valt er te onderbouwen :/ Zie het anders even zwart-wit: Een methode met alle functionaliteit testen betekend dat je eerst aan een hoop randvoorwaarden moet voldoen alvorens je het juiste onderdeel in je methode kunt testen. Oftewel meer functionaleit in een methode maakt testen onherroepelijk lastiger.
Niet helemaal. Het publieke contract van een methode waaruit onderdelen zijn ge-extract is hetzelfde is hetzelfde als de orginele versie. De unit test voor een ongerefactorde en een gerefactorde versie zal gelijk zijn (mits je de private ge-extracte methode niet expliciet gaat unittesten).
Overigens, als er juist over iets te twisten valt is het wel smaak ;)
Zo lang het gefundeerd is dan wel. Jij komt niet met argumenten aanzetten en komt meteen mij en mijn code komt afzeiken, dan zeik ik jouw af. En het is niet de eerste keer dat ik een soortgelijke ervaring met je hebt gehad. Dus vandaar dat ik ook bitterweinig van je pik. Zeker als er geen argumenten komen.

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 20:53
momania schreef op donderdag 21 juli 2005 @ 11:10:
Java:
1
if (log.isDebugEnabled()) log.debug("bla");
Ik zou die test in mijn log.debug functie willen hebben.

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


  • alienfruit
  • Registratie: Maart 2003
  • Laatst online: 11:08

alienfruit

the alien you never expected

Ach.... who cares about de grote van de methods :+
Ik heb hier ook nog wel ergens een syntax higligher component liggen waarvan een bestand (oftewel rond de 600-700 regels :P) alleen de paint methode is :+ Komt wel uit 1998 ofzo, maar toch lomp groot, en met een mooie goto/label implementatie, maar het werkt wel! Ik zou het niet eens meer durven om dat aan te raken :)

Overigens helemaal met Alarmnummer eens over de accolade-gebruik, verder blijf ik het onzin vinden om je code onleesbaar te maken (i.e. Ruby) alleen om te zorgen dat je minder hoeft te typen. Daar hebben ze producten als CodeRush e.d. voor om je minder te laten tikken :+ Ik hoef nu bijv. alleen "st" in te tikken en bang! Daar komt mijn standaard singleton code te voorschijn, heerlijk.

[ Voor 60% gewijzigd door alienfruit op 21-07-2005 12:10 ]


Verwijderd

OZ-Gump schreef op donderdag 21 juli 2005 @ 11:33:
[...]
Stelling: te vaak wordt van te voren niet (voldoende) nagedacht over de architectuur van een software systeem, waardoor gedurende de ontwikkeling van dat systeem verschillende vragen naar boven komen welke nogal drastische invloed zouden kunnen uitoefenen op de implementatie van het systeem.
/me eensch is...

Ik betrap mezelf er maar vaak genoeg op, maar dat komt misschien omdat ik nogal halsoverkop begin met programmeren. Het is zeker een competentie van mij om dit in de komende maand wat te verbeteren. Ik hou wel van overzichtelijke code redelijk wat commentaar, maar vaak verval ik in een wat simpele gedachtengang en snap na een week niet meer wat de code nou eigenlijk deed.

Verwijderd

momania schreef op donderdag 21 juli 2005 @ 11:10:
Sommige stukken code worden imo nml. echt niet overzichtelijker als je ze op gaat splitsen in tig methodes om daardoor per method die complexity maar laag te houden.
Ga je dan kijken naar de public interface van een class en je moet je voor de rest van de functionaliteit nog eerst door een weg van 20 methods wanen, wordt je ook niet vrolijker.
Inderdaad. Dat is de factor die het moeilijk maakt. Je kunt idd niet even zomaar gaan refactoren om die complexiteit eruit te halen. Er is namelijk ook nog zoiets als het closure effect. Als mensen met iets bezig zijn willen ze een taak afsluiten alvorens met de volgende te beginnen. Op het moment dat jij een sub functie moet in duiken om te kunnen begrijpen wat er op het vorige niveau gebeurde dan heb je 1 taak open voor jezelf. Toen ik nog op de universiteit zat heb ik wat bijvakken psychologie gevolgt, en daar kwam dit ook ter sprake. Ik dacht dat een mens hoogstens 5 a 6 van die (deel)taken open wil hebben staan.

Concreet; als je telkens in een functie -moet- duiken om de body te kunnen volgen, dan moet je extra goed nagaan of je opslitsing wel echt nuttig is.

In mijn idealistische voorbeeld was het wel duidelijk. De hoofdstructuur is commando's processen en om die structuur te volgen hoef je absoluut niet te weten hoe die commando's foo & bar werken. Echter, als ik wel eens door framework sourcecode heen lees dan kom ik dikwijls over die 5 a 6 functies die ik in moet duiken, zodat ik de oorspronkelijke body die ik aan het volgen was kwijt ben in mijn gedachten.

Verwijderd

Ik vind het wel grappig. Allerlei mensen die zeggen dat hun methodes nooit groter zijn dan een scherm. Op mijn notebook (1280*800) zou dat in JBuilder betekenen dat de methodes niet langer dan 33 regels zouden mogen worden.

Nu heb ik bijvoorbeeld een TCP-IP server die verschillende commando's kan afhandelen. Dus een functie geschreven
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
protected void Handler (int Commando,String Data) {
  try {
    switch (Commando) {
      case C_LOGIN : {
        DoLogin(Data);
        break;
      }
      case C_LOGOUT: {
        DoLogout(Data);
        break;
      }
      default: {
        break;
      }
  } catch (Exception e) {
    LogException(e);
  }
}

Probleem is natuurlijk dat als je nogal wat verschillende commando's wilt afhandelen je redelijk wat case statements krijgt en het nooit van zijn leven op één á twee schermen gaat passen. Dus guru's van de kleine functies. Hoe krijgen jullie het voor elkaar dat (leesbaar) op één scherm te houden? Dit zijn al 18 regels en per case krijg je er 4 bij. Als je dan weet dat je snel aan enkele tientallen verschillende commando's zit gaat zo'n switch statement nooit van zijn leven passen.

Kleine functies is best mooi maar zo nu en dan ontkom je er gewoon niet aan een functie te schrijven die wat meer regels inneemt.

  • Michali
  • Registratie: Juli 2002
  • Laatst online: 22-03 18:12
Ik probeer functies altijd gewoon in zo duidelijk mogelijk taken in te delen. De naam van de method moet vrijwel exact vertellen wat er gebeurt zodat je er gebruik van moet kunnen maken zonder je er verder druk om te maken of in de code te gaan kijken. Ook probeer ik bij te diepe nesting zaken op te splitsen in verschillende methods.

Noushka's Magnificent Dream | Unity


  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Verwijderd schreef op donderdag 21 juli 2005 @ 12:23:
Dus guru's van de kleine functies. Hoe krijgen jullie het voor elkaar dat (leesbaar) op één scherm te houden? Dit zijn al 18 regels en per case krijg je er 4 bij. Als je dan weet dat je snel aan enkele tientallen verschillende commando's zit gaat zo'n switch statement nooit van zijn leven passen.

Kleine functies is best mooi maar zo nu en dan ontkom je er gewoon niet aan een functie te schrijven die wat meer regels inneemt.
Switch statements zijn meestal een uitzondering. Maar buiten dat, je kan dit OO opzetten. Het simpelste is met een function calltable, dus je roept gewoon aan: calltable[commando](); Maar als je je dan bedenkt dat je eigenlijk al calltables in de taal zelf hebt met vtables, dan kan je er ook wel een object structuur van maken. Het state pattern helpt hierbij ook vaak.

C++:
1
2
3
4
5
6
7
8
typedef void (*HandlerPtr)(String);

// map is beter
HandlerPtr calltable[] = {dologin, dologout};

void Handler(int commando, String data) {
   calltable[commando](data); // met map check je of commando bestaat etc
}

Niet alleen is dit beter leesbaar, het is ook nog sneller, want je branched helemaal niet meer.

[ Voor 17% gewijzigd door Zoijar op 21-07-2005 12:34 ]


  • Michali
  • Registratie: Juli 2002
  • Laatst online: 22-03 18:12
Verwijderd schreef op donderdag 21 juli 2005 @ 12:23:
Ik vind het wel grappig. Allerlei mensen die zeggen dat hun methodes nooit groter zijn dan een scherm. Op mijn notebook (1280*800) zou dat in JBuilder betekenen dat de methodes niet langer dan 33 regels zouden mogen worden.

Nu heb ik bijvoorbeeld een TCP-IP server die verschillende commando's kan afhandelen. Dus een functie geschreven
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
protected void Handler (int Commando,String Data) {
  try {
    switch (Commando) {
      case C_LOGIN : {
        DoLogin(Data);
        break;
      }
      case C_LOGOUT: {
        DoLogout(Data);
        break;
      }
      default: {
        break;
      }
  } catch (Exception e) {
    LogException(e);
  }
}

Probleem is natuurlijk dat als je nogal wat verschillende commando's wilt afhandelen je redelijk wat case statements krijgt en het nooit van zijn leven op één á twee schermen gaat passen. Dus guru's van de kleine functies. Hoe krijgen jullie het voor elkaar dat (leesbaar) op één scherm te houden? Dit zijn al 18 regels en per case krijg je er 4 bij. Als je dan weet dat je snel aan enkele tientallen verschillende commando's zit gaat zo'n switch statement nooit van zijn leven passen.

Kleine functies is best mooi maar zo nu en dan ontkom je er gewoon niet aan een functie te schrijven die wat meer regels inneemt.
Die code blokken zijn sowieso al onnodig en je default: ook. Dan krijg je dit al:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
protected void Handler (int Commando,String Data) {
  try {
    switch (Commando) {
      case C_LOGIN:
        DoLogin(Data);
        break;
      case C_LOGOUT:
        DoLogout(Data);
        break;
  } catch (Exception e) {
    LogException(e);
  }
}

Als je verder echt met te veel acties komt te zitten, dan ga je idd over dat limiet heen. Maar dat is in dit geval helemaal geen probleem. De complexiteit van het stuk neemt namelijk absoluut niet toe bij het groeien van het aantal regels code. Het is slechts 1 constructie die met een paar extra opties uitgebreid wordt. Pas als je echt verschillende complexe statements en constructies gaat mixen en je dan over dat limiet gaat, dan is het imo wel een goed idee om eens te gaan op splitsen.

Noushka's Magnificent Dream | Unity


  • st0p
  • Registratie: April 2004
  • Laatst online: 19-07-2024
Verwijderd schreef op donderdag 21 juli 2005 @ 12:23:
Ik vind het wel grappig. Allerlei mensen die zeggen dat hun methodes nooit groter zijn dan een scherm. Op mijn notebook (1280*800) zou dat in JBuilder betekenen dat de methodes niet langer dan 33 regels zouden mogen worden.

Nu heb ik bijvoorbeeld een TCP-IP server die verschillende commando's kan afhandelen. Dus een functie geschreven
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
protected void Handler (int Commando,String Data) {
  try {
    switch (Commando) {
      case C_LOGIN : {
        DoLogin(Data);
        break;
      }
      case C_LOGOUT: {
        DoLogout(Data);
        break;
      }
      default: {
        break;
      }
  } catch (Exception e) {
    LogException(e);
  }
}

Probleem is natuurlijk dat als je nogal wat verschillende commando's wilt afhandelen je redelijk wat case statements krijgt en het nooit van zijn leven op één á twee schermen gaat passen. Dus guru's van de kleine functies. Hoe krijgen jullie het voor elkaar dat (leesbaar) op één scherm te houden? Dit zijn al 18 regels en per case krijg je er 4 bij. Als je dan weet dat je snel aan enkele tientallen verschillende commando's zit gaat zo'n switch statement nooit van zijn leven passen.

Kleine functies is best mooi maar zo nu en dan ontkom je er gewoon niet aan een functie te schrijven die wat meer regels inneemt.
mooi voorbeeld! hetzelfde gebeurt vaak bij window procedures, dat worden ook ellenlange switch statements. je zou daarvan gedeeltes kunnen opsplitsen maar het lijkt dat dat de leesbaarheid alleen maar ten slechte komt.

Verwijderd

st0p schreef op donderdag 21 juli 2005 @ 12:31:
mooi voorbeeld! hetzelfde gebeurt vaak bij window procedures, dat worden ook ellenlange switch statements. je zou daarvan gedeeltes kunnen opsplitsen maar het lijkt dat dat de leesbaarheid alleen maar ten slechte komt.
List.get(Commando) ;)

  • momania
  • Registratie: Mei 2000
  • Laatst online: 19:39

momania

iPhone 30! Bam!

farlane schreef op donderdag 21 juli 2005 @ 11:58:
[...]


Ik zou die test in mijn log.debug functie willen hebben.
Nee, juist niet. Het gaat er hier juist om dat je die String creation voorkomt als debug logging niet aan staat ;)

Neem je whisky mee, is het te weinig... *zucht*


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 18:07

.oisyn

Moderator Devschuur®

Demotivational Speaker

Verwijderd schreef op donderdag 21 juli 2005 @ 12:23:
Dus guru's van de kleine functies. Hoe krijgen jullie het voor elkaar dat (leesbaar) op één scherm te houden?
Hogere resolutie nemen :P
Heb op m'n werk hier een 22" op 2048x1534, dat code heerlijk. En ja, ik zet de { op een losse regel, vind ik een stuk overzichtelijker (is trouwens ook een coding guideline hier). Maar ik vind het nogal onzin om dit soort dingen aan te dragen om je functies kleiner te maken, dat maakt natuurlijk geen zak uit. Waar het om gaat is hoeveel code er daadwerkelijk in een functie staat, niet hoeveel regels die functie beslaat.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Verwijderd

momania schreef op donderdag 21 juli 2005 @ 12:42:
[...]

Nee, juist niet. Het gaat er hier juist om dat je die String creation voorkomt als debug logging niet aan staat ;)
Voor high-performance code heb je helemaal gelijk, maar soms moet je een afweging maken tussen performance en maintenance. Voor business software lijkt de huidige trend toch te zijn dat je voor maintenance (ook readibility, extendibility, etc) optimized ipv performance. Dergelijke micro optimalisaties als een String creation voorkomen, komen eigenlijk alleen nog voor bij scientific software, drivers, en hele kleine stukjes critische code in een applicatie.

Zelf stam ik nog uit het C en asm tijdperk, waar je voor elke regel code afvroeg of die niet sneller kon en je op papier de cycles bijhield voor elke loop. Een functie call opzich deed je al heel spaarzaam, omdat de overhead van alleen die call al enorm was voor die tijd.

Voor mij is het nu na enkele jaren 'modern' programmeren af & toe nog steeds vreemd om met de aanname te werken dat functie calls 'gratis' zijn en dat je best een paar lagen mag doorgaan als dat de uitbreidbaarheid ten goede komt.

Wat dat betreft zal je wel gruwelen van logging frameworks, waarbij overal in de code dingen staan als logger.log( "mymessage" ); die dan @runtime een hele hyrarchie van loggers gaan doorlopen om te kijken of de message wel of niet gelogged moet worden en waarheen.

offtopic:
[quote].oisyn schreef op donderdag 21 juli 2005 @ 12:58:
[...]
Hogere resolutie nemen :P
Heb op m'n werk hier een 22" op 2048x1534, dat code heerlijk.
[/quote]
Patser! ;) Maar ik heb lekker 3 maal 1280x1024. Netto meer pixels! :P (erg handig bij visual studio, eclipse, etc. code full screen op de middelste, tool windowetjes links, en applicatie die ik aan het maken ben rechts.

[ Voor 15% gewijzigd door Verwijderd op 21-07-2005 13:12 ]


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Verwijderd schreef op donderdag 21 juli 2005 @ 12:23:
Ik vind het wel grappig. Allerlei mensen die zeggen dat hun methodes nooit groter zijn dan een scherm.
Er is een verschil tussen nooit en bijna nooit :) Ik heb ze ook wel eens.. Maar het zijn wel zeldzaamheden.

En zoals anderen al hebben aangegeven zou ik niet zo snel met een switchcase werken als er ook andere alternatieven zijn. Maar soms heb ik ze wel :) Het moet alleen geen dagelijkse praktijk worden.

  • GrimaceODespair
  • Registratie: December 2002
  • Laatst online: 04-05 15:16

GrimaceODespair

eens een tettenman, altijd ...

.oisyn schreef op donderdag 21 juli 2005 @ 12:58:
Hogere resolutie nemen :P
Heb op m'n werk hier een 22" op 2048x1534, dat code heerlijk.
You lucky bastard
En ja, ik zet de { op een losse regel, vind ik een stuk overzichtelijker (is trouwens ook een coding guideline hier). Maar ik vind het nogal onzin om dit soort dingen aan te dragen om je functies kleiner te maken, dat maakt natuurlijk geen zak uit. Waar het om gaat is hoeveel code er daadwerkelijk in een functie staat, niet hoeveel regels die functie beslaat.
I couldn't agree more. Ik heb zelf af en toe behoorlijk veel witruimte in mijn code, en persoonlijk vind ik dat lekker :9 Maar dat zal een kwestie van gewenning zijn.

Wij onderbreken deze thread voor reclame:
http://kalders.be


Verwijderd

Alarmnummer schreef op donderdag 21 juli 2005 @ 13:06:
[...]
Er is een verschil tussen nooit en bijna nooit :) Ik heb ze ook wel eens.. Maar het zijn wel zeldzaamheden.
In het verlengde van dit topic: als je 1 abstractie niveau hoger kijkt dan functies, dan zit je op het class niveau. Als je je functies gaat refactoren en laat groeien, dan kom je ook op een gegeven moment aan het algemeen aanvaard aantal maximale regels voor een classe.

Je zit dan met het zelfde probleem als functies, je gaat delen van je class afsplitsen naar nieuwe classes, terwijl deze eigenlijk allemaal 'private' zijn voor je eerste class.

Ik zit zelf voor een project altijd te vechten met 1 class die op een gegeven moment naar de 3000 regels ging groeien. |:( Ik heb ik weet niet hoeveel afgesplitst naar losse classes, maar tijdens de verdere development ging dat ding toch weer groeien. Probeer het nu stabiel rond de 2000 regels te houden (maar dit is eigenlijk ook al te groot).

  • Michali
  • Registratie: Juli 2002
  • Laatst online: 22-03 18:12
Ik groepeer bij elkaar horende regels ook met witruimte als ik het onnodig vind om er een nieuwe functie van te maken. Ook zet ik { altijd op een losse regel. Ik vind het echt niet prettig lezen als { op dezelfde regel staat. Bovendien geeft het op een nieuwe regel veel beter aan waar het blok begint en waar het eindigd. Je offert er wel een regeltje voor op, maar dat vind ik niet zo erg.

Noushka's Magnificent Dream | Unity


  • momania
  • Registratie: Mei 2000
  • Laatst online: 19:39

momania

iPhone 30! Bam!

Ach, de { op een nieuwe regel of niet. 't Maakt mij niet zoveel uit.

Zelf heb ik ze liever op dezelfde regel en als ik in code van een ander moet werken waar dat niet is, haal je het eerst even door de formatter heen en is het helemaal naar jouw wensen. Zo kan iedereen het lekker op de manier blijven doen die hij het prettigst vind :)

Neem je whisky mee, is het te weinig... *zucht*


  • Michali
  • Registratie: Juli 2002
  • Laatst online: 22-03 18:12
momania schreef op donderdag 21 juli 2005 @ 13:19:
Ach, de { op een nieuwe regel of niet. 't Maakt mij niet zoveel uit.

Zelf heb ik ze liever op dezelfde regel en als ik in code van een ander moet werken waar dat niet is, haal je het eerst even door de formatter heen en is het helemaal naar jouw wensen. Zo kan iedereen het lekker op de manier blijven doen die hij het prettigst vind :)
Alleen krijg je dan wel problemen met diff tools als je die code weer commit in CVS of SVN oid. Of zijn die slim genoeg om daar rekening mee te houden?

Noushka's Magnificent Dream | Unity


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Verwijderd schreef op donderdag 21 juli 2005 @ 13:18:
[...]


In het verlengde van dit topic: als je 1 abstractie niveau hoger kijkt dan functies, dan zit je op het class niveau. Als je je functies gaat refactoren en laat groeien, dan kom je ook op een gegeven moment aan het algemeen aanvaard aantal maximale regels voor een classe.
Ik grijp meestal vrij snel in. Trek structuren vrij snel uit elkaar en kom bijna geen grote classes meer tegen (vroeger wel vaak). Vooral sinds ik veel met dependency injection ben gaan werken en classes minder verantwoordelijkheden ben gaan geven, zijn mijn classes minder complex geworden. Uiteraard verschuift dit wel ergens anders heen (ik heb dan weer veel sources) en zo nu en dan merk ik dat ik te ver ben gegaan. Dus dan moet ik weer een stap terug doen.

  • Orphix
  • Registratie: Februari 2000
  • Niet online
Nog een aanrader hiervoor is dit boek: Code Complete, 2nd edition. Dit boek behandelt zeer uitgebreid hoe goed te coden. Dus echt voor de programmeur geschreven en niet voor de software engineer/architect. Een van de leukste boeken binnen deze discpline!

Wat ik zelf ook vaak als mentaal hulpmiddel gebruik, en wat ook wordt uitgelegd in dat boek, is het nastreven van consistente abstractie. Dat wil zeggen dat alle statements binnen een functie ruwweg op hetzelfde abstractieniveau zitten. Heb je je ooit afgevraagd of je objecten moet doorgeven als parameters of primitieve datatypes? Bekijk naar je abstractieniveau en vaak weet je het antwoord. Hetzelfde geldt bij het opstellen van functies en classes.

Dus stel dat je een logging class hebt. Andere componenten spreken deze aan, bijvoorbeeld door het doorgeven van Exception objects. De logging class zorgt voor opmaak, filtering, etc. Echter het daadwerkelijk wegschrijven van de gevens naar een database/tekstbestand/etc, dat is een niveau lager. Immers zal je daar voornamelijk met ruwe strings werken. En dus is een opsplitsing wenselijk.

Maar het blijft een heuristiek, het antwoord zal niet altijd hetzelfde zijn. En soms zal je gefundeerd de regels kunnen overtreden.

  • alienfruit
  • Registratie: Maart 2003
  • Laatst online: 11:08

alienfruit

the alien you never expected

Voor een logging class heb ik gewoon verschillend write methodes o.a. writeInteger(), writeBytes(), writeString(), beginMethod(), endMethod() e.d. Intern in de logging-klasse worden de berichten dan via een dispatch naar de juiste plek gestuurd. Bijv. een viewer, tcpview, database, of file. Werkt prima. Heerlijk voor distributed applicaties, werkt ook leuk samen met PHP :+

[ Voor 64% gewijzigd door alienfruit op 21-07-2005 14:26 ]


  • st0p
  • Registratie: April 2004
  • Laatst online: 19-07-2024
in C# kan dat maar in C++ gaat dat niet.

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 18:07

.oisyn

Moderator Devschuur®

Demotivational Speaker

Verwijderd schreef op donderdag 21 juli 2005 @ 13:06:
offtopic:
Patser! ;) Maar ik heb lekker 3 maal 1280x1024. Netto meer pixels! :P (erg handig bij visual studio, eclipse, etc. code full screen op de middelste, tool windowetjes links, en applicatie die ik aan het maken ben rechts.
offtopic:
Had ik al verteld dat ik er een 19" naast heb staan met een resolutie van 1792x1344? Netto heb ik dus 5.554.176 pixels, en jij "slechts" 3.932.160 :7 ;). En dan tel ik de TV die ik ernaast heb staan om xbox games op te runnen niet eens mee :P.
Maar idd, multimonitor is tha bomb als developer, ik kan ook echt niet meer zonder

[ Voor 17% gewijzigd door .oisyn op 21-07-2005 15:50 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Verwijderd

st0p schreef op donderdag 21 juli 2005 @ 15:18:
in C# kan dat maar in C++ gaat dat niet.
Het was geen concrete implementatie hoor ;)

Gewoon een voobeeld dat je een switch-case ook kan oplossen met behulp van een Map/List implementatie. In C++ kun je bijvoorbeeld heerlijke effciente dingen doen als een array met function pointers...

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 18:07

.oisyn

Moderator Devschuur®

Demotivational Speaker

Michali schreef op donderdag 21 juli 2005 @ 13:22:
[...]

Alleen krijg je dan wel problemen met diff tools als je die code weer commit in CVS of SVN oid. Of zijn die slim genoeg om daar rekening mee te houden?
Over het algemeen werken die slechts op regelniveau. Best jammer idd, het zou handig zijn als je code geparsed werd zodat de differ kon zien dat een "for(int i=0;i<10;i++)" niet anders is dan een "for (int i = 0; i < 10; i++)". Aan de andere kant kom je op die manier denk ik wel in de knoei. Er is natuurlijk een reden om dat aan te passen, en het zou van de zotte zijn als je sourcecontrol applicatie doodleuk zegt dat er geen changes zijn en dus je file niet update :)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Verwijderd

.oisyn schreef op donderdag 21 juli 2005 @ 15:47:
Over het algemeen werken die slechts op regelniveau. Best jammer idd, het zou handig zijn als je code geparsed werd zodat de differ kon zien dat een "for(int i=0;i<10;i++)" niet anders is dan een "for (int i = 0; i < 10; i++)". Aan de andere kant kom je op die manier denk ik wel in de knoei. Er is natuurlijk een reden om dat aan te passen, en het zou van de zotte zijn als je sourcecontrol applicatie doodleuk zegt dat er geen changes zijn en dus je file niet update :)
Tsja ik vind eerlijk gezegd dat een IDE doormiddel van een decorator verantwoordelijk moet zijn voor het opmaken van je code. Zodoende heeft iedereen zijn/haar eigen voorkeur en heb je dat onzinnig gelul over waar dat ene haakje of puntje moet staan ook niet.

Maarja, dan heb je wel een slimmere cvs nodig ja...

  • momania
  • Registratie: Mei 2000
  • Laatst online: 19:39

momania

iPhone 30! Bam!

Verwijderd schreef op donderdag 21 juli 2005 @ 15:55:
[...]
Maarja, dan heb je wel een slimmere cvs nodig ja...
Of een uitbreiding op de cvs of plugin die je daar voor gebruikt die eerst de code format. Zodat het niet uit zou maken welke format iedereen gebruikt.

Zou wel lekker zijn idd :)

Neem je whisky mee, is het te weinig... *zucht*


  • Killemov
  • Registratie: Januari 2000
  • Laatst online: 10:28

Killemov

Ik zoek nog een mooi icooi =)

Je kunt met CVS wel alle whitespace laten ignoren.

Hey ... maar dan heb je ook wat!

Pagina: 1