enum A {a,b,c}
enum B extends A {d}
/*B is {a,b,c,d}*/
può essere scritto come:
public enum All {
a (ClassGroup.A,ClassGroup.B),
b (ClassGroup.A,ClassGroup.B),
c (ClassGroup.A,ClassGroup.B),
d (ClassGroup.B)
...
- ClassGroup.B.getMembers () contiene {a, b, c, d}
Come può essere utile: diciamo che vogliamo qualcosa di simile: abbiamo eventi e stiamo usando enum. Tali enumerazioni possono essere raggruppate mediante elaborazioni simili. Se abbiamo un'operazione con molti elementi, alcuni eventi iniziano a funzionare, alcuni sono solo step e altri terminano l'operazione. Per raccogliere tale operazione ed evitare una lunga commutazione, possiamo raggrupparli come nell'esempio e usare:
if(myEvent.is(State_StatusGroup.START)) makeNewOperationObject()..
if(myEnum.is(State_StatusGroup.STEP)) makeSomeSeriousChanges()..
if(myEnum.is(State_StatusGroup.FINISH)) closeTransactionOrSomething()..
Esempio:
public enum AtmOperationStatus {
STARTED_BY_SERVER (State_StatusGroup.START),
SUCCESS (State_StatusGroup.FINISH),
FAIL_TOKEN_TIMEOUT (State_StatusGroup.FAIL,
State_StatusGroup.FINISH),
FAIL_NOT_COMPLETE (State_StatusGroup.FAIL,
State_StatusGroup.STEP),
FAIL_UNKNOWN (State_StatusGroup.FAIL,
State_StatusGroup.FINISH),
(...)
private AtmOperationStatus(StatusGroupInterface ... pList){
for (StatusGroupInterface group : pList){
group.addMember(this);
}
}
public boolean is(StatusGroupInterface with){
for (AtmOperationStatus eT : with.getMembers()){
if( eT .equals(this)) return true;
}
return false;
}
// Each group must implement this interface
private interface StatusGroupInterface{
EnumSet<AtmOperationStatus> getMembers();
void addMember(AtmOperationStatus pE);
}
// DEFINING GROUPS
public enum State_StatusGroup implements StatusGroupInterface{
START, STEP, FAIL, FINISH;
private List<AtmOperationStatus> members = new LinkedList<AtmOperationStatus>();
@Override
public EnumSet<AtmOperationStatus> getMembers() {
return EnumSet.copyOf(members);
}
@Override
public void addMember(AtmOperationStatus pE) {
members.add(pE);
}
static { // forcing initiation of dependent enum
try {
Class.forName(AtmOperationStatus.class.getName());
} catch (ClassNotFoundException ex) {
throw new RuntimeException("Class AtmEventType not found", ex);
}
}
}
}
//Some use of upper code:
if (p.getStatus().is(AtmOperationStatus.State_StatusGroup.FINISH)) {
//do something
}else if (p.getStatus().is(AtmOperationStatus.State_StatusGroup.START)) {
//do something
}
Aggiungi alcuni più avanzati:
public enum AtmEventType {
USER_DEPOSIT (Status_EventsGroup.WITH_STATUS,
Authorization_EventsGroup.USER_AUTHORIZED,
ChangedMoneyAccountState_EventsGroup.CHANGED,
OperationType_EventsGroup.DEPOSIT,
ApplyTo_EventsGroup.CHANNEL),
SERVICE_DEPOSIT (Status_EventsGroup.WITH_STATUS,
Authorization_EventsGroup.TERMINAL_AUTHORIZATION,
ChangedMoneyAccountState_EventsGroup.CHANGED,
OperationType_EventsGroup.DEPOSIT,
ApplyTo_EventsGroup.CHANNEL),
DEVICE_MALFUNCTION (Status_EventsGroup.WITHOUT_STATUS,
Authorization_EventsGroup.TERMINAL_AUTHORIZATION,
ChangedMoneyAccountState_EventsGroup.DID_NOT_CHANGED,
ApplyTo_EventsGroup.DEVICE),
CONFIGURATION_4_C_CHANGED(Status_EventsGroup.WITHOUT_STATUS,
ApplyTo_EventsGroup.TERMINAL,
ChangedMoneyAccountState_EventsGroup.DID_NOT_CHANGED),
(...)
In precedenza, se si verificano errori (myEvent.is (State_StatusGroup.FAIL)), durante l'iterazione di eventi precedenti, è possibile verificare facilmente se è necessario ripristinare il trasferimento di denaro tramite:
if(myEvent2.is(ChangedMoneyAccountState_EventsGroup.CHANGED)) rollBack()..
Può essere utile per:
- compresi i metadati espliciti sulla logica di elaborazione, meno da ricordare
- implementando parte dell'ereditarietà multipla
- non vogliamo usare le strutture di classe, ad es. per l'invio di brevi messaggi di stato