0

I have many classes that retrieve databases objects. I have implemented their methods as static, so they can be called like this:

class xxxDB {
   public static method1(Connection dbcon) {
      //...
      method2(dbcon, ...);
   }
   public static method2(Connection dbcon, ....) {
      //...
   }
   // Other specific methods for xxx
}

I like the static methods solution, but it requires passing around the Connection object all the time to every method, and I don't find this particularly clear or elegant. So I have been evaluating different options for refactoring (and discarded the use of JPA, as I am not sure how to implement this in my specific weird database). One is to avoid static and use an immutable instance variable in each of the classes:

class xxxDB {
   private final Connection dbcon;

   public xxxDB(Connection dbcon) {
      this.dbcon = dbcon;
   }

   public static method1() {
      //...
      method2(...);
   }
   // Other specific methods for xxx
}

But this creates a lot of duplicated code. For each class, and I have quite a few, I have to duplicate the instance and the constructor. My idea would be to have a super class that can be extended by all the others:

class superDB {
   private final Connection dbcon;

   private superDB(){}

   public superDB(Connection dbcon) {
      this.dbcon = dbcon;
   }
}

But this still forces me to repeat this code in every class:

   public xxxDB(Connection dbcon) {
      this.dbcon = dbcon; // or super(dbcon);
   }

My questions are:

  1. Is it really a good idea to refactor the static methods that access the database?
  2. Is there a way/pattern for my classes to inherit the "one arg constructor" of the super class? Something like:

.

class superDB {
   private final Connection dbcon;

   private superDB(){}

   public superDB(Connection dbcon) {
      this.dbcon = dbcon;
   }
}

class xxxDB extends superDB {
   // no need to add duplicated code to call the super
   public static method1() {
      //...
   }
   // Other specific methods for xxx
}
user1156544
  • 109
  • 3
  • 1
    Possible duplicate of [Staying OO and Testable while working with a database](https://softwareengineering.stackexchange.com/questions/42792/staying-oo-and-testable-while-working-with-a-database) – gnat Apr 05 '18 at 13:59
  • Personally, I like using code generator scripts when the language doesn't allow for completely eliminating repetitive code. – isaach1000 Apr 05 '18 at 14:07
  • OT: And why not use something like http://projects.spring.io/spring-data/#quick-start ? – Thomas Junk Apr 05 '18 at 14:35
  • I am not sure why the "possible duplicate" answers my questions (one of them is very Java specific I believe). The link exposes general patterns, but no direct answer to either my questions. Actually, forget about database access, think of them as classes that provide a service – user1156544 Apr 05 '18 at 14:36
  • Thanks for the suggestion, but I don't like Spring – user1156544 Apr 05 '18 at 14:37
  • Child classes with `super(dbcon)` in every constructor is in my opinion the best solution (unless you try code generation). This is just 1 duplicate line per class, you shouldn't be afraid of that – Joel Apr 05 '18 at 20:52
  • Perhaps you are right and that is the best option. But I don't like repeating so much code in all my classes... However it seems there is no other option here! So your answer would be 1) not really 2) not really, so go for the super() option and accept (this small) duplication – user1156544 Apr 08 '18 at 15:05

1 Answers1

1

Why you want keep the static access? If you going with instances of the child classes you could create a super class with a getter and setter for the connection:

class superDB {
   protected Connection dbcon;

   public getDbcon() {
      return this.dbcon;
   }

   public setDbcon(Connection dbcon) {
      this.dbcon = dbcon;
   }
}

You child classes inherit from the super class and when you instance your childs you can set the connection via setDbcon.

To keep your access lazy you could create a singleton which provide the different instances of your db classes. Your singleton init method could look like this:

superDB[] cons;
public init(Connection dbCon){
 this.cons = new superDB[2];
 this.cons[0] = new XXX();
 this.cons[1] = new YYY();

 foreach(superDB db in this.cons){
   db.setDbcon(dbCon);
 }
}
enno.void
  • 131
  • 4
  • I don't want a singleton (I would need to implement synchronisation). And I think it is better idea to have `dbcon` immutable – user1156544 Apr 08 '18 at 15:02
  • By the way, I think the last code you wrote is a bad idea. First because you cannot achieve concurrency - the connection should be different each time. Second, because it breaks OO... and also it will be a mess to call specific methods on XXX or YYY if you have to recover them from the array. – user1156544 Apr 10 '18 at 08:46