A Ovest Di Paperino

Welcome to the dark side.

Overengineering

Comincio a credere che quello di passare troppo tempo sul come migliorare una soluzione - laddove non sia strettamente necessario - stia diventando una piaga molto comune. In inglese hanno una sola parola, overengineering: un esempio [quasi] reale di quanto ho visto accadere può essere di aiuto.

Richiesta di implementare HelloWorld in C#. La prima versione:

/// <summary>
/// My hello world class
/// </summary>
public class HelloWorld
{
    static void Main(string[] args)
    {
        System.Console.WriteLine("hello world");
    }
}

Primo feedback: System.Console non è proprio standard. Meglio uno using statement. E ovviamente mancano i copyright.

/*
 * HelloWorld.cs
 * 
 * copyright PippoSoft corp. 2007
 * 
 * owner: Paolino Paperino
 * 
 * */
using System;

/// <summary>
/// My hello world class
/// </summary>
public class HelloWorld
{
    static void Main(string[] args)
    {
        Console.WriteLine("hello world");
    }
}

Secondo feedback: che succede se non vogliamo più scrivere alla console ma ad un'altra classe di tracing? Giusto:

/*
 * HelloWorld.cs
 * 
 * copyright PippoSoft corp. 2007
 * 
 * owner: Paolino Paperino
 * 
 * */
using System;

/// <summary>
/// Abstract trace writer
/// </summary>
public abstract class AbstractWriter
{
    public abstract void WriteLine(string line);
}

/// <summary>
/// Trace writer to Console
/// </summary>
public class ConsoleWriter : AbstractWriter
{
    public override void WriteLine(string line)
    {
        Console.WriteLine(line);
    }
}

/// <summary>
/// My hello world class
/// </summary>
public class HelloWorld
{
    static void Main(string[] args)
    {
        ConsoleWriter cw = new ConsoleWriter();
        cw.WriteLine("hello world");
    }
}

Terzo feedback: ma così facendo la stringa non è localizzabile. Ah vero!

/*
 * HelloWorld.cs
 * 
 * copyright PippoSoft corp. 2007
 * 
 * owner: Paolino Paperino
 * 
 * */
using System;

/// <summary>
/// Abstract trace writer
/// </summary>
public abstract class AbstractWriter
{
    public abstract void WriteLine(string line);
}

/// <summary>
/// Trace writer to Console
/// </summary>
public class ConsoleWriter : AbstractWriter
{
    public override void WriteLine(string line)
    {
        Console.WriteLine(line);
    }
}

public enum LocalizedStrings
{
    Error,
    HelloWorld
}

public class ResourceHelper
{
    public static string RetrieveResource(string xmlFileName, 
LocalizedStrings aLocalizedString) { // TODO: open the file // find the string return "Hello world"; } } /// <summary> /// My hello world class /// </summary> public class HelloWorld { static void Main(string[] args) { ConsoleWriter cw = new ConsoleWriter(); cw.WriteLine(ResourceHelper.RetrieveResource("myfilename.resx",
LocalizedStrings.HelloWorld)); } }

Quarto feedback. Ma se volessimo scrivere ad un server che ha una certa latenza? Meglio invertire il controllo tra Writer e codice che lo invoca. Un paio d'ore dopo:

/*
 * HelloWorld.cs
 * 
 * copyright PippoSoft corp. 2007
 * 
 * owner: Paolino Paperino
 * 
 * */
using System;

/// <summary>
/// Generic interface for all traceable stuff
/// </summary>
public interface ITraceable
{
    string ReturnTrace();
}

public enum LocalizedStrings
{
    Error,
    HelloWorld
}

public class ResourceHelper
{
    public static string RetrieveResource(string xmlFileName, 
LocalizedStrings aLocalizedString) { // open the file // find the string return "Hello world"; } } /// <summary> /// My ITraceable implementation /// </summary> public class MyTraceable : ITraceable { public string ReturnTrace() { return ResourceHelper.RetrieveResource("myfilename.resx",
LocalizedStrings.HelloWorld); } } /// <summary> /// Abstract trace writer /// </summary> public abstract class AbstractWriter { public abstract void WriteLine(); public abstract void SetTraceable(ITraceable myTraceable); } /// <summary> /// Trace writer to Console /// </summary> public class ConsoleWriter : AbstractWriter { ITraceable _mytrace = null; public override void WriteLine() { if (_mytrace == null) { throw new Exception("traceable not set"); } Console.WriteLine(_mytrace.ReturnTrace()); } public override void SetTraceable(ITraceable myTraceable) { this._mytrace = myTraceable; } } /// <summary> /// My hello world class /// </summary> public class HelloWorld { static void Main(string[] args) { MyTraceable mt = new MyTraceable(); ConsoleWriter cw = new ConsoleWriter(); cw.SetTraceable(mt); cw.WriteLine(); } }

Quinto feedback. Ma se non si riesce a instanziare una delle classi per OUT_OF_MEMORY? Quinta e ultima implementazione:

/// vaffanc **o; an this is not a pointer pointer!
public class HelloWorld { static void Main(string[] args) {
System.Console.WriteLine("hello world"); } }

Sì, perché il codice poi non lo debugga chi dà questi geniali suggerimenti, ma chi lo "scrive".

-quack

P.S. che ci crediate o no il codice compila e funziona come da specifiche in tutte le forme!