[ALG]Goede Commentstyle?

Pagina: 1
Acties:
  • 133 views sinds 30-01-2008
  • Reageer

  • Nick The Heazk
  • Registratie: Maart 2004
  • Laatst online: 07-09-2024

Nick The Heazk

Zie jij er wat in?

Topicstarter
Ik had een vraagje met betrekking tot het schrijven van goede comments. Toen ik vandaag een aantal van mijn Java-scriptjes herbekeek viel het me op hoe veel ik wel gecomment had. (Hieronder een voorbeeld).

Op het eerste zicht lijkt er redelijk wat gecomment te zijn, en dat is ook zo! Het voordeel is wel dat je met alleen het lezen van de comments de hele flow - voor zover we hier van een flow kunnen spreken - begrijpt.

Op de universiteit werd hier nog niet veel aandacht aan besteed. Er wordt wel een voorbeeld gegeven van overbodig en onnodig commenten. Ik moet bekennen dat in het onderstaande voorbeeld zulke voorbeelden staan (zoals Prompt input), terwijl ik het net heel overzichtelijk vind om aan te geven waar ik user input vraag.

Mijn vraag is als volgt: Maak ik hier te vaak gebruik van comments - als beginnend programmeur ? Of heb ik net te veel onnodig gecomment en te weinig goed gecomment? Hebben jullie goede raad voor mij in verband met commenting (bedrijfsleven, projecten, school)?

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
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
import java.util.Scanner;
import java.lang.Integer;

class OZ2OG2NickVannieuwenhoven
  {
    public static void main(String[] args)
     {
      //Declaration and Initialisation  
      boolean bBreak = false,
              bEnd = false,
              bFirstTime = true,
              bSorting = true,
              bCheckAgain = false;
      int iCurrent = 0, iNext = 0;
      String sPrint = "",
             sHow = "",
             sScan = "end";
      
      Scanner scan = new Scanner(System.in);
      
      //Prompt input  
      System.out.println("Voer een rij getallen in gescheiden door een witruimte ('end' om te beeindigen):");
     
      //Looping through integers to determine if they form an ascending or descending row.
      do
        {
        //Current value has to be the previous value. If this is the first run, read the first integer. 
        iCurrent = bFirstTime ? scan.nextInt(): iNext;
            
       //Determine if the next integer exists.
        if(scan.hasNextInt())
          iNext = scan.nextInt();
        
        //End loop if the next value is not an integer.
        else
         bEnd = true;
         
         //Determine if the input is descending. Only check the first time.
         if( ((iCurrent > iNext) && bFirstTime) || ((iCurrent > iNext) && bCheckAgain) )
         { bSorting = false; bFirstTime = false; bCheckAgain = false; }
        
        //Determine if the input is ascending. Only check the first time.
        else if( ((iCurrent < iNext) && bFirstTime) || ((iCurrent < iNext) && bCheckAgain))
         { bSorting = true; bFirstTime = false; bCheckAgain = false; }
        
        //If the input is neither ascending nor descending, check on the next loop. 
        else if( ((iCurrent == iNext) && bFirstTime) || ((iCurrent == iNext) && bCheckAgain))
          { System.out.println("equal"); bFirstTime = false; bCheckAgain = true;  }
        
         //If the input is ought to be descending but has an element that is greater than the previous, break the loop.
         else if(!bSorting && (iCurrent < iNext) )
        bBreak = true;
        
        //If the input is ought to be ascending but has an element that is smaller than the previous, break the loop. 
        else if(bSorting && (iCurrent > iNext) )
        bBreak = true;
        } 
       //Loop until the end is reached, or if the input is neither ascending nor descending.
       while(!bBreak && !bEnd);
      
      //Determine how the order of elements was. (Determined in the first loop).  
      if(!bCheckAgain)  
        sHow = bSorting ? "stijgend": "dalend";
      else 
        sHow = "constant";
      
      //Determine if the elements were ascending, descending, constant or not ordered.
      sPrint = bBreak ? "Deze rij is niet stijgend of dalend": "Deze rij is " + sHow;
      
      //Print outcome 
      System.out.println(sPrint);
     }
  }

Performance is a residue of good design.


  • NMe
  • Registratie: Februari 2004
  • Laatst online: 15-04 22:07

NMe

Quia Ego Sic Dico.

Het commentaar op de regels 21 en 70 vind ik totaal overbodig. Je code maakt immers duidelijk genoeg wat je daar doet. In plaats van sPrint had je voor dat laatste misschien beter sResult als naam kunnen kiezen, dan had je helemaal een duidelijke naamgeving gehad.

Wat ik verder mis aan je commentaar is eigenlijk een globale omschrijving van je functie. JavaDoc doet dat mooi:
Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/**
 * Returns an Image object that can then be painted on the screen. 
 * The url argument must specify an absolute {@link URL}. The name
 * argument is a specifier that is relative to the url argument. 
 * <p>
 * This method always returns immediately, whether or not the 
 * image exists. When this applet attempts to draw the image on
 * the screen, the data will be loaded. The graphics primitives 
 * that draw the image will incrementally paint on the screen. 
 *
 * @param  url  an absolute URL giving the base location of the image
 * @param  name the location of the image, relative to the url argument
 * @return      the image at the specified URL
 * @see         Image
 */
 public Image getImage(URL url, String name) {
    try {
        return getImage(new URL(url, name));
    } catch (MalformedURLException e) {
        return null;
    }
 }
Dergelijke informatie is best wel belangrijk voor je classes en je methods. Bovendien kun je, als je dit soort commentaar gebruikt, commentaar zoals op regel 24 in je code weglaten, omdat je dat in je functie-uitleg kan opnemen. :)

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 25-04 21:17

curry684

left part of the evil twins

Je commentaar schiet z'n doel voorbij. Commentaar is bedoeld zodat een getrainde programmeur ipv de code het commentaar kan lezen en daarmee tijdswinst behaald om de werking te kunnen begrijpen. Jij schrijf per regel code een complete volzin die langer is dan de code zelf. Probeer 1 regel commentaar te gebruiken per "functioneel blok" ipv per iedere statement, als ik de afzonderlijke statements uitgelegd wil zien lees ik ze wel. Ik wil als ik jouw functie moet begrijpen het overzicht kunnen zien. En pas vervolgens in je commentaar 'steno' toe. Grammaticaal perfect volzinnen zijn BS, het moet net voldoende zijn om het punt duidelijk te krijgen :)

Heel concreet je laatste paar regels, zijn nu zo:
Java:
1
2
3
4
5
6
7
8
9
10
11
     //Determine how the order of elements was. (Determined in the first loop).  
      if(!bCheckAgain)  
        sHow = bSorting ? "stijgend": "dalend";
      else 
        sHow = "constant";
      
      //Determine if the elements were ascending, descending, constant or not ordered.
      sPrint = bBreak ? "Deze rij is niet stijgend of dalend": "Deze rij is " + sHow;
      
      //Print outcome 
      System.out.println(sPrint); 

Wordt dat nu echt moeilijker te snappen als je het zo doet?
Java:
1
2
3
4
5
6
      // Construct and print result string
      if(!bCheckAgain)  
        sHow = bSorting ? "stijgend": "dalend";
      else 
        sHow = "constant";
      System.out.println(bBreak ? "Deze rij is niet stijgend of dalend": "Deze rij is " + sHow); 

Scheelt je opvolger stapels tijd hoor 8)7

[ Voor 41% gewijzigd door curry684 op 21-10-2005 00:25 ]

Professionele website nodig?


  • Nick The Heazk
  • Registratie: Maart 2004
  • Laatst online: 07-09-2024

Nick The Heazk

Zie jij er wat in?

Topicstarter
Bovendien kun je, als je dit soort commentaar gebruikt, commentaar zoals op regel 24 in je code weglaten, omdat je dat in je functie-uitleg kan opnemen
Ik merk nu ook net dat regel 24 het hele script beschrijft. Dat had inderdaad veel beter gestaaan in een klasse beschrijving.

Over Javadoc hebben wij nog niets geleerd. Ik weet dat zoiets bestaat, en dat /** */ aangeeft dat het om JavaDoc code gaat. Ik ben momenteel Java Software Solutions aan het lezen (aangeraden lectuur voor cursus Beginselen van Programmeren) en ik heb gezien dat het daarin wordt vermeld, maar zo ver zit ik nog niet ;). In een ander boek (Object georiënteerd programmeren met Java) wordt hier dieper op ingegaan heb ik willen zien (Enkel nog maar door het boek heen gebladerd, is namelijk van het tweede semester).

Duidelijk een belangrijk concept dus :).

Edit:
Scheelt je opvolger stapels tijd hoor 8)7
Niet vergeten dat de opvolgers de komende jaren proffen en assistenten zijn :D. Ik zie je punt, en inderdaad dat is heel wat korter. Dan zou ik toch ook de andere volzinninen moeten herschrijven tot iets beknopter - want inderdaad er is meer comment dan code - niet?

[ Voor 17% gewijzigd door Nick The Heazk op 21-10-2005 00:35 ]

Performance is a residue of good design.


  • NMe
  • Registratie: Februari 2004
  • Laatst online: 15-04 22:07

NMe

Quia Ego Sic Dico.

Oh, ik heb zelf ook nog nooit met JavaDoc gewerkt, zelfs nooit serieus met Java. Maar ik gebruik wel de commentstyle die JavaDoc toepast, aangezien dat gewoon vrij duidelijk is. :)

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 25-04 21:17

curry684

left part of the evil twins

Nick The Heazk schreef op vrijdag 21 oktober 2005 @ 00:28:
[...]

Ik merk nu ook net dat regel 24 het hele script programma beschrijft.
:X
Ik zie je punt, en inderdaad dat is heel wat korter. Dan zou ik toch ook de andere volzinninen moeten herschrijven tot iets beknopter - want inderdaad er is meer comment dan code - niet?
Laat ik het erop houden dat je geen Employee of the Month gaat worden als je zo je code schrijft in mijn team ;) Comment is bedoeld als samenvatting voor het snelle overzicht, en om de functioneel scheidbare onderdelen van je code te markeren met een zo kort mogelijke samenvatting die nog wel het hele proces beschrijft. Als ik de itty gritty details wil weten wat je feitelijk print lees ik de code wel ;) Dus ja, als je meer comments dan code hebt heb je oftewel een verdomd complexe functie (dan is het ook voluit terecht) of je hebt zitten prutz0ren en had schrijver moeten worden :P

Professionele website nodig?


  • prototype
  • Registratie: Juni 2001
  • Niet online

prototype

Cheer Bear

Het meeste is al gezegd, maar toch wil ik nog een duitje in het zakje doen. Wat mij opvalt is dat jij bijna overal expressies gebruikt van de vorm: (A && B || A && C). Dit is natuurlijk vrij redudant aangezien A iig altijd aan voldaan moet worden om de expressie true te evalueren, en met logica algebra (in het bijzonder communitiviteit wet) makkelijk te herschrijven naar: (A && (B || C)).

[ Voor 4% gewijzigd door prototype op 21-10-2005 03:57 ]


  • Nick The Heazk
  • Registratie: Maart 2004
  • Laatst online: 07-09-2024

Nick The Heazk

Zie jij er wat in?

Topicstarter
Dat werkt in Java? Ik had het nogthans eens geprobeert maar duidelijk niet goed dus ;). Dus je beweert dat ik het als volgt kan schrijven;
Java:
1
((iCurrent == iNext) && (bFirstTime || bCheckAgain)


Logischerwijze natuurlijk wel. Zal het thuis meteen even testen. Ik zal dan ook de commenting herschrijven met alle tips die hier werden gegeven in de hoop dat het dan wat beter is :*)
[..] :X
Als we de code die ik hier neerplantte al een programma gaan noemen :p. Het bestaat maar uit een klasse en het is geschreven alsof het een script is.

[ Voor 19% gewijzigd door Nick The Heazk op 21-10-2005 08:40 ]

Performance is a residue of good design.


  • Eelke Spaak
  • Registratie: Juni 2001
  • Laatst online: 25-04 12:33

Eelke Spaak

- Vlad -

Wat ik belangrijker vind dan duidelijk commentaar, is heldere naamgeving voor klassen en methoden. Wanneer dit wordt gehanteerd is veel commentaar direct overbodig. Commentaar dat de code sneller te begrijpen maakt moet je natuurlijk altijd toevoegen, maar dat kan tot een minimum beperkt worden als de code op zich al helder is.

Om even een voorbeeldje te noemen van hoe ik het niet zou doen:

Java:
1
class OZ2OG2NickVannieuwenhoven


Waarom zul je inmiddels wel begrijpen ;) .

TheStreme - Share anything with anyone


  • prototype
  • Registratie: Juni 2001
  • Niet online

prototype

Cheer Bear

Nick The Heazk schreef op vrijdag 21 oktober 2005 @ 08:38:
Dat werkt in Java? Ik had het nogthans eens geprobeert maar duidelijk niet goed dus ;). Dus je beweert dat ik het als volgt kan schrijven;
Java:
1
((iCurrent == iNext) && (bFirstTime || bCheckAgain) )
Dat werkt ja ;) Een shortcuircit and (&&) controlleert of iig eerst de linker operand true is, en alleen als dat het geval is wordt ook nog de rechteroperand ge-evalueerd. En de rechteroperand bestaat in dit geval weer uit een shortcuircuit or, waarbij als de linker operand al true is, de rechteroperand niet meer ge-evalueerd wordt, omdat de subexpressie al true is. Teken maar even een waarheidstabelletje uit en je ziet dat het klopt :)

  • JeroenTheStig
  • Registratie: Mei 2000
  • Laatst online: 14:18
Nick The Heazk schreef op vrijdag 21 oktober 2005 @ 08:38:

[...]

Als we de code die ik hier neerplantte al een programma gaan noemen :p. Het bestaat maar uit een klasse en het is geschreven alsof het een script is.
Noem het dan java-code in plaats van java-script, daar schop je namelijk een hoop java-programmeurs mee tegen de schenen ;)

Maar on-topic. Ik schrijf voor elke public class/method/variable een commentaarblok in de vorm van de javadoc standaard. Wat me daarbij opvalt is dat voor vanzelfsprekende dingen overbodig commentaar komt te staan. Bijvoorbeeld bij simpele constructors, simpele getters en setters. Bijvoorbeeld het volgende:

Java:
1
2
3
4
5
6
7
/**
* Geeft het bericht terug.
* @return message het bericht van <insert zelfst nw>
*/
public String getMessage() {
  return _message;
}


Dan denk ik, wat voor zin heeft het? Alleen om de javadoc-generator geen warnings te laten geven?
Hoe denken andere java-programmeurs hierover?

[ Voor 50% gewijzigd door JeroenTheStig op 21-10-2005 13:32 ]


  • prototype
  • Registratie: Juni 2001
  • Niet online

prototype

Cheer Bear

Boktor schreef op vrijdag 21 oktober 2005 @ 13:05:
[...]


Noem het dan java-code in plaats van java-script, daar schop je namelijk een hoop java-programmeurs mee tegen de schenen ;)
Ik voelde me idd mateloos geoffendeerd hehe ;) Maar even zonder ongein een samenvatting voor de topicstarter:

* Javadoc (neem alleen dingen op die horen bij de specificatie van een classe! dat zijn dus alleen public en protected members)
* (Loop)Invariants (dit zijn invarianten die gelden over of de hele classe of voor een lus.)
B.v.:
Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Counter
{
    private int count; //@invariant: count >= 0
    public void increment()
    {
        this.count++;
    }

    public void decrement()
    {
        if (this.count > 0)
            this.count--;
    }
}


* Logica algebra (met name de wetten)
* Java naming convention (camelcasing)

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Boktor schreef op vrijdag 21 oktober 2005 @ 13:05:
[...]

Java:
1
2
3
4
5
6
7
/**
* Geeft het bericht terug.
* return message het bericht van <insert zelfst nw>
*/
public String getMessage() {
  return _message;
}
Ik zou zelf het commentaar ook in het engels schrijven. Omdat de programmeer taal en de syntax in het engels is vindt ik dat veel duidelijker. Anders krijg je een mengelmoes van engels en nederlands.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 25-04 21:17

curry684

left part of the evil twins

Eelke Spaak schreef op vrijdag 21 oktober 2005 @ 11:19:
Om even een voorbeeldje te noemen van hoe ik het niet zou doen:
Java:
1
class OZ2OG2NickVannieuwenhoven

Waarom zul je inmiddels wel begrijpen ;) .
Dat is sowieso idioot, daar heb je namespaces voor :)

Professionele website nodig?


  • JeroenTheStig
  • Registratie: Mei 2000
  • Laatst online: 14:18
rwb schreef op vrijdag 21 oktober 2005 @ 13:19:
[...]


Ik zou zelf het commentaar ook in het engels schrijven. Omdat de programmeer taal en de syntax in het engels is vindt ik dat veel duidelijker. Anders krijg je een mengelmoes van engels en nederlands.
Klopt. Ik commentarieer altijd in het engels, maar dit voorbeeld ging mij er om om aan te geven dat de commentaar zinloos is. Hoe pakken jullie dit soort dingen aan?

  • prototype
  • Registratie: Juni 2001
  • Niet online

prototype

Cheer Bear

rwb schreef op vrijdag 21 oktober 2005 @ 13:19:
[...]


Ik zou zelf het commentaar ook in het engels schrijven. Omdat de programmeer taal en de syntax in het engels is vindt ik dat veel duidelijker. Anders krijg je een mengelmoes van engels en nederlands.
Niet alleen dat, ik zou ook nog even de javadoc tags gebruiken ;) Bovendien moet een methode naam al vrijgeven wat het doet. getMessage is daarbij mateloos abstract, want wat voor message gaat het om? Een error message? Een liefdesboodschap? Ambiguiteit dus, waardoor ik misschien door naar de documentatie te kijken wijzer van wordt, maar dan ben ik al genoodzaakt om de stap te zetten om de documentatie erop na te slaan, terwijl b.v. getErrorMessage() in een keer al zegt wat het doet. Verder zou ik ook gebruik maken van pre- en postcondities (wedereens, uitsluitend dingen opnemen die tot de specificatie behoren), waardoor defensief programmeren dus wordt vermeden en dat zie je terug in omvang en dus ook in vermindering in complexiteit.
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
private int errorCount; // @invariant: errorCount >= 0


/**
 * Gets the error message.
 * 
 * @require this.errorCount() > 0
 * @ensure result != null 
 * @return The error message.
*/
public String getErrorMessage()
{
    String result;
    //... stub ...
    return result;
}

/**
 * Returns the number of errors that have occured by the time of invocation.
 *
 * @return The errorcount.
 */
public int errorCount()
{
    return this.errorCount;
}


Niet de meest ideale manier op pre- en postcondities te demo'en, maar ik hoop dat het idee een beetje duidelijk wordt. Als een preconditie door een client niet aan voldaan wordt, dan beloofd de server dus niets.

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 25-04 21:17

curry684

left part of the evil twins

Nederlands commentaar is net zoiets als een boek dat in geforceerd Nederlands probeert uit te leggen hoe C++ werkt. Ik heb er vandeweek zo een in handen gehad, en ik was er straal van overtuigd dat ze niets over templates hadden totdat mijn oog viel op 'klassensjablonen'. Zelfs termen als inheritance komen in heel het boek niet voor :X

Sowieso, commentaar schrijf je niet alleen voor jezelf maar vooral ook voor anderen. En dus schrijf je het in een taal die iedereen kent, oftewel Engels.

Professionele website nodig?


  • JeroenTheStig
  • Registratie: Mei 2000
  • Laatst online: 14:18
prototype schreef op vrijdag 21 oktober 2005 @ 13:30:
[...]


Niet alleen dat, ik zou ook nog even de javadoc tags gebruiken ;) Bovendien moet een methode naam al vrijgeven wat het doet. getMessage is daarbij mateloos abstract, want wat voor message gaat het om? Een error message? Een liefdesboodschap? Ambiguiteit dus, waardoor ik misschien door naar de documentatie te kijken wijzer van wordt, maar dan ben ik al genoodzaakt om de stap te zetten om de documentatie erop na te slaan, terwijl b.v. getErrorMessage() in een keer al zegt wat het doet. Verder zou ik ook gebruik maken van pre- en postcondities (wedereens, uitsluitend dingen opnemen die tot de specificatie behoren), waardoor defensief programmeren dus wordt vermeden en dat zie je terug in omvang en dus ook in vermindering in complexiteit.
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
private int errorCount; // @invariant: errorCount >= 0


/**
 * Gets the error message.
 * 
 * @require this.errorCount() > 0
 * @ensure result != null 
 * @return The error message.
*/
public String getErrorMessage()
{
    String result;
    //... stub ...
    return result;
}

/**
 * Returns the number of errors that have occured by the time of invocation.
 *
 * @return The errorcount.
 */
public int errorCount()
{
    return this.errorCount;
}


Niet de meest ideale manier op pre- en postcondities te demo'en, maar ik hoop dat het idee een beetje duidelijk wordt. Als een preconditie door een client niet aan voldaan wordt, dan beloofd de server dus niets.
Mijn getMessage is idd ook niet de ideale manier om duidelijk te maken wat mijn probleem is. Laten we voor de duidelijkheid getMessage dan vervangen door getLoveLetter() ;) Wat voor commentaar krijg je daarbij? Juist: "returns the loveletter".
En javadoc tags, hoezo heb ik die niet gebruikt? O-)

  • prototype
  • Registratie: Juni 2001
  • Niet online

prototype

Cheer Bear

Boktor schreef op vrijdag 21 oktober 2005 @ 13:35:
[...]


Mijn getMessage is idd ook niet de ideale manier om duidelijk te maken wat mijn probleem is. Laten we voor de duidelijkheid getMessage dan vervangen door getLoveLetter() ;) Wat voor commentaar krijg je daarbij? Juist: "returns the loveletter".
En javadoc tags, hoezo heb ik die niet gebruikt? O-)
Maar dat is het hele punt :) Het commentaar is al bij wijze van spreken overbodig, doordat de methodenaam al mateloos triviaal is, maar toch voeg je de commentaar er alsnog bij ivm consistentie en voor de mensen die wat trager van begrip zijn ;).
En nee, je was vergeten een @ voor 'return' te plaatsen ;)

  • prototype
  • Registratie: Juni 2001
  • Niet online

prototype

Cheer Bear

curry684 schreef op vrijdag 21 oktober 2005 @ 13:33:
Nederlands commentaar is net zoiets als een boek dat in geforceerd Nederlands probeert uit te leggen hoe C++ werkt. Ik heb er vandeweek zo een in handen gehad, en ik was er straal van overtuigd dat ze niets over templates hadden totdat mijn oog viel op 'klassensjablonen'. Zelfs termen als inheritance komen in heel het boek niet voor :X

Sowieso, commentaar schrijf je niet alleen voor jezelf maar vooral ook voor anderen. En dus schrijf je het in een taal die iedereen kent, oftewel Engels.
Haha, ik had laatst hetzelfde, alleen was het toen Genericiteit en Overerving, opzich nog te begrijpen, maar je zou maar iemand in dienst hebben die zo praat. ;)

  • Nick_S
  • Registratie: Juni 2003
  • Laatst online: 22-04 03:55

Nick_S

++?????++ Out of Cheese Error

Heb je extra informatie over de tags @ensure, @invariant en @require. Dit is de eerste keer dat ik dat tegenkom en via google kom ik er ook niet echt uit (java javadoc ensure require).

'Nae King! Nae quin! Nae Laird! Nae master! We willna' be fooled agin!'


  • Erkens
  • Registratie: December 2001
  • Niet online

Erkens

Fotograaf

prototype schreef op vrijdag 21 oktober 2005 @ 13:16:
* Javadoc (neem alleen dingen op die horen bij de specificatie van een classe! dat zijn dus alleen public en protected members)
Waarom niet bij private members :?

Ik gooi meestal ook wat javadoc bij private members, juist omdat je daardoor een snel overzicht hebt van wat het voor moet stellen.

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 15-04 22:07

NMe

Quia Ego Sic Dico.

Nick_S schreef op vrijdag 21 oktober 2005 @ 14:17:
Heb je extra informatie over de tags @ensure, @invariant en @require. Dit is de eerste keer dat ik dat tegenkom en via google kom ik er ook niet echt uit (java javadoc ensure require).
http://java.sun.com/j2se/javadoc/

Have fun. ;)

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


  • prototype
  • Registratie: Juni 2001
  • Niet online

prototype

Cheer Bear

Nick_S schreef op vrijdag 21 oktober 2005 @ 14:17:
[...]


Heb je extra informatie over de tags @ensure, @invariant en @require. Dit is de eerste keer dat ik dat tegenkom en via google kom ik er ook niet echt uit (java javadoc ensure require).
Dit zijn tags die gebruikt worden bij het code by contract principe, waarbij pre- en postcondities een essentiele rol bij spelen. Als je daar op googled vind je een hoop meer erover terug :) Je kan javadoc custom tags oplaten nemen en deze vallen daar dan ook onder :) @invariant in het bijzonder is opgenomen met // comment, en wordt dus niet door javadoc geparsed, omdat de invariant ook van toepassing is op de implementatie en dus niet interessant is voor de 'buitenwereld' i.e. het behoort niet tot de classenspecificatie.
Erkens schreef op vrijdag 21 oktober 2005 @ 14:21:
[...]

Waarom niet bij private members :?

Ik gooi meestal ook wat javadoc bij private members, juist omdat je daardoor een snel overzicht hebt van wat het voor moet stellen.
Omdat private members implementatie gebonden zijn; public en protected behoren tot de specificatie van de classe, i.e. het is zichtbaar voor de 'buitenwereld'. Als ik gebruik ga maken van een classe dan doet het mij er niet toe wat er op 'onderwater' niveau gebeurt, slechts is voor mij van belang wat de interface is waar ik tegenaan programmeer.

Een analogie: een tv bijvoorbeeld, ik hoef als gebruiker van de tv alleen maar te weten dat er een aan/uit knop b.v. op zit, wat er binnen gebeurt hoef ik niet te weten. Encapsulation :)

[ Voor 10% gewijzigd door prototype op 21-10-2005 14:28 ]


  • Erkens
  • Registratie: December 2001
  • Niet online

Erkens

Fotograaf

prototype schreef op vrijdag 21 oktober 2005 @ 14:26:
Omdat private members implementatie gebonden zijn; public en protected behoren tot de specificatie van de classe, i.e. het is zichtbaar voor de 'buitenwereld'. Als ik gebruik ga maken van een classe dan doet het mij er niet toe wat er op 'onderwater' niveau gebeurt, slechts is voor mij van belang wat de interface is waar ik tegenaan programmeer.

Een analogie: een tv bijvoorbeeld, ik hoef als gebruiker van de tv alleen maar te weten dat er een aan/uit knop b.v. op zit, wat er binnen gebeurt hoef ik niet te weten. Encapsulation :)
Maar natuurlijk, maar afaik doet de javadoc parser (:?) niks met javadoc @ private members, waardoor je voor je zelf in de code wel alles generiek en overzichtelijk hebt.

  • Kwistnix
  • Registratie: Juni 2001
  • Laatst online: 15:08
Boktor schreef op vrijdag 21 oktober 2005 @ 13:05:
[...]


Maar on-topic. Ik schrijf voor elke public class/method/variable een commentaarblok in de vorm van de javadoc standaard. Wat me daarbij opvalt is dat voor vanzelfsprekende dingen overbodig commentaar komt te staan. Bijvoorbeeld bij simpele constructors, simpele getters en setters. Bijvoorbeeld het volgende:

Java:
1
2
3
4
5
6
7
/**
* Geeft het bericht terug.
* @return message het bericht van <insert zelfst nw>
*/
public String getMessage() {
  return _message;
}


Dan denk ik, wat voor zin heeft het? Alleen om de javadoc-generator geen warnings te laten geven?
Hoe denken andere java-programmeurs hierover?
Zo doe ik het dus ook altijd en ik ben altijd langer bezig met (in mijn ogen overbodig) commentaar toe te voegen voor triviale methoden, zoals standaard getters en setters, dan met het aanmaken van de methoden zelf (zeker wanneer je die met een IDE kan genereren).
Iedereen die de code leest begrijp direct wat de methode doet (mits duidelijke naamgeving) en toch ga je commentaar toevoegen om de Javadoc voor die klassen compleet te houden.
Ik geen fan van commentaar toevoegen, maar ik begrijp het belang er van dus ik doe het altijd netjes, maar soms gaat er echt teveel tijd aan verloren.

  • prototype
  • Registratie: Juni 2001
  • Niet online

prototype

Cheer Bear

Erkens schreef op vrijdag 21 oktober 2005 @ 14:30:
[...]

Maar natuurlijk, maar afaik doet de javadoc parser (:?) niks met javadoc @ private members, waardoor je voor je zelf in de code wel alles generiek en overzichtelijk hebt.
Valt wat over te zeggen, maar bij mij is het 9/10 zo dat ik private methods vooral gebruik als auxilery methoden, die qua complexiteit niet veel meewegen. Commentaar erbij toevoegen streeft vaak z'n doel voorbij, in dat de commentaarblok groter is dan de code zelf bij wijze van spreken :) Dit vergroot onnodig de omvang, maar bij een complexe private member zou ik het wel willen overwegen idd, vooral als het niet geheel zeker is of deze wel altijd private moet blijven.

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 23-04 02:19
Het doel van commentaar is uitleg geven over de bedoeling en opzet van de code die niet helder is uit de code zelf. Commentaar voegt dan wat toe aan de code.

Veel programmeurs maken de fout te denken dat ze de werking van hun hele programma in het commentaar kwijtmoeten. Dat is niet alleen onnodig veel werk, maar het heeft ook het vervelende probleem dat mensen bij het doornemen van de code voornamelijk het commentaar bekijken en niet de code zelf. Op die manier zie je fouten over het hoofd als het commentaar aangeeft wat er moet gebeuren maar de code zelf daar niet mee overeenkomt. Sowieso heb je het probleem dat je voor elke aanpassing die je doet zowel commentaar als code moet aanpassen; duplicatie van 'code' is altijd een probleem.

Als je je aanwent om code te lezen, leer je ook code op te schrijven op een manier dat die duidelijk leesbaar is. Ik vind jouw voorbeeld al niet echt geweldig geïmplementeerd, omdat 'ie stikt van allemaal boolean variabelen die wel of niet geset zijn. Het wordt zo ontzettend onoverzichtelijk wat nu precies de staat van het programma wordt. (Sowieso zie ik al een bug op regel 28: de eerste keer controleer je niet of er een integer in te lezen valt, wat waarschijnlijk een exceptie oplevert.)

Je kunt naar mijn mening dus beter al het commentaar wegmikken en de code herschrijven. Ik zou zelf duidelijk onderscheid maken tussen het inlezen van de invoer en het geven van de uitvoer. Eerst een regel met getallen inlezen, bijvoorbeeld, en daarna bepalen of die oplopend, aflopend of gelijk zijn; dat kun je ook mooi in een aparte functie stoppen.

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 23-04 02:19
curry684 schreef op vrijdag 21 oktober 2005 @ 13:33:
Nederlands commentaar is net zoiets als een boek dat in geforceerd Nederlands probeert uit te leggen hoe C++ werkt. Ik heb er vandeweek zo een in handen gehad, en ik was er straal van overtuigd dat ze niets over templates hadden totdat mijn oog viel op 'klassensjablonen'.
Ik vind sjabloon altijd wel een mooi woord O+. Maar echt praktisch is het inderdaad niet.

  • ronaldmathies
  • Registratie: Juni 2001
  • Niet online
Javadoc kan prima overweg met comments bij private members / methods / klasse. Alleen moet je het dan wel expliciet opgeven:

javadoc.exe -[public/protected/package/private]

-public
Shows only public classes and members.

-protected
Shows only protected and public classes and members. This is the default.

-package
Shows only package, protected, and public classes and members.

-private
Shows all classes and members.

Als je wilt weten hoe je voor Java code comments hoort te schrijven kijk dan eens op:

http://java.sun.com/j2se/javadoc/index.jsp

Bijvoorbeeld :

How to Write Doc Comments for Javadoc - Sun conventions for writing documentation comments.
http://java.sun.com/j2se/...ingdoccomments/index.html

Requirements for Writing API Specifications
http://java.sun.com/j2se/javadoc/writingapispecs/index.html

De meeste Java ontwikkelaars houden zich hier aan, dit is een consistente duidelijke manier van schrijven.

Probeer commentaar generiek te schrijven, vaak heb je code stukken die eigenlijk hetzelfde doen maar voor iets andere data. Dit zie je bijvoorbeeld veel bij EJB's het principe achter de ejbCreate is hetzelfde, ga dan ook niet elke keer opnieuw een gedetaileerde beschrijving erbij maken maar maak een generieke met eventueel een verwijzing naar de documentatie in de EJB specificatie.
Zelfde geldt bijvoorbeeld voor EJB klassen. Maak een deel standaard commentaar wat uitlegt waarvoor de klasse is en voeg een stukje toe om het verschil met de andere uit te leggen. Zo bespaar je een hoop werk en blijft het alsnog duidelijk.

Daarnaast leest het ook nog eens sneller omdat je als lezer op ten duur door hebt dat bepaalde commentaar stukken hetzelfde zijn met als gevolg dat je de teksten ook makkelijker begrijpt.

Wij hebben bij ons een project gemaakt en hier was de verhouding commentaar / code ongeveer 60 / 40 (dus ja meer commentaar dan code). Maar toch was het schrijven van de commentaar in verhouding van de code ongeveer 30 / 70, Dit omdat we geprobeerd hebben in eerste instantie meer moeite te steken in generieke documentatie die we vervolgens konden hergebruiken.

[ Voor 38% gewijzigd door ronaldmathies op 21-10-2005 15:29 ]

3015 Wp-z 5360 Wp-nno op 2 x SMA-SB3600 TL-21, Warmtepomp: ERSC-VM2CR2 / PUHZ-SHW140 YHA, WTW Q350, EV Kia Ev6 GT-Line


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 01:30

.oisyn

Moderator Devschuur®

Demotivational Speaker

curry684 schreef op vrijdag 21 oktober 2005 @ 13:33:
en ik was er straal van overtuigd dat ze niets over templates hadden totdat mijn oog viel op 'klassensjablonen'.
:X :X :X
Wij hebben te kampen met vergelijkbare problemen, vertalers die je game iets te over-localizeren. Dan krijg je settings als "hoekpuntarcering", "beeldpuntarcering", "'gecomprimeerde structuren", "naverwerking" en "overdruk"

vertexshaders, pixelshaders, compressed textures, post-processing, decals

En:
C++:
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
#define klasse class
#define sjabloon template
#define voor for
#define kaats return
#define nieuw new
#define verwijder delete
#define niets void

sjabloon<klasse T> klasse Foo
{
    niets DoeIets()
    {
        T * t = nieuw T();
        t->DoeIets();
        verwijder t;
    }

    int VerkrijgWaarde()
    {
        int k = 0;
        voor (int i = 0; i < 10; i++)
            k += i*i;
        kaats k;
    }
};

:P

[ Voor 35% gewijzigd door .oisyn op 21-10-2005 15:58 ]

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.


  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
.oisyn schreef op vrijdag 21 oktober 2005 @ 15:51:
[...]


:X :X :X
Wij hebben te kampen met vergelijkbare problemen, vertalers die je game iets te over-localizeren. Dan krijg je settings als "hoekpuntarcering", "beeldpuntarcering", "'gecomprimeerde structuren", "naverwerking" en "overdruk"

vertexshaders, pixelshaders, compressed textures, post-processing, decals
LOL, als je dat tegen zou komen zou ik inderdaad echt wel 5 keer moeten kijken om te snappen wat ze nou bedoelen.
C++:
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
#define klasse class
#define sjabloon template
#define voor for
#define kaats return
#define nieuw new
#define verwijder delete
#define niets void

sjabloon<klasse T> klasse Foo
{
    niets DoeIets()
    {
        T * t = nieuw T();
        t->DoeIets();
        verwijder t;
    }

    int VerkrijgWaarde()
    {
        int k = 0;
        voor (int i = 0; i < 10; i++)
            k += i*i;
        kaats k;
    }
};

:P
Ja dat soort dingen komen me bekend voor van op de hbo om de docent te pesten :P. Helaas werd je dan altijd fijn terug gepest omdat je het nogmaals mocht maken :P

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 25-04 21:17

curry684

left part of the evil twins

C++:
1
#define kaats return 

_o_

Professionele website nodig?


  • Nick_S
  • Registratie: Juni 2003
  • Laatst online: 22-04 03:55

Nick_S

++?????++ Out of Cheese Error

Ik hoopte, dat uit mijn vraag over die specifieke tags wel duidelijk was, dat ik javadoc wel kende. Helaas had ik dus niks aan je link.

Aan Prototype's antwoord had ik meer en ik ga eens zoeken op "code by contract". Thanks!

'Nae King! Nae quin! Nae Laird! Nae master! We willna' be fooled agin!'


  • Nick The Heazk
  • Registratie: Maart 2004
  • Laatst online: 07-09-2024

Nick The Heazk

Zie jij er wat in?

Topicstarter
Ik heb me zonet beziggehouden met het herschrijven van de comments en enkele onderdelen van het programmaatje.

Ik heb getracht zoveel mogelijk goede raad op te volgen met uitzondering van JavaDoc (dat heb ik nog niet gezien) en gebruik maken van een OO-aanpak (deze opdracht was nog non-OO).

Nog even een verklaring voor de vreemde naamgeving: de programmaatjes die ik maak zijn allen voor 1 vak en tot nogtoe niet erg complex noch OO. Daarom bewaar ik al deze bestanden in eenzelfde map. Om snel na te gaan welk bestand bij welke opgave hoort schrijf ik de namen van mijn classes als OZXOGX (OefenZitting X OpGave X). Die naam daar hoorde nog uit het tijdperk dat ik dacht dat we dit electronisch moetsen indienen :).

Hieronder volgt het script samen met de aanpassingen die ik gemaakt heb:
- Alle comments geschrapt
- Alleen onderdelen die comment behoeven van comment voorzien
- Functie-beschrijving toegevoegd
- Prog herschreven zodat 2 booleans niet meer nodig zijn
- Overbodige check verwijderd
- Check op eerste input toegevoegd
- Functie kan ook bij 1 getal de ordening bepalen ... constant

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
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
import java.util.Scanner;
import java.lang.Integer;

/*--------------------Function Description-------------------*\
| This function checks if the row is either ascending,        |
| descending, constant or not ordered.                        |
| It automatically determines the order in the first loop.    |
\*-----------------------------------------------------------*/
class OrderedRows
  {
    public static void main(String args[])
     {
      boolean bBreak = false,
              bSorting = true,
              bCheck = true;
      int iCurrent = 0, iNext = 0;
      String sOutput = "",
             sHow = "";
      
      Scanner scan = new Scanner(System.in);
      
      System.out.println("Voer een rij getallen in gescheiden door een witruimte ('end' om te beeindigen):");
      if(scan.hasNextInt())
        iNext = scan.nextInt();
      else
        bBreak = true;
        
      while(!bBreak)
        {
        iCurrent = iNext;
            
        if(scan.hasNextInt())
          iNext = scan.nextInt();
        else
         break;
         
         //Determine order in first loop 
         if( (iCurrent > iNext) && bCheck )
           { bSorting = false; bCheck = false; }
        
         else if( (iCurrent < iNext) && bCheck )
           { bSorting = true; bCheck = false; }
        
         //Make sure order is correct 
         else if(!bSorting && (iCurrent < iNext) )
           bBreak = true;
        
         else if(bSorting && (iCurrent > iNext) )
           bBreak = true;
        }
      
      //Construct and print output 
      if(!bCheck)
        sHow = bSorting ? "stijgend": "dalend";
      else 
        sHow = "constant";
      
      sOutput = bBreak ? "Deze rij is niet stijgend of dalend": "Deze rij is " + sHow;
      
      System.out.println(sOutput);
     }
  }

[ Voor 10% gewijzigd door Nick The Heazk op 21-10-2005 18:33 ]

Performance is a residue of good design.


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 25-04 21:17

curry684

left part of the evil twins

Je bent nu wel erg summier ineens met commentaar hoor :D

Ik hou altijd als stelregel aan dat je een functie kunt onderverdelen in 1..x functionele blokken van 1..x regels. Vervolgens plaats ik voor ieder blok een commentaarregel, en houd ik een witregel tussen die blokken. Een functioneel blok is zelden langer dan 5 regels, eigenlijk alleen als het oftewel heel straightforward is of heel veel identieke operaties (20 properties zetten op hetzelfde object is gewoon "Initialize object blahblah" ;) ).

Uiteindelijk is een goede vuistregel dat je met puur en alleen de comments de functie beschreven hebt. Bij jou staat er nu:
Java:
1
2
3
         //Determine order in first loop 
         //Make sure order is correct 
      //Construct and print output  

Da's niet veel :P Wat de functie doet zet je in het commentaar erboven, hoe je dat stapsgewijs doet staat ertussen. Ik zou moeten lezen:
Java:
1
2
3
4
5
6
// Request input from the user and start parsing
// Loop until sufficient input was parsed
  // Advance in the sequence and check whether we're already done
  // Determine order in first loop 
  // Make sure order is correct 
// Construct and print output

En dan zie je dat het commentaar een erg summiere doch volledige samenvatting is van alles wat je doet :)

Professionele website nodig?


  • prototype
  • Registratie: Juni 2001
  • Niet online

prototype

Cheer Bear

Hehe lol @ .oisyn! :D
Nick_S schreef op vrijdag 21 oktober 2005 @ 16:39:
[...]


Ik hoopte, dat uit mijn vraag over die specifieke tags wel duidelijk was, dat ik javadoc wel kende. Helaas had ik dus niks aan je link.

Aan Prototype's antwoord had ik meer en ik ga eens zoeken op "code by contract". Thanks!
Hehe, er zijn boeken over geschreven over code by contract aka design by contract; hier op de UTwente is het de standaard de facto. Handig linkje voor je als je je wat meer erin wil verdiepen: http://en.wikipedia.org/wiki/Design_by_contract

  • Tomatoman
  • Registratie: November 2000
  • Laatst online: 26-04 20:15

Tomatoman

Fulltime prutser

In wat voor stijl je het commentaar geeft is in grote mate een kwestie van smaak, het gaat in eerste instantie om wát voor commentaar je levert. Wel zie ik een onderscheid tussen de soorten commentaar die je levert, ongeacht de programmeertaal die je gebruikt.

• Ten eerste is er de uitleg bij een functie /class /andersoortige declaratie - die is bedoeld voor de gebruiker om te begrijpen hoe hij de functie/ class/ enzovoort dient te gebruiken. Hoe de code is geïmplementeerd is bij declaraties niet van belang, het gaat om de functionaliteit.

Bij dingen zoals functiedeclaraties is dat simpel, namelijk: een algemene omschrijving van wat de functie doet; (voor zover niet overduidelijk) wat de functieparameters doen; wat de geretourneerde waarde is en eventueel nog wat uitzonderlijke dingen zoals exceptions die de gebruiker om zijn oren geslingerd kan rijgen. Om een voorbeeld te geven:
Delphi:
1
2
3
4
5
6
7
8
9
{ CanAccessAuditAlarms indicates if the calling process can acquire the
  privilege to access audit alarms for system objects. Audit alarm settings
  determine which security-related events generate audit reports in the security
  event log.
    - Windows 95/98/Me: Audit alarms are not supported and the function always
      returns False.
    - Windows NT4/2000/XP/2003: Typically, only administrators can acquire the
      privilege to access audit alarms. }
function CanAccessAuditAlarms: Boolean;



• Ten tweede is er de implementatie van de code. Daarbij gebruik je een heel ander soort commentaar. Hier dien je lastige code te commentariëren om hem begrijpelijk te maken voor iemand die de code probeert te begrijpen. Ook hier een voorbeeld:

Delphi:
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
function CanAccessAuditAlarms: Boolean;
var
  Token: THandle;
  NewState, PrevState: TTokenPrivileges;
  ReturnLength: Cardinal;
begin
  Result := False;

  { Audit alarms are unavailable on Windows 9x }
  if Win32Platform = VER_PLATFORM_WIN32_NT then
  begin
    { Impersonate the client in order create an impersonation token }
    Win32Check(ImpersonateSelf(SecurityImpersonation));
    try
      { Open the impersonated access token associated with the current thread }
      Win32Check(OpenThreadToken(GetCurrentThread, TOKEN_ADJUST_PRIVILEGES or
        TOKEN_QUERY, True, Token));
      try
        { Enable SeSecurityPrivilege, which allows to retrieve and change audit
          information via SACL_SECURITY_INFORMATION }
        Win32Check(LookupPrivilegeValue(nil, 'SeSecurityPrivilege',
          NewState.Privileges[0].Luid));
        NewState.PrivilegeCount := 1;
        NewState.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
        Win32Check(AdjustTokenPrivileges(Token, False, NewState,
          SizeOf(NewState), PrevState, ReturnLength));

        { Check if the privilege has been acquired }
        case GetLastError of
          ERROR_SUCCESS: Result := True;
          ERROR_NOT_ALL_ASSIGNED: Result := False;
        end;
      finally
        CloseHandle(Token);
      end;
    finally
      { Delete the impersonation token }
      RevertToSelf;
    end;
  end;
end;
Hoe AdjustTokenPrivileges nou precies wordt aangeroepen op regel 25 becommentarieer ik in de code bewust niet, dat valt na te lezen in de documentatie van Microsoft. Wel kun je op regel 19 en 20 lezen wat de regels code eronder doen, namelijk een privilege enablen. Al met al is het commentaar gedetailleerd genoeg om de grote lijnen van de code te begrijpen, zonder alle details uit te kauwen. Zelfs iemand die geen Delphi kent zal aan het commentaar genoeg hebben om enigszins te begrijpen wat de code doet. Anderzijds zou zelfs een doorgewinterde Delphiprogrammeur moeite hebben om deze code te begrijpen als er helemaal geen commentaar bij zou staan.

Een goede grap mag vrienden kosten.


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 01:30

.oisyn

Moderator Devschuur®

Demotivational Speaker

Hier staat overigens ook nog veel info in: [rml][ alg] Commentaar in code nodig of overbodig?[/rml]

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.


  • JayVee
  • Registratie: Mei 2002
  • Laatst online: 14-11-2025

JayVee

shibby++!

Voor mijn bedrijf heb ik de volgende guideline:
Als een comment alleen op een regel staat geeft het aan wat er gedaan wordt. Als je die leest zie je dus welke stappen doorlopen worden. Als je een bepaald stukje code wilt commenten omdat het misschien niet intuitief is of juist een bug oplost, etc, dan zet je je commentaar ernaast.
PHP:
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
//---------------------------------------
// Setup
//---------------------------------------

// -- load libraries --
require( 'util/include/specLib.inc.php' );
require( 'util/include/maskLib.inc.php' );
require( 'util/include/maskTrail.class.inc.php' );
require( 'util/include/queryBuilder.class.inc.php' );
    
// -- get parameters --
$_maskid = (int)$_GET['maskid'];

$_pagingOffset = 0; // default: start at page 1
if ( isset($_GET['offset']) ) {
    $_pagingOffset = (int)$_GET['offset'];
}



//---------------------------------------
// Cache user and mask information
//---------------------------------------

// -- store mask element names by id --
$_ar_mask = getMask( $_maskid, false, true );   // load mask with inactive fkey data
$_ar_maskElements = array();                    // used for optimization only
foreach ( $_ar_mask['ar_elements'] as $elName => $ar_trailElement ) {
    $_ar_maskElements[ $ar_trailElement['id'] ] = $elName;
}

// -- store full user names by id --
$_ar_users = array();
$sql_users = $_dbh->executeQuery( "SELECT id, fullname FROM support_user" );
while ( $row_users = $_dbh->fetchAssoc($sql_users) ) {
    $_ar_users[ $row_users['id'] ] = $row_users['fullname'];
}

De grote comment blokken geven de grote lijn van een grote functie of een heel script aan, de '// -- hoi --' comments geven aan welke stappen doorlopen worden in het algorithme.

Aangezien er dus vrij weinig documentatie in het script zelf staat maakt dat de code erg overzichtelijk (vind ik dan). Functies zijn goed gedocumenteerd met phpdoc (bijna hetzelfde als javadoc).
Daarnaast hebben we externe documentatie waar het idee achter een script wordt uitgelegd. Als je niet snapt waarom een bepaalde stap in het algorithme staat of 'waarom dat zo moeilijk moet' - dan kan je de externe documentatie lezen om te begrijpen hoe een script werkt. Door deze documentatie buiten de code te houden blijft de code leesbaar.

Zoals alle namen van variabelen en tabellen etc is ook de documentatie volledig Engels.

[ Voor 10% gewijzigd door JayVee op 22-10-2005 12:04 ]

ASCII stupid question, get a stupid ANSI!


  • prototype
  • Registratie: Juni 2001
  • Niet online

prototype

Cheer Bear

Gege, ik vind het altijd vrij komisch om ascii art commentblocken te zien. Waarom doen jullie dat eigenlijk? :D
Externe documentatie, is dat niet juist gigantisch onhandig/error prone? Ik bedoel, als de code aangepast dient te worden en de documentatie dus ook... dit laatste kan je misschien een keer over het hoofd zien, immers zijn we ook maar menselijk, dan klopt de hele documentatie al niet meer. Bovendien is het rete inconsistent, want je staat zowel documentatie in de code toe -zij het in beperkte mate- maar je hebt daarnaast nog paralel een documentatie lopen over de methode werking. Ik moet dus letterlijk heletijd switchen tussen twee bestanden om de werking ervan te doorgronden. Ik weet niet, ergens ontbreekt mij de logica van hoe dit handig kan zijn ;)
Een beetje IDE heeft tegenwoordig de optie om commentblocken te collapsen :)

[ Voor 8% gewijzigd door prototype op 22-10-2005 14:25 ]


  • JayVee
  • Registratie: Mei 2002
  • Laatst online: 14-11-2025

JayVee

shibby++!

Je moet er inderdaad aan wennen om bij ingrijpende veranderingen ook de externe documentatie aan te passen. Maar als je dat meteen doet zodra je klaar bent met wijzigen (en testen) is het niet veel meer werk dan wanneer de documentatie tussen de code staat. En ik vind dat code overzichtelijker wordt door globale en abstracte documentatie extern te houden.

De comments die er nu in staan dienen eigelijk puur het overzicht (ze beschrijven wat). Het is net een hoofdstuk indeling van een boek. (Daarom ook de "ascii" comments, zo zie je nog duidelijker of het een hoofdstuk of paragraaf is.) Sommige regels code moet je toch even van commentaar voorzien om duidelijk te maken wat het doet als dat niet zomaar af te lezen is. Als je bijvoorbeeld iets hebt als
code:
1
inp.name.substring( inp.name.indexOf('[')+1, inp.name.indexOf(']') );
is het wel zo mooi als je daar naast zet wat het nou eigelijk doet. En om dit voor de leesbaarheid nou in drie regels code te doen vind ik niet de moeite waard.

De documentatie die echt de stappen van het script / algorithme beschrijft (dus hoe en waarom (ook belangrijk!)) staat dus extern.

Misschien is dit ook alleen van toepassing als je grote lappen code hebt. Wij programmeren (nog?) niet OO in PHP en dan krijg je dus scripts van 100-600 regels (wel vrij veel whitespace, zie voorbeeld heirboven). Als je daar ook nog eens honderden regels documentatie in zet verlies je het overzicht.

ASCII stupid question, get a stupid ANSI!


  • prototype
  • Registratie: Juni 2001
  • Niet online

prototype

Cheer Bear

JayVee schreef op zaterdag 22 oktober 2005 @ 15:22:
Je moet er inderdaad aan wennen om bij ingrijpende veranderingen ook de externe documentatie aan te passen. Maar als je dat meteen doet zodra je klaar bent met wijzigen (en testen) is het niet veel meer werk dan wanneer de documentatie tussen de code staat. En ik vind dat code overzichtelijker wordt door globale en abstracte documentatie extern te houden.
Dan noem ik jou een noeste arbeider :) Persoonlijk heb ik geen zin na bugfixes doorgevoerd te hebben nog even pietje precies na te gaan wat ik nou exact heb aangepast. Nogmaals, je zou zomaar even een onderdeeltje vergeten op te nemen. Een beetje IDE kan die inline commentblocks zo collapsen...
De comments die er nu in staan dienen eigelijk puur het overzicht (ze beschrijven wat). Het is net een hoofdstuk indeling van een boek. (Daarom ook de "ascii" comments, zo zie je nog duidelijker of het een hoofdstuk of paragraaf is.) Sommige regels code moet je toch even van commentaar voorzien om duidelijk te maken wat het doet als dat niet zomaar af te lezen is. Als je bijvoorbeeld iets hebt als
code:
1
inp.name.substring( inp.name.indexOf('[')+1, inp.name.indexOf(']') );
is het wel zo mooi als je daar naast zet wat het nou eigelijk doet. En om dit voor de leesbaarheid nou in drie regels code te doen vind ik niet de moeite waard.
Die versiersels, leuk en aardig, maar het vertroebelt nogal je commentblocks imho, maar als je het consistent aanhoudt, more power to ya :) Persoonlijk zou ik een de facto standaard aanhouden.
Geheel subjectief natuurlijk, maar ik heb niet echt moeite te lezen wat er nou gebeurd (wat mijns inziens ook met een schonere regliere expressie kan).
De documentatie die echt de stappen van het script / algorithme beschrijft (dus hoe en waarom (ook belangrijk!)) staat dus extern.
Dit vind ik dus vrij intensief voor de programmeur en bovendien errorprone; ik moet heletijd switchen en kan daarbij wat vergeten zijn. Frustrerend :)
Misschien is dit ook alleen van toepassing als je grote lappen code hebt. Wij programmeren (nog?) niet OO in PHP en dan krijg je dus scripts van 100-600 regels (wel vrij veel whitespace, zie voorbeeld heirboven). Als je daar ook nog eens honderden regels documentatie in zet verlies je het overzicht.
De hele grap bij OO is om flexibiliteit te creeeren, redudancy in code tegen te gaan, complexiteit tegen te gaan en herbruikbaarheid dus bevorderen. Waar wacht je nog op? ;)

[ Voor 5% gewijzigd door prototype op 22-10-2005 15:36 ]


  • JayVee
  • Registratie: Mei 2002
  • Laatst online: 14-11-2025

JayVee

shibby++!

prototype schreef op zaterdag 22 oktober 2005 @ 15:34:
[...]

Dan noem ik jou een noeste arbeider :) Persoonlijk heb ik geen zin na bugfixes doorgevoerd te hebben nog even pietje precies na te gaan wat ik nou exact heb aangepast. Nogmaals, je zou zomaar even een onderdeeltje vergeten op te nemen. Een beetje IDE kan die inline commentblocks zo collapsen...
In de externe documentatie staat wat het script doet. Als je een bugfix doorvoert of een stuk code optimaliseert veranderd er niets aan de documentatie! Het script doet eindelijk of nog steeds wat er in de documentatie staat.
Die versiersels, leuk en aardig, maar het vertroebelt nogal je commentblocks imho, maar als je het consistent aanhoudt, more power to ya :) Persoonlijk zou ik een de facto standaard aanhouden.
Geheel subjectief natuurlijk, maar ik heb niet echt moeite te lezen wat er nou gebeurd (wat mijns inziens ook met een schonere regliere expressie kan).
We hebben eigen coding standards (over whitespace, commentaar, naamgeving variabelen, etc). Het is voor de meeste programmeurs waarschijnlijk wel even wennen, maar uiteindelijk wen je er wel aan. En dan vind ik deze manier van werken erg overzichtelijk.
Een substring pakken met een regExp? Kan dat zo makkelijk in javascript? Was ook maar een voorbeeld. Een regExp moet je ook commenten, omdat die al helemaal onleesbaar zijn voor regExp n00bs (such as myself).
Dit vind ik dus vrij intensief voor de programmeur en bovendien errorprone; ik moet heletijd switchen en kan daarbij wat vergeten zijn. Frustrerend :)
Je kan aan de aanwezige commentaren zien wat het script doet. Meestal ben je al een tijd bezig met een bepaald script en weet je toch wel hoe het in elkaar zit. Mocht je nou een (half) jaar later vergeten zijn hoe het script op globaal niveau (script of zelfs inter-script) werkt (of je hebt het nooit begrepen :+ ), dan raadpleeg je de externe documentatie. Het is net als een manual van een programma. Die pak je erbij als je er zo niet uitkomt.
Nu kunnen we de discussie voeren "waarom zou je de manual niet integreren", oftewel: waarom ueberhaupt externe documentatie gebruiken. Nou, omdat het script zo lekker clean blijft en je minder regels hoeft te bekijken om een bepaalde plek te vinden.
De hele grap bij OO is om flexibiliteit te creeeren, redudancy in code tegen te gaan, complexiteit tegen te gaan en herbruikbaarheid dus bevorderen. Waar wacht je nog op? ;)
Ik zie het nu van OO in PHP niet zo. Het zorgt voor veel overhead (niet alleen kwa performance, ook heb je meer code nodig). We hebben wel wat objecten, maar dat zijn flexibel en globaal inzetbare tools (bijvoorbeeld: querybuilder, database handler, error handler, etc). Redundante stukken code (veiligheid en sessiebeheer, layout template, veel gebruikte code) hebben we wel in aparte scripts of functies gezet. Maar het echte werk wordt over het algemeen door een script gedaan. Deze bevatten vaak wel wat functies om de complexiteit te verlagen, maar over het algemeen zijn het redelijk lange lappen code.

Kijk, over het algemeen zie ik het voordeel van OO programmeren wel in! Maar bij web applicaties vind ik 'functioneel' (volgens mij gebruik ik hier de verkeerde term) programmeren beter passen.

[ Voor 7% gewijzigd door JayVee op 22-10-2005 20:52 ]

ASCII stupid question, get a stupid ANSI!


  • prototype
  • Registratie: Juni 2001
  • Niet online

prototype

Cheer Bear

Smaken verschillen :) Voorbeeldje iig van iets dat ik aan het maken ben en dat ik in PHP mistte, een ArrayList classe ;)
PHP:
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
<?php
    /**
    * ArrayList blablablabla
    *
    * @author Ninh Bui
    * @version $Revision$
    */
    class PArrayList implements PList
    {
    //*knip*

        /** 
         * Gets the index of the first occurance of a provided element from this list, if present.
         *
         * @param   mixed The element from which we want the index of the first occurance in this list.
         * @return        The index of the first occurance of the given object in this list.
         *                -1 if the given object is not in this list.
         * @ensure  result >= -1 && result < this.size().
         *          result > 0 implies that for all k from [0, result - 1]: !this.get(k).equals(mixed)
         *                                                                  && this.get(result).equals(mixed).
         *          result < 0 implies that for all m from [0, this.size() - 1]: !this.get(m).equals(mixed).
         */
        public function indexOf($mixed)
        {
            $found = false;
            $i = 0;
            
            while($i < $this->size && !$found)
            {
                // @invariant:  For all k from [0, i - 2]: !this.get(k).equals(mixed).
                //              found   => this.get(i - 1).equals(mixed).
                //              !found  => !this.get(i - 1).equals(mixed).
                $found = ($this->list[$i] == $mixed);
                $i++;
            }

            return ( ($found) ? ($i - 1) : -1 );
        }

    //*knip*
    }
?>
Waarschijnlijk zullen een paar lezers nu wel van hun stoel flikkeren, omdat er zowaar meer commentaar staat dan code en jij al helemaal omdat het in de code zit ;)

  • alienfruit
  • Registratie: Maart 2003
  • Laatst online: 18-04 05:37

alienfruit

the alien you never expected

Nou deze commentaar lijkt mij geen probleem, zo doe ik het zelf ook vaak :) Hoewel ik wel val over de PArrayList. P? T ;)

  • prototype
  • Registratie: Juni 2001
  • Niet online

prototype

Cheer Bear

alienfruit schreef op zaterdag 22 oktober 2005 @ 22:03:
Nou deze commentaar lijkt mij geen probleem, zo doe ik het zelf ook vaak :) Hoewel ik wel val over de PArrayList. P? T ;)
Haha, T is niet origineel meer, dus ik dacht hmmm, P van Prototype/Phusion ;)

  • Bluestorm
  • Registratie: Januari 2000
  • Laatst online: 20-08-2022
prototype schreef op zaterdag 22 oktober 2005 @ 22:01:
PHP:
1
2
3
4
5
6
7
8
9
10
11
<?php
while($i < $this->size && !$found)
            {
                // @invariant:  For all k from [0, i - 2]: !this.get(k).equals(mixed).
                //              found   => this.get(i - 1).equals(mixed).
                //              !found  => !this.get(i - 1).equals(mixed).
                $found = ($this->list[$i] == $mixed);
                $i++;
            }

?>

Waarschijnlijk zullen een paar lezers nu wel van hun stoel flikkeren, omdat er zowaar meer commentaar staat dan code en jij al helemaal omdat het in de code zit ;)
Persoonlijk vind ik bovenstaande inderdaad een beetje overdreven. Het is dermate cryptisch dat het niet makkelijker leest dan de eigenlijke code en het voegt ook niet echt informatie toe. Bovendien is het voor mij persoonlijk in iedergeval zeer gevoelig om te vergeten als je de code wijzigt.

Doe mij ook maar gewoon een 'kopje' per blokje code en dan een goede documentatie van de functie. Zelf zie ik goed commentaar/api documentatie schrijven trouwens wel als een van de moeilijkere dingen van programmeren. In iedergeval iets wat in mijn opleiding tot nu toe wel mist... Veel dieper dan 'je moet commentaar schrijven' gaat het niet.
(Mijn luie ik vind ondertussen dat een programmeertaal zelf ruimte moet bieden voor formele beschrijving van alle voorwaarden, etc en dat je daar dan samen met de testcases eigenlijk best automatisch goed leesbare engelstalige documentatie uit zou moeten kunnen genereren :D Totdat dat kan blijf je alles sowieso altijd min om meer dubbel opschrijven, wat gewoon gevoelig is voor fouten en luiheid. )

Tenminste... dat [ denk / zie / weet ] ik... | Javascript obfuscator | foto's en video's uploaden


  • prototype
  • Registratie: Juni 2001
  • Niet online

prototype

Cheer Bear

Bluestorm schreef op zondag 23 oktober 2005 @ 19:21:
[...]


Persoonlijk vind ik bovenstaande inderdaad een beetje overdreven. Het is dermate cryptisch dat het niet makkelijker leest dan de eigenlijke code en het voegt ook niet echt informatie toe. Bovendien is het voor mij persoonlijk in iedergeval zeer gevoelig om te vergeten als je de code wijzigt.
Hehe, dat is een loopinvariant, en deze is noch cryptisch noch 'nutteloos'; het is een conditie die geldt voor elke iteratie. Het zegt dat bij een bepaalde iteratie i, voor alle indexes k van 0 t/m i-2 dat deze elementen niet overeenkomen met het gegeven object. Indien found true is, impliceert dat dat i-1 de index is die overeenkomt met mixed, en indien found false is, betekent dat geen enkele element overeenkomt met het gegeven object. Als je het niet gewend bent om invarianten te lezen dan kan het misschien kryptisch overkomen, maar lusinvarianten bewijzen de correctheid van je lus, en ik word er ook mee doodgegooid bij m'n opleiding ;)

[ Voor 5% gewijzigd door prototype op 23-10-2005 21:03 ]


  • Bluestorm
  • Registratie: Januari 2000
  • Laatst online: 20-08-2022
Ik zie wel wat het doet enzo hoor, maar persoonlijk vind ik dat bij dit soort meer formele notaties (OCL bijvoorbeeld) het al vaak neigen naar een functionele programmeertaal zonder het voordeel dat je het daadwerkelijk kunt uitvoeren. Doe mij dan toch maar gewoon code om te testen of het werkt voor alle uitzonderingen, etc. In plaats van onderhoudsgevoelig commentaar wat ik zelf moet interpreteren en naast de code houden om te zien of het klopt.

Als ik trouwens oude code van mezelf terug kijk heb ik vaak het meeste aan het commentaar wat meer globale structuur van het geheel beschrijft. Met goede naamgeving, etc kom je voor individuele stukken code meestal wel een eind,maar juist het doel en de relaties/afhankelijkheden zijn vaak achteraf moeilijk te achterhalen.

[ Voor 37% gewijzigd door Bluestorm op 23-10-2005 23:40 ]

Tenminste... dat [ denk / zie / weet ] ik... | Javascript obfuscator | foto's en video's uploaden

Pagina: 1