Questa strategia prevede la sostituzione di simili:
public class Politician
{
public const int Infidelity = 0;
public const int Embezzlement = 1;
public const int FlipFlopping = 2;
public const int Murder = 3;
public const int BabyKissing = 4;
public int MostNotableGrievance { get; set; }
}
Con:
public class Politician
{
public MostNotableGrievance MostNotableGrievance { get; set; }
}
public class MostNotableGrievance
{
public static readonly MostNotableGrievance Infidelity = new MostNotableGrievance(0);
public static readonly MostNotableGrievance Embezzlement = new MostNotableGrievance(1);
public static readonly MostNotableGrievance FlipFlopping = new MostNotableGrievance(2);
public static readonly MostNotableGrievance Murder = new MostNotableGrievance(3);
public static readonly MostNotableGrievance BabyKissing = new MostNotableGrievance(4);
public int Code { get; private set; }
private MostNotableGrievance(int code)
{
Code = code;
}
}
Perché è esattamente preferibile fare questo tipo di enumerazione, in questo modo:
public class Politician
{
public MostNotableGrievance MostNotableGrievance { get; set; }
}
public enum MostNotableGrievance
{
Infidelity = 0,
Embezzlement = 1,
FlipFlopping = 2,
Murder = 3,
BabyKissing = 4
}
Non esiste alcun comportamento associato al tipo e se esistesse si utilizzerebbe comunque un diverso tipo di refactoring, ad esempio "Sostituisci il codice del tipo con sottoclassi" + "Sostituisci condizionale con polimorfismo".
Tuttavia, l'autore spiega perché aggrotta le sopracciglia su questo metodo (in Java?):
I codici numerici o le enumerazioni sono una caratteristica comune dei linguaggi basati su C. Con nomi simbolici possono essere abbastanza leggibili. Il problema è che il nome simbolico è solo un alias; il compilatore vede ancora il numero sottostante. Il tipo di compilatore controlla usando il numero 177 non il nome simbolico. Qualsiasi metodo che prende il codice del tipo come argomento si aspetta un numero e non c'è nulla per forzare l'uso di un nome simbolico. Ciò può ridurre la leggibilità ed essere fonte di bug.
Ma quando si tenta di applicare questa affermazione a C #, questa affermazione non sembra vera: non accetterà un numero perché un'enumerazione è in realtà considerata una classe. Quindi il seguente codice:
public class Test
{
public void Do()
{
var temp = new Politician { MostNotableGrievance = 1 };
}
}
Non compilerà. Quindi questo refactoring può essere considerato non necessario in linguaggi di alto livello più recenti, come C #, o non sto prendendo in considerazione qualcosa?
var temp = new Politician { MostNotableGrievance = MostNotableGrievance.Embezzlement };