Apri principio chiuso contro perdita di astrazione (enumerazione Java)

1

In Java, un enum non è un semplice sostituto di un numero (come in C / C ++), ma una famiglia di oggetti che possono avere proprietà. Ad esempio

public enum Order {
  NAME("Ordering by name"),
  SURNAME("Ordering by surname");

  private String comment;

  private Order(String comment) {
    this.comment = comment;
  }

  public String getComment() {
    return this.comment;
  }
}

E poi, potrei fare:

System.out.println(Order.NAME.getComment());

Ora, immagina di definire un'API come:

public interface MyApi {
  public List<People> getAllPeople(Order order);
}

Posso fare diverse cose nell'implementazione:

  • Un passaggio con enum, che definisce la clausola ORDER BY come necessario per ciascun valore.

  • Aggiungi un nuovo parametro all'enumerazione:

    • un esempio estremo sarebbe, con SQL, NAME("Ordering by Name", " ORDER BY peo_name") 1 , e basta fare

      if (order! = null) {sql + = order.getOrderClause (); }

    • Usando JPA, userei la proprietà e non il nome della colonna, quindi potrei fare 'NOME ("Ordinamento per nome", "nome") 2 e fare

      if (order! = null) {jpql +="ORDER BY p." + order.getOrderAttribute (); }

Sul lato positivo, trovo il modo più semplice per implementare il principio Open / Closed (se aggiungo un nuovo criterio di ordinamento, devo solo aggiungere la rispettiva istanza enum). In modo meno positivo, espongo i dettagli interni del mio server al client (sebbene il client non sia in grado di "iniettare" un valore diverso per trarne profitto).

Che tipo di problemi posso aspettarmi da questa violazione dell'astrazione? Ne vale la pena la semplicità della codifica? C'è qualche modo, in modo spiacevole, 3 per migliorare questo design (quello JPA)?

1 peo_name è il nome della colonna nel DB.

2 name sarebbe un attributo di People , ovvero esiste un metodo getName() in People .

3 Un'alternativa che posso pensare sarebbe utilizzare un nuovo enum, Order2 , come parte dell'API, quindi collegare ogni istanza di tale enum a un'istanza di Order , ma penso che sia complicato e in qualche modo infrange il principio di apertura / chiusura (per aggiungere un criterio di ordinamento avrei bisogno di modificare sia Order che Order2 ).

    
posta SJuan76 06.02.2015 - 11:41
fonte

1 risposta

2

Le perdite di astrazione sono un problema solo nella misura in cui i chiamanti possono fare affidamento su interni non documentati e si interrompono misteriosamente quando si cambiano quelli interni. Ad esempio (dal momento che stiamo parlando di ordinamento), se restituisci un elenco di cose e accade che venga sempre ordinato, i chiamanti potrebbero presumere che questo è parte del contratto e interrompere se si reimplementa il metodo in un modo diverso. / p>

In questo caso, la perdita è un problema nella misura in cui i chiamanti si aspetteranno il particolare valore che il metodo aggiuntivo restituisce e dipende da esso. Mi sembra improbabile, ma probabilmente conosci i tuoi utenti meglio di noi, quindi è una tua richiesta. In generale, mi piacciono molto i metodi di utilità in enum s, proprio per i motivi che offri.

    
risposta data 06.02.2015 - 11:59
fonte

Leggi altre domande sui tag