Chiến lược này liên quan đến việc thay thế những thứ như thế này:
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; }
}
Với:
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;
}
}
Tại sao chính xác điều này lại thích hợp hơn để làm cho kiểu liệt kê, như vậy:
public class Politician
{
public MostNotableGrievance MostNotableGrievance { get; set; }
}
public enum MostNotableGrievance
{
Infidelity = 0,
Embezzlement = 1,
FlipFlopping = 2,
Murder = 3,
BabyKissing = 4
}
Không có hành vi nào liên quan đến loại và nếu có, bạn sẽ sử dụng một loại tái cấu trúc khác, ví dụ: 'Thay thế Mã loại bằng các lớp con' + 'Thay thế có điều kiện bằng Đa hình'.
Tuy nhiên, tác giả giải thích lý do tại sao anh ta cau mày với phương pháp này (trong Java?):
Mã loại số, hoặc liệt kê, là một tính năng phổ biến của các ngôn ngữ dựa trên C. Với tên tượng trưng họ có thể khá dễ đọc. Vấn đề là tên tượng trưng chỉ là bí danh; trình biên dịch vẫn nhìn thấy số cơ bản. Kiểu trình biên dịch kiểm tra bằng cách sử dụng số 177 không phải là tên tượng trưng. Bất kỳ phương thức nào lấy mã loại làm đối số đều mong muốn một số và không có gì để buộc một tên tượng trưng được sử dụng. Điều này có thể làm giảm khả năng đọc và là một nguồn lỗi.
Nhưng khi cố gắng áp dụng tuyên bố này cho C #, tuyên bố này dường như không đúng: nó sẽ không chấp nhận một con số vì một phép liệt kê thực sự được coi là một lớp. Vậy đoạn mã sau:
public class Test
{
public void Do()
{
var temp = new Politician { MostNotableGrievance = 1 };
}
}
Sẽ không biên dịch. Vì vậy, việc tái cấu trúc này có thể được coi là không cần thiết trong các ngôn ngữ cấp cao mới hơn, như C #, hoặc tôi không xem xét điều gì?
var temp = new Politician { MostNotableGrievance = MostNotableGrievance.Embezzlement };