In Java, le enumerazioni sono progettate per essere più che semplici costanti. I valori Enum sono oggetti (come quello che potresti instanciare da qualsiasi classe standard) ma con alcune restrizioni:
- Le istanze di un enum sono limitate da te: quando scrivi
enum Number {ONE, TWO, THREE;}
dici esplicitamente che le tre istanze sono le uniche a cui è permesso vivere
- Java si prende cura di instanciare le istanze dell'enum (quindi il costruttore deve essere
private
)
- Java genera anche una serie di metodi di supporto per aiutarti a utilizzare queste istanze di enum (
values()
, valueOf()
, ...)
Poiché sono oggetti e dal momento che gli oggetti hanno un comportamento, è perfettamente soddisfacente avere metodi in enumerazione.
Tuttavia, ho raramente affrontato un caso in cui ho finito per implementare qualcosa del genere. L'unica volta che lo faccio è quando ho un class
che conosco dai requisiti o dal dominio può avere solo un insieme noto di istanze . Esempio:
Norm A describe how a device counting energy should be identified.
Company X is working in energy domain and produces 3 devices that are separately identified according to norm A. Let's say that these
3 devices are identified as such:
- Device1 is from generation 1 and of type 1
- Device2 is from generation 2 and of type 2
- Device3 is from generation 2 and of type 1
I am mandated by Company X to create a software that manage data
extracted from these 3 devices.
Quindi questa potrebbe essere una potenziale classe che modella un dispositivo da Azienda X :
public final class CompanyXDevice {
private final int generation;
private final int deviceType;
public CompanyXDevice(int generation, int deviceType) {
this.generation = generation;
this.deviceType = deviceType;
}
public int[] generateHistoricalData() {
...
}
...
}
Tutto potrebbe funzionare perfettamente qui ... tranne che è possibile fare qualcosa del genere: new CompanyXDevice(3, 3);
che non dovrebbe essere consentito poiché CompanyX non ha tale dispositivo. Il prossimo passo è trovare un modo per limitare le possibilità di instanciazione. Questo può essere ottenuto (non solo) rifattorizzando un enum:
public enum CompanyXDevice {
DEVICE_1(1, 1),
DEVICE_2(2, 2),
DEVICE_3(2, 1);
private final int generation;
private final int deviceType;
private CompanyXDevice(int generation, int deviceType) {
this.generation = generation;
this.deviceType = deviceType;
}
public int[] generateHistoricalData() {
...
}
...
}
Ora è possibile giocare solo con dispositivi che riflettono realmente un dispositivo reale di Azienda X .