Indecent Exposure: Encapsulate Classes with Factory

Continuiamo con lo smell: Indecent Exposure

 

Problema:

Il client istanzia direttamente un oggetto che risiede in una libreria.

 

Motivazione:

Durante la realizzazione di una libreria, si potrebbe cadere nella tentazione di creare delle classi che istanziano oggetti di cui il client necessita.

Un esempio di logica errata:

smell_Indecent_Exposure

Ciò significa dare al client la responsabilità di conoscere tutti gli oggetti presenti nella nostra libreria.

 class Program
{
static void Main(string[] args)
{
List<AttributeDescriptor> lstAttDesc = new List<AttributeDescriptor>();
lstAttDesc.Add(new BooleanDescriptor("boolean"));
lstAttDesc.Add(new DefaultDescriptor("primo", typeof(string), 10));
lstAttDesc.Add(new ReferenceDescriptor("secondo", typeof(MiaClasse), sizeof(MiaClasse)));
// ...
}
}

public abstract class AttributeDescriptor
{
protected AttributeDescriptor()
{
// ...
}
}

public class BooleanDescriptor : AttributeDescriptor
{
public BooleanDescriptor(string name)
: base()
{
// ...
}
}

public class DefaultDescriptor : AttributeDescriptor
{
public DefaultDescriptor(string name, Type t, long length)
: base()
{
// ...
}
}

public class ReferenceDescriptor : AttributeDescriptor
{
public ReferenceDescriptor(string name, Type t, long length)
: base()
{
// ...
}
}
 

 

E ciò è un male == smells.


Soluzione:

Tenendo presente la regola: far lavorare il client tramite interfacce e non tramite oggetti.

Ne consegue che, quanto sopra, si potrebbe risolvere con un Factory pattern:

 class Program
{
static void Main(string[] args)
{
List<AttributeDescriptor> lstAttDesc = new List<AttributeDescriptor>();
lstAttDesc.Add(AttributeDescriptor.CreateBoolean("boolean"));
lstAttDesc.Add(AttributeDescriptor.CreateDefault("primo", 10));
lstAttDesc.Add(AttributeDescriptor.CreateReference("secondo", typeof(MiaClasse), sizeof(MiaClasse)));
// ...
}
}

public abstract class AttributeDescriptor
{
protected AttributeDescriptor()
{
// ...
}

public static AttributeDescriptor CreateBoolean(string name)
{
return new BooleanDescriptor(name);
}

public static AttributeDescriptor CreateDefault(string name, long length)
{
return new DefaultDescriptor(name, typeof(string), length);
}

public static AttributeDescriptor CreateReference(string name, Type t, long length)
{
return new ReferenceDescriptor(name, t, length);
}
}

public class BooleanDescriptor : AttributeDescriptor
{
public BooleanDescriptor(string name)
{
// ...
}
}

public class DefaultDescriptor : AttributeDescriptor
{
public DefaultDescriptor(string name, Type t, long length)
{
// ...
}
}

public class ReferenceDescriptor : AttributeDescriptor
{
public ReferenceDescriptor(string name, Type t, long length)
{
// ...
}
}

 

Questa è una possibile soluzione

Da notare che classi BooleanDescriptor, DefaultDescriptor e ReferenceDescriptor, dopo il Refactoring, il client non ha nessun bisogno di sapere come queste sono implementate e possono risiedere in qualsiasi dll, il client avrà solamente bisogno di referenziare la classe AttributeDescriptor

refactored

Benefici e non
+ Semplifica la creazione delle istanze degli oggetti.
+ Allegerisce la conoscenza da parte del client delle classi e della loro implementazione.
+ Mantiene viva la regola sull’utilizzo delle interfacce.
- Bisogna creare un metodo Create per ogni oggetto.
- Limita le customizzazioni da parte del client perchè può accedere solo all’interfaccia.

 

E non prendete come scusa: “il mio sistema ormai è troppo evoluto per poterne apportare queste migliorie. E’ troppo tardi.”

Se fosse realmente così non esisterebbe il Refactoring :)

Per questi post sto prendendo, molto, spunto da libro Refactoring To Patterns di Joshua Kerievsky.

posted @ giovedì 30 aprile 2009 02:37

Print

Comments on this entry:

# 

Left by BitVector at 15/10/2009 12:03
Gravatar
Duplicated Code: Introduce Polymorphic Creation with Factory Method

# re: Indecent Exposure: Encapsulate Classes with Factory

Left by jifenoded at 05/09/2018 02:03
Gravatar
In the satisfied customers will give you the positive feedback and the negative customers obviously www.lowes.com/survey will give you the negative comments.
Comments have been closed on this topic.