<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
		>
<channel>
	<title>Comments on: Comments != Code Smell</title>
	<atom:link href="http://ilker.de/comments-code-smell/feed" rel="self" type="application/rss+xml" />
	<link>http://ilker.de/comments-code-smell</link>
	<description>Creative Computing.</description>
	<lastBuildDate>Tue, 31 Jan 2012 12:27:32 +0000</lastBuildDate>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
	<item>
		<title>By: RYErnest</title>
		<link>http://ilker.de/comments-code-smell#comment-283</link>
		<dc:creator>RYErnest</dc:creator>
		<pubDate>Sun, 30 Nov 2008 03:07:32 +0000</pubDate>
		<guid isPermaLink="false">http://www.gmbsg.com/stories/?p=202#comment-283</guid>
		<description>Nice post u have here :D Added to my RSS reader</description>
		<content:encoded><![CDATA[<p>Nice post u have here <img src='http://ilker.de/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' />  Added to my RSS reader</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Ilker Cetinkaya</title>
		<link>http://ilker.de/comments-code-smell#comment-282</link>
		<dc:creator>Ilker Cetinkaya</dc:creator>
		<pubDate>Sun, 23 Nov 2008 11:27:17 +0000</pubDate>
		<guid isPermaLink="false">http://www.gmbsg.com/stories/?p=202#comment-282</guid>
		<description>Hi Tobi,

zunächst einmal: Good Code!

Da sieht man mal, wie wichtig es ist, gute Kommentare zu schreiben und diese auch richtig zu lesen. Fakt ist, das Du mit der &quot;Synchronisation&quot; von HttpRequest.Cookies und HttpResponse.Cookies recht hast - sie werden nicht synchronisiert. Allerdings scheint es mir hast Du den Kommentar falsch interpretiert - es geht nicht um die Erstellung eines neuen Cookies, sondern um die Modifikation.

Doch auch bei der Modifikation muss ich Dir natürlich recht geben - immer über HttpResponse.Cookies gehen! Ich behaupte jedoch weiterhin, das der gezeigte Code richtig ist. Wie kommt&#039;s?

Tja, gerade das, was Du im Kommentar kritisierst ist wohl der entscheidende Hint: die Methode heisst &quot;ResetSessionCookieDomain&quot;. Soll heissen, die Methode setzt den Domain-Wert des Session-Cookies zurück. Man beachte auch, das der gesamte Code wie erwähnt in einem HttpModule abläuft. Die einzige wichtige Info, die ich nicht mitgegeben habe ist, das die Methode effektiv aufgerufen wird, nachdem der SessionState von der HttpRuntime erzeugt wurde (siehe AquireRequestState / ReleaseRequestState). **In genau diesem Kontext** ist es korrekt, den Session-Cookie über HttpRequest.Cookies zu verändern. Genau genommen ist sogar der Kommentar **in genau diesem Kontext** richtig - obwohl er wirklich irreführend ist.

Denn genau auf die selbe (richtige) Art und Weise, wie Du in Deinem refaktorisierten Code machst, setzt intern der SessionStateManager bzw. der SessionIDManager das Cookie-Handling um. Es nimmt also als Ausgangsbasis HttpRequest.Cookies und modifiziert es später über HttpResponse.Cookies. Möchte man nun den Session-Cookie selbst noch modifizieren, so bleibt einem nichts anderes übrig, als das über HttpRequest.Cookies zu tun - schließlich möchte man verhindern, das die internen Modifikationen von ASP.NET ausgelassen werden. Am Ende der ASP.NET Pipeline (genauer: zu ReleaseRequestState), wird dann der Cookie über HttpResonse.Cookies intern aktualisiert.

Des Weiteren finde ich die Argumentation, das ein Methodenname die Parameter der Methode reflektieren soll nicht gerade erstrebenswert. Würde man dies stringent umsetzen, hätte man schnell zum Einen ellenlange Methodennamen und zum Anderen würde man den Fokus von dem eigentlichen Zweck - dem &quot;was macht die Methode&quot; - ablenken und abweichen.

Die refaktorisierte Variante von Dir ist sehr schlüssig und übersichtlich. Die Fragestellung für mich ist es nun, welcher der zwei Code-Varianten lesbarer und übersichtlicher ist. Ich persönlich tendiere immer noch zu meinem gezeigten Beispiel - obwohl Deines, wie Du schon richtig anmerkst, eine bessere Separation of Concerns gewährleistet. Entscheidend ist für mich der Kosten/Nutzen-Effekt. Deine Variante ist in Relation zum Aufwand, den Du betreiben musstest, nicht sondernlich lesbarer oder einfacher - obwohl in objektorientiertem Sinne formal korrekter.

Bei der Entscheidung zur Refaktorisierung sollte man meiner Meinung mach nicht nur den Aspekt der Korrektheit in betracht ziehen, sondern andere Faktoren wie Einfachheit, Isolationsgrad und Chattiness beachten. Nichtsdestotrotz - ich finde Deine Variante äußerst elegant - wenngleich nicht lesbarer oder einfacher. Gerade Deine Refaktorisierungsbemühungen bestätigen meine Behauptung, das Kommentare per se kein Code Smell sind. Im Bestreben, den Kommentar überflüssig zu machen, hast Du meiner Meinung nach die Komplexität erhöht und die Lesbarkeit gemindert.

Dennoch gebe ich zu, das auch mein gezeigter Code (und der Kommentar) nicht gerade gelungen ist. Der Kommentar enthält die Falschaussage &quot;always synchronized&quot; - das ist schon mal ein dicker Minuspunkt. Es ist besser, einen Kommentar ganz wegzulassen, anstatt einen falschen Kommentar zu schreiben - Shame on me!

Des Weiteren würde ich an dem ersten Code-Beispiel die mangelnde Konvention in der Benennung der Methoden anmahnen. Während die Methode selbst &quot;ResetSessionCookieDomain&quot; heisst (IMHO korrekterweise), ist der Name der Methode zum Ermitteln des Cookienamens &quot;GetApplicationCookieName&quot; - aus meiner Sicht sollte das wohl eher zu &quot;GetSessionCookieName&quot; umbenannt werden.

Am liebsten würde ich jetzt das Code-Beispiel im Post korrigieren - ich lasse es dennoch so falsch wie es ist stehen, damit man auch unsere Kommentierungen nachvollziehen kann.

Gruß,
Ilker</description>
		<content:encoded><![CDATA[<p>Hi Tobi,</p>
<p>zunächst einmal: Good Code!</p>
<p>Da sieht man mal, wie wichtig es ist, gute Kommentare zu schreiben und diese auch richtig zu lesen. Fakt ist, das Du mit der &#8220;Synchronisation&#8221; von HttpRequest.Cookies und HttpResponse.Cookies recht hast &#8211; sie werden nicht synchronisiert. Allerdings scheint es mir hast Du den Kommentar falsch interpretiert &#8211; es geht nicht um die Erstellung eines neuen Cookies, sondern um die Modifikation.</p>
<p>Doch auch bei der Modifikation muss ich Dir natürlich recht geben &#8211; immer über HttpResponse.Cookies gehen! Ich behaupte jedoch weiterhin, das der gezeigte Code richtig ist. Wie kommt&#8217;s?</p>
<p>Tja, gerade das, was Du im Kommentar kritisierst ist wohl der entscheidende Hint: die Methode heisst &#8220;ResetSessionCookieDomain&#8221;. Soll heissen, die Methode setzt den Domain-Wert des Session-Cookies zurück. Man beachte auch, das der gesamte Code wie erwähnt in einem HttpModule abläuft. Die einzige wichtige Info, die ich nicht mitgegeben habe ist, das die Methode effektiv aufgerufen wird, nachdem der SessionState von der HttpRuntime erzeugt wurde (siehe AquireRequestState / ReleaseRequestState). **In genau diesem Kontext** ist es korrekt, den Session-Cookie über HttpRequest.Cookies zu verändern. Genau genommen ist sogar der Kommentar **in genau diesem Kontext** richtig &#8211; obwohl er wirklich irreführend ist.</p>
<p>Denn genau auf die selbe (richtige) Art und Weise, wie Du in Deinem refaktorisierten Code machst, setzt intern der SessionStateManager bzw. der SessionIDManager das Cookie-Handling um. Es nimmt also als Ausgangsbasis HttpRequest.Cookies und modifiziert es später über HttpResponse.Cookies. Möchte man nun den Session-Cookie selbst noch modifizieren, so bleibt einem nichts anderes übrig, als das über HttpRequest.Cookies zu tun &#8211; schließlich möchte man verhindern, das die internen Modifikationen von ASP.NET ausgelassen werden. Am Ende der ASP.NET Pipeline (genauer: zu ReleaseRequestState), wird dann der Cookie über HttpResonse.Cookies intern aktualisiert.</p>
<p>Des Weiteren finde ich die Argumentation, das ein Methodenname die Parameter der Methode reflektieren soll nicht gerade erstrebenswert. Würde man dies stringent umsetzen, hätte man schnell zum Einen ellenlange Methodennamen und zum Anderen würde man den Fokus von dem eigentlichen Zweck &#8211; dem &#8220;was macht die Methode&#8221; &#8211; ablenken und abweichen.</p>
<p>Die refaktorisierte Variante von Dir ist sehr schlüssig und übersichtlich. Die Fragestellung für mich ist es nun, welcher der zwei Code-Varianten lesbarer und übersichtlicher ist. Ich persönlich tendiere immer noch zu meinem gezeigten Beispiel &#8211; obwohl Deines, wie Du schon richtig anmerkst, eine bessere Separation of Concerns gewährleistet. Entscheidend ist für mich der Kosten/Nutzen-Effekt. Deine Variante ist in Relation zum Aufwand, den Du betreiben musstest, nicht sondernlich lesbarer oder einfacher &#8211; obwohl in objektorientiertem Sinne formal korrekter.</p>
<p>Bei der Entscheidung zur Refaktorisierung sollte man meiner Meinung mach nicht nur den Aspekt der Korrektheit in betracht ziehen, sondern andere Faktoren wie Einfachheit, Isolationsgrad und Chattiness beachten. Nichtsdestotrotz &#8211; ich finde Deine Variante äußerst elegant &#8211; wenngleich nicht lesbarer oder einfacher. Gerade Deine Refaktorisierungsbemühungen bestätigen meine Behauptung, das Kommentare per se kein Code Smell sind. Im Bestreben, den Kommentar überflüssig zu machen, hast Du meiner Meinung nach die Komplexität erhöht und die Lesbarkeit gemindert.</p>
<p>Dennoch gebe ich zu, das auch mein gezeigter Code (und der Kommentar) nicht gerade gelungen ist. Der Kommentar enthält die Falschaussage &#8220;always synchronized&#8221; &#8211; das ist schon mal ein dicker Minuspunkt. Es ist besser, einen Kommentar ganz wegzulassen, anstatt einen falschen Kommentar zu schreiben &#8211; Shame on me!</p>
<p>Des Weiteren würde ich an dem ersten Code-Beispiel die mangelnde Konvention in der Benennung der Methoden anmahnen. Während die Methode selbst &#8220;ResetSessionCookieDomain&#8221; heisst (IMHO korrekterweise), ist der Name der Methode zum Ermitteln des Cookienamens &#8220;GetApplicationCookieName&#8221; &#8211; aus meiner Sicht sollte das wohl eher zu &#8220;GetSessionCookieName&#8221; umbenannt werden.</p>
<p>Am liebsten würde ich jetzt das Code-Beispiel im Post korrigieren &#8211; ich lasse es dennoch so falsch wie es ist stehen, damit man auch unsere Kommentierungen nachvollziehen kann.</p>
<p>Gruß,<br />
Ilker</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Tobi</title>
		<link>http://ilker.de/comments-code-smell#comment-281</link>
		<dc:creator>Tobi</dc:creator>
		<pubDate>Thu, 20 Nov 2008 11:40:25 +0000</pubDate>
		<guid isPermaLink="false">http://www.gmbsg.com/stories/?p=202#comment-281</guid>
		<description>Hallo,

der Kommentar in Deinem Codebeispiel ist so entweder von mir falsch verstanden worden, oder sagt etwas aus, was nicht korrekt ist. Die Cookie Collections in Request und Response sind nicht synchronisiert. Ganz im Gegenteil. Der Unterschied zwischen den beiden Collections ist, dass im Request alle vom Client geschickte Cookies, plus transidiente Cookies vorgehalten werden und in Response ausschließlich neue Cookies vorgehalten werden, die im Response im Set-Cookie Header mitgesendet werden. Korrekt ist allerdings, dass Cookies, die über Response.Cookies.Add gesetzt werden anschließend zusätzlich in Request.Cookies auftauchen. Um den Unterschied noch weiter zu verdeutlichen: Cookies, die über Request.Cookies.Add hinzugefügt werden, sind sogenannte transidiente Cookies - das heißt, sie stehen der restlichen Verarbeitungskette zur Verfügung - werden allerdings anschließend NICHT an den Client gesendet. Man kann das verifizieren, indem man Request.Cookies.Add aufruft und dabei beobachten kann, dass Response.Cookies.AllKeys keine neuen Keys enthält.

Zusätzlich finde ich, dass Dein Codebeispiel gerade ein ideales Beispiel dafür ist, dass man hellhörig (= potential Code Smell) werden muss, wenn man das Bedürfnis hat einen Kommentar zu schreiben.

Ich sehe da durchaus Verbesserungspotential. Denn zum Beispiel passt die Methodensignatur nicht zum Methodennamen. Es ist im Methodennamen von Cookies die Rede - es wird allerdings eine HttpApplication übergeben. Das passt nicht zusammen. Zusätzlich wird in der Methode auf IsNewSession geprüft - davon steht ebenfalls nichts im Methodenname.

Ich hätte Dein Codebeispiel wie folgt refactored (ich hoffe mal, dass das formatiert bleibt):

&lt;pre name=&quot;code&quot; class=&quot;csharp&quot;&gt;
private void SetApplicationCookieDomainOnNewSession(HttpApplication application)
{
  string host = application.Request.Url.Host;
  if (application.Session.IsNewSession &amp;&amp; !application.Request.Url.IsLoopback)
  {
    CookieHandler cookieHandler = new CookieHandler(application);

    HttpCookie appCookie;
    if (cookieHandler.TryGetExistingCookie(this.GetApplicationCookieName(), out appCookie))
    {
      appCookie.Domain = this.GetCookieDomain();
    }
  }
}


public class CookieHandler
{
  public CookieHandler(HttpApplication application)
  {
    Application = application;
  }

  public HttpApplication Application { get; private set; }

  ///
  /// Tries to retrieve an existing cookie.
  ///
  /// The name of the cookie to get
  /// The cookie, if  is true, otherwise null
  /// True if a cookie was found, otherwise false.
  public bool TryGetExistingCookie(string cookieName, out HttpCookie appCookie)
  {
    try
    {
      HttpCookie cookie = Application.Request.Cookies[cookieName];
      if (cookie != null)
      {
        appCookie = cookie;
        return true;
      }
    }
    catch (Exception ex)
    {
      LOG.LogException(ex);
    }

    appCookie = null;
    return false;
  }
}
&lt;/pre&gt;

Bessere SoC. Man beachte auch, dass ich wenn es um Dokumentationskommentare geht absolut für Kommentare bin (Intellisense, API Doku, ...)

Trotzdem kann ich erstmal nur zustimmen: When you feel the need to write an (inline) comment, first try to refactor the code so that any comment becomes superfluous.

Denn das Refactoring hat zumindest in meinen Augen den inline(!) Kommentar ersetzt. Und wenn wir jetzt auch noch 3.5 einsetzen, dann können wir es noch sprechender gestalten:

&lt;pre name=&quot;code&quot; class=&quot;csharp&quot;&gt;
public void DieAufrufendeMethode(HttpApplication application)
{
  ExecuteOnIsNewSessionSafe(application,
    () =&gt;
    {
      CookieHandler cookieHandler = new CookieHandler(application);
      ResetApplicationCookieDomain(cookieHandler);
    }
    );
}

private void ResetApplicationCookieDomain(CookieHandler cookieHandler)
{
  HttpCookie appCookie;
  if (cookieHandler.TryGetExistingCookie(this.GetApplicationCookieName(), out appCookie))
  {
    appCookie.Domain = this.GetCookieDomain();
  }
}

private void ExecuteOnIsNewSessionSafe(HttpApplication application, Action action)
{
  if (application.Session.IsNewSession &amp;&amp; !application.Request.Url.IsLoopback)
  {
    action();
  }
}
&lt;/pre&gt;

Dann ist endlich das HttpApplication aus der Methodensignatur draußen. (DieAufrufendeMethode ist dabei die Methode wo vorher ResetSessionCookieDomain(HttpApplication application) aufgerufen wurde.)

Viele Grüße,
Tobi</description>
		<content:encoded><![CDATA[<p>Hallo,</p>
<p>der Kommentar in Deinem Codebeispiel ist so entweder von mir falsch verstanden worden, oder sagt etwas aus, was nicht korrekt ist. Die Cookie Collections in Request und Response sind nicht synchronisiert. Ganz im Gegenteil. Der Unterschied zwischen den beiden Collections ist, dass im Request alle vom Client geschickte Cookies, plus transidiente Cookies vorgehalten werden und in Response ausschließlich neue Cookies vorgehalten werden, die im Response im Set-Cookie Header mitgesendet werden. Korrekt ist allerdings, dass Cookies, die über Response.Cookies.Add gesetzt werden anschließend zusätzlich in Request.Cookies auftauchen. Um den Unterschied noch weiter zu verdeutlichen: Cookies, die über Request.Cookies.Add hinzugefügt werden, sind sogenannte transidiente Cookies &#8211; das heißt, sie stehen der restlichen Verarbeitungskette zur Verfügung &#8211; werden allerdings anschließend NICHT an den Client gesendet. Man kann das verifizieren, indem man Request.Cookies.Add aufruft und dabei beobachten kann, dass Response.Cookies.AllKeys keine neuen Keys enthält.</p>
<p>Zusätzlich finde ich, dass Dein Codebeispiel gerade ein ideales Beispiel dafür ist, dass man hellhörig (= potential Code Smell) werden muss, wenn man das Bedürfnis hat einen Kommentar zu schreiben.</p>
<p>Ich sehe da durchaus Verbesserungspotential. Denn zum Beispiel passt die Methodensignatur nicht zum Methodennamen. Es ist im Methodennamen von Cookies die Rede &#8211; es wird allerdings eine HttpApplication übergeben. Das passt nicht zusammen. Zusätzlich wird in der Methode auf IsNewSession geprüft &#8211; davon steht ebenfalls nichts im Methodenname.</p>
<p>Ich hätte Dein Codebeispiel wie folgt refactored (ich hoffe mal, dass das formatiert bleibt):</p>
<pre name="code" class="csharp">
private void SetApplicationCookieDomainOnNewSession(HttpApplication application)
{
  string host = application.Request.Url.Host;
  if (application.Session.IsNewSession &amp;&amp; !application.Request.Url.IsLoopback)
  {
    CookieHandler cookieHandler = new CookieHandler(application);

    HttpCookie appCookie;
    if (cookieHandler.TryGetExistingCookie(this.GetApplicationCookieName(), out appCookie))
    {
      appCookie.Domain = this.GetCookieDomain();
    }
  }
}

public class CookieHandler
{
  public CookieHandler(HttpApplication application)
  {
    Application = application;
  }

  public HttpApplication Application { get; private set; }

  ///
  /// Tries to retrieve an existing cookie.
  ///
  /// The name of the cookie to get
  /// The cookie, if  is true, otherwise null
  /// True if a cookie was found, otherwise false.
  public bool TryGetExistingCookie(string cookieName, out HttpCookie appCookie)
  {
    try
    {
      HttpCookie cookie = Application.Request.Cookies[cookieName];
      if (cookie != null)
      {
        appCookie = cookie;
        return true;
      }
    }
    catch (Exception ex)
    {
      LOG.LogException(ex);
    }

    appCookie = null;
    return false;
  }
}
</pre>
<p>Bessere SoC. Man beachte auch, dass ich wenn es um Dokumentationskommentare geht absolut für Kommentare bin (Intellisense, API Doku, &#8230;)</p>
<p>Trotzdem kann ich erstmal nur zustimmen: When you feel the need to write an (inline) comment, first try to refactor the code so that any comment becomes superfluous.</p>
<p>Denn das Refactoring hat zumindest in meinen Augen den inline(!) Kommentar ersetzt. Und wenn wir jetzt auch noch 3.5 einsetzen, dann können wir es noch sprechender gestalten:</p>
<pre name="code" class="csharp">
public void DieAufrufendeMethode(HttpApplication application)
{
  ExecuteOnIsNewSessionSafe(application,
    () =&gt;
    {
      CookieHandler cookieHandler = new CookieHandler(application);
      ResetApplicationCookieDomain(cookieHandler);
    }
    );
}

private void ResetApplicationCookieDomain(CookieHandler cookieHandler)
{
  HttpCookie appCookie;
  if (cookieHandler.TryGetExistingCookie(this.GetApplicationCookieName(), out appCookie))
  {
    appCookie.Domain = this.GetCookieDomain();
  }
}

private void ExecuteOnIsNewSessionSafe(HttpApplication application, Action action)
{
  if (application.Session.IsNewSession &amp;&amp; !application.Request.Url.IsLoopback)
  {
    action();
  }
}
</pre>
<p>Dann ist endlich das HttpApplication aus der Methodensignatur draußen. (DieAufrufendeMethode ist dabei die Methode wo vorher ResetSessionCookieDomain(HttpApplication application) aufgerufen wurde.)</p>
<p>Viele Grüße,<br />
Tobi</p>
]]></content:encoded>
	</item>
</channel>
</rss>

