Come assicurarsi che il setter di ogni campo esegua un codice specifico?

4

Sto lavorando con Java 1.7, IDE è Eclipse Indigo.

Ho una classe base che ha id come int. Ha anche una variabile booleana onlyIdInitialized ; Lo imposto su true quando viene creato un oggetto con id .

public abstract class BaseBO {
   protected Boolean onlyIdInitialized = null;
   private int id;

   public BaseBO(int id) {
      this.id = id;
      onlyIdInitialized = true;
   }

   public int getId() {
      return id;
   }
   public void setId(Integer id) {
      this.id = id;
   }

   public Boolean isOnlyIdInitialized() {
      return onlyIdInitialized;
   }

}

Ora per ogni classe che eredita dalla classe precedente; Voglio che ognuno del metodo setter del proprio campo per impostare la variabile booleana onlyIdInitialized su falso i.e. onlyIdInitialized = false;

Potrei farlo in un modo grezzo e crudo, ad esempio:

public class Location extends BaseBO {
   private String description;
   private boolean active;

   public Location(int id) {
      super(id);
   }

   public String getDescription() {
      return description;
   }
   public void setDescription(String description) {
      this.description = description;
      this.onlyIdInitialized = false;
   }

   public boolean isActive() {
      return active;
   }
   public void setActive(boolean active) {
      this.active= active;
      this.onlyIdInitialized = false;
   }

}

Ma sarà un incubo da mantenere e non sembra buono. C'è una soluzione elegante a questo problema? Esiste un modello di progettazione che risolva questo problema?

UPDATE:

@ThomasJunk

Ho una classe Employee che ha un riferimento alla classe Location .

public class Employee extends BaseBO {
   private String employeeNumber;
   private Location location;

   public Employee(int id) {
      super(id);
   }

   public String getEmployeeNumber() { return employeeNumber; }
   public void setEmployeeNumber(String employeeNumber) { this.employeeNumber = employeeNumber; }
   public Location getLocation() { return location; }
   public void setLocation(Location location) { this.location = location; }
}

Ho già menzionato la classe Location sopra la quale ha 2 campi description e active oltre al campo id .

Quando l'oggetto Employee viene creato dal recupero di 1 riga della tabella dei dipendenti, ho solo il id della posizione interessata; Non ho il description e active della posizione interessata. Se anche il programma chiamante desidera accedere a description e active della posizione interessata, desidero sapere se i description e active della posizione interessata sono già stati recuperati: se sono già stati recuperati, solo dare il loro accesso; se non sono già stati recuperati, recuperarli prima e poi dare il loro accesso.

AGGIORNAMENTO 2:

@ThomasJunk @Laiv

Non sono sicuro che la mia domanda sia un lazy fetch di un oggetto (se ho capito bene). Nel mio caso l'oggetto location esiste già ma ha solo il campo id popolato. Ad esempio nel mio EmployeeDAO avrei questo metodo (psuedo-code):

public Employee getEmployeeById(int employeeId) throws SQLException {
   ResultSet resultSet = null;
   //...
   String employeeNumber = resultSet.getInt(2, 'employee_number');
   int locationId = resultSet.getInt(3, 'location_id');
   Location location = new Location(locationId);
   Employee employee = new Employee(employeeId);
   employee.setEmployeeNumber(employeeNumber);
   employee.setLocation(location);
   return employee;
} 

Ma l'oggetto posizione non ha altri campi description e active popolati, quindi non è corretto dire che il suo lazy fetch di altri campi di un oggetto ?

    
posta srh 16.07.2017 - 05:43
fonte

1 risposta

7

Puoi ottenerlo con il modello di modello di metodo , che rende il tuo codice "più elegante".

public abstract class BaseBO {
   private int id;

   public BaseBO(int id) {
      this.id = id;
   }

   public int getId() {
      return id;
   }
   public void setId(Integer id) {
      this.id = id;
   }
   protected boolean isOnlyIdInitialized() {
      return id != null && isEmpty();
   }
   abstract boolean isEmpty();
}

Le sottoclassi sarebbero simili a:

public class Location extends BaseBO {
   private String description;
   private boolean active;

   public Location(int id) {
      super(id);
   }

   public String getDescription() {
      return description;
   }
   public void setDescription(String description) {
      this.description = description;
   }

   public boolean isActive() {
      return active;
   }
   public void setActive(boolean active) {
      this.active= active;
    }

   boolean isEmpty() {
       return description == null && ... ;
   }        
}

Non prestare troppa attenzione al nome del metodo, non sapevo come chiamarlo.

Il punto è che la bandiera può essere valutata al volo perché dipende dal fatto che gli altri attributi siano nulli (o vuoti) o meno. 1

Modifica

Secondo i commenti e l'ultima modifica, sembra che tu stia implementando le inizializzazioni pigre . Si noti che la risposta sopra sta cercando di risolvere la domanda originale intorno a rendere il codice reale meno complicato. Ma, se la vera domanda è Come implementare le inizializzazioni pigre , la risposta è completamente diversa. Se così fosse, la domanda sarebbe francamente troppo ampia. Tuttavia, dai un'occhiata a Pattern proxy . Secondo me, si adatta meglio all'obiettivo generale. Per implementazioni più sofisticate Aspect Oriented Programming che possono essere implementate insieme al pattern Proxy.

1. Per le convalide contro null o vuoti, Apache commons lib è tuo amico

    
risposta data 16.07.2017 - 10:22
fonte