Verifica della presenza di proprietà facoltative di un oggetto

1

Sto progettando una classe che contiene diversi tipi di dati. Alcune delle proprietà sono facoltative. Ad esempio, supponiamo di avere una classe che rappresenta una persona e una delle proprietà è l'occupazione. Ho un'altra proprietà, grado militare, ma questa proprietà può essere recuperata solo se l'occupazione della persona è militare. Qual è il modo migliore per gestirlo?

  1. Avere getMilitaryRank() gettare IllegalStateException se l'occupazione non è militare
  2. ha getMilitaryRank() restituisce un Optional<Rank>
  3. Restituisce null se l'occupazione non è valida (non mi piacciono i valori null)
  4. Qualcos'altro?

L'idea 1 funziona perché l'utente può controllare l'occupazione prima di chiamare questo metodo, assicurandosi che non lo chiamino su una persona non valida.

L'idea 2 sembra superflua, perché puoi dedurre se l'opzione è presente chiamando getOccupation() .

Tuttavia, supponiamo che la mia classe Person abbia un'altra proprietà opzionale, ma la sua presenza non può essere dedotta dal valore di un'altra proprietà; per esempio, un secondo nome. Ovviamente è meglio che getMiddleName() restituisca un Optional o null vuoto se la persona non ha un secondo nome, in quanto la presenza di un secondo nome non può in realtà essere dedotta in altro modo.

Poiché probabilmente dovrei essere coerente nel modo in cui gestisco le proprietà facoltative, sembra che potrei svolgere una delle seguenti operazioni:

  1. Utilizza Optional per qualsiasi proprietà che potrebbe essere assente, anche se può essere dedotta da un'altra proprietà.
  2. Aggiungi metodi come hasMiddleName() per risolvere le discrepanze (questa sembra una cattiva idea)
  3. Non essere coerente e lasciare che le proprietà la cui presenza possa essere determinata esternamente generino un'eccezione, mentre quelle indipendenti siano racchiuse in un Optional .
  4. Qualcos'altro?

Mentre i null possono semplificare le cose, causa un problema se una proprietà opzionale è un int , che non può essere annullabile in Java. Potrei usare Integer , ma mi sembra una cattiva idea.

Qual è il modo migliore per gestire questi diversi tipi di proprietà facoltative?

    
posta codebreaker 23.04.2014 - 23:40
fonte

3 risposte

2

Esistono due soluzioni, a seconda delle specifiche del tuo problema. Se queste proprietà facoltative sono combinate solo in un numero relativamente ridotto di modi, puoi utilizzare un sum type per distinguerli. Il vantaggio di questo approccio è che puoi garantire esaustività: puoi garantire staticamente che, ovunque sia necessario prendere una decisione in base al tipo di persona, tutti i tipi sono gestiti in qualche modo.

L'altra soluzione consiste nel raggruppare le proprietà facoltative che si verificano sempre insieme nelle interfacce e quindi implementare le interfacce che è possibile supportare in ogni classe. Puoi rilevare le particolari interfacce supportate da una persona applicando instanceof e quindi casting. Questo approccio non ti costringerà ad aggiornare tutti i siti di utilizzo quando aggiungi una nuova interfaccia, ma funziona meglio quando il numero di combinazioni possibili di proprietà facoltative è molto grande. Per esempio. se ci sono 7 gruppi di proprietà facoltative, ci sono 127 modi per combinare questi gruppi in classi, e sarebbe ridicolo prendere una decisione in base a ciascuna combinazione possibile. Se è necessario riutilizzare le implementazioni di tali interfacce, utilizzare la composizione.

A parte questo, fai attenzione a fare ipotesi sui nomi delle persone .

    
risposta data 24.04.2014 - 02:50
fonte
1

Mi piace l'idea di ereditarietà di DFord ... estendendo la classe Person ... Ecco alcune idee aggiuntive da considerare ...

public class Person {

  private String middelName;
  private String occupation;

  public String getMiddleName() {
      if (middleName == null) {
         return ""; // or any default value
      } else {
         return middleName;
      }
  }

  public String getOccupation() {
     if (occupation == null) {
         return "Unknown";
     } else {
         return occupation;
     }
  }

  public class Military extends Person {
     String rank;
     public String getMilitaryRank() {
        return rank;
     }
  }

.... quindi nel codice da qualche parte ...

if (person instanceof Military) {
   String rank = person.getMilitaryRank();
}

Un'altra idea è creare un enum per l'occupazione e restituire il valore predefinito dell'occupazione se non è impostato nulla, invece di "sconosciuto". A volte il controllo di valori specifici come il testo "sconosciuto" può aggiungere ulteriore complessità.

 if (occupation == null) {
    return Occupation.UNKNOWN;
 } else {
    return occupation;
 }

... un'opzione migliore è inizializzare tutte le variabili nel costruttore

public class Person {
    public Person() {
       middleName = "";
       occupation = Occupation.UNKNOWN;
    }

    public Occupation getOccupation() {
       return occupation;
    }

    public String getMiddleName() {
       return middleName;
    }
    
risposta data 24.04.2014 - 00:56
fonte
-1

Perché non creare una sottoclasse che rappresenti qualcuno nell'esercito e che erediti dalla tua classe genitrice. In questo modo, puoi verificare il tipo di classe dell'oggetto. Se è la classe Military, puoi chiamare getMilitaryRank() .

Puoi quindi creare classi aggiuntive per altre situazioni simili a questa.

    
risposta data 24.04.2014 - 00:05
fonte

Leggi altre domande sui tag