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!