4

I am working with Java 1.7, IDE is Eclipse Indigo.

I have a base class which has id as an int. It also has a boolean variable onlyIdInitialized; I am setting it to true when an object is created with 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;
   }

}

Now for each class which inherits from the above class; I want each of their field's setter method to set boolean variable onlyIdInitialized to false i.e. onlyIdInitialized = false;

I could do that in a crude and raw way for example:

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;
   }

}

But it will be a nightmare to maintain and looks not good. Is there an elegant solution to this problem? Is there a design pattern which solves this problem?

UPDATE:

@ThomasJunk

I have a class Employee which has a reference to class 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; }
}

I have already mentioned the Location class above which has 2 fields description and active in addition to id field.

When Employee object is build from retrieve of 1 row of employee table, I only have the id of the concerned location; I dont have the description and active of the concerned location. If the calling program also want to access the description and active of the concerned location then I want a way to know that if the description and active of the concerned location are already retrieved: if already retrieved then just give their access; if not already retrieved then retrieved them first and then give their access.

UPDATE 2:

@ThomasJunk @Laiv

I am not sure my question is a lazy fetch of an object (if I understand it correctly). In my case the location object would already exist but it only has id field populated. For example in my EmployeeDAO I would have this method (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;
} 

But the location object does not have other fields description and active populated so is it not correct to say that its lazy fetch of other fields of an object?

  • Why would it be a nightmare to maintain? – Tulains Córdova Jul 16 '17 at 3:51
  • 3
    Could you provide a less contrived example of what you are trying to accomplish? This code does not seem to reveal your actual intent. I see no reason to do what you are doing. – Thomas Junk Jul 16 '17 at 9:33
  • 1
    @TulainsCórdova Every developer has to remember that for each field of each subclass of BaseBO, the same code is included in the setter method. Thats why I think it would be nightmare to maintain. – srh Jul 16 '17 at 11:47
  • @ThomasJunk I want to check if only id is populated or other fields are also populated of each subclass. I forgot to add a method in BaseBO which I have added now: public Boolean isOnlyIdInitialized() { return onlyIdInitialized; } – srh Jul 16 '17 at 11:55
  • 1
    @ThomasJunk I updated the OP to explain what is my motive – srh Jul 16 '17 at 15:23
7

You can achieve it with method template pattern, which makes your code "more elegant".

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();
}

Subclasses would look similar to:

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 && ... ;
   }        
}

Don't pay too much attention to the method's name, I didn't know how to name it.

The point is, the flag can be evaluated on the fly because it depends on whether the other attributes are null (or empty) or not. 1


Edit:

According to the comments and the last edit, looks like you are implementing lazy initializations. Note that the answer above is trying to solve the original question around making the actual code less convoluted. But, if the real question is How to implement lazy initializations, the answer is totally different. If that were the case, the question would be frankly too broad. Nevertheless, take a look on Proxy pattern. In my opinion, fits better with the overall goal. For more sophisticated implementations Aspect Oriented Programming which can be implemented alongside with Proxy pattern.


1. For validations against null or empties, Apache commons lib is your friend

  • 2
    As I suspected, it is an XY-Problem. And I suggest to accept this answer. – Thomas Junk Jul 17 '17 at 1:27
  • @Laiv I like the example you gave but is it possible that isEmpty() method of BaseBO class is not abstract and instead dynamically go through all the fields of the class and evaluate the same expression something like return field1 == null && field2 == null && ... fieldn == null? This way I dont have to define isEmpty() method in sub classes. Example: in Location class the isEmpty() method will evaluate to return description == null && active == null. – srh Jul 17 '17 at 20:26
  • Maybe via reflection you can. But putting code on the parent "to spy" children don't seems good design to me. Despite your doubts, typing the conditions explictly in each subclass, makes your code cleaner , simpler and readable. – Laiv Jul 17 '17 at 20:34
  • Take a look here – Laiv Jul 17 '17 at 20:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.