1

I'm getting my feet wet with Android app development and tying to find a good way to manage database interactions across multiple similar objects. My goal was to have a structure like:

public abstract class DatabaseObject{

    public static abstract String getTableName();
    public static abstract SQLiteDatabase getDB();
    public static void dropTable(){
        getDB().execSQL("DROP TABLE IF EXISTS " + getTableName());
    }
}

public class Book extends DatabaseObject{

    public static final String TABLE_NAME = "book";
    private String author;
    private static SQLiteDatabase _db;

    public static setDB(SQLiteDatabase db){
        _db = db;
    }

    @Override
    public static String getTableName(){
        return TABLE_NAME;
    }

    @Override
    public static SQLiteDatabase getDB(){
        return _db;
    }

    public String getAuthor(){
        return author;
    }

    public void getAuthor(String auth){
        author = auth;
    }
}

Lately I've been working on a project that uses Hibernate, so I'm used to having a class that can be used throughout the application and also contains the ability to persist its data to the database. Unfortunately, "static abstract" isn't allowed in Java, so this wouldn't work.

My current plan is to have each of the classes like "Book" that I plan to use implement an interface and have an external class handle the common db interactions instead of the ancestor class.

Is there a better way to accomplish what I'm trying to do?

  • 1
    Maybe what you're looking for is the Template Method pattern? – RibaldEddie Aug 26 '15 at 0:55
  • @RibaldEddie, I don't think so based on what I found when I looked that up, but can you elaborate a little more please? – mowwwalker Aug 26 '15 at 5:13
1

I think you can adapt the visitor pattern for your requirement.

Your Book class should implement an interface, typically named Visitable.

public interface Visitable{
  public void accept(Visitor visitor);
}

Now, to your book class you pass in a visitor which performs the necessary operations. Implement this method in book class.

public class Book implements Visitable{
  public void accept(Visitor visitor){
    visitor.visit(this);
  }
}

Now, let's check the visitor part. If your set of actions are going to be common for all entities, implement a generic visitor.

public interface Visitor{
  public void visit(DatabaseObject dbo);
}

Let's look at the visitor itself now.

public class DBOVisitor implements Visitor{
  public void visit(DatabaseObject dbo){
    String tableName = dbo.getTableName();
    String tableDropSQL = "DROP TABLE "+tableName;
    getDB().execSQL(tableDropSQL);
  }
}

I hope you get the idea of it. Feel free to adapt it. Add specific methods if you want and as always, name the methods meaningfully. Hope this helps!

0

This would work if you dropped all the statics from the base class, and the abstract from the method with an implementation. Think of how the methods would be called by clients: either aBook.dropTable() or Book.dropTable() makes sense, but DatabaseObject.dropTable() doesn't; which table did you want dropped?

Doubtless there are better ways to do things, e.g. http://developer.android.com/training/basics/data-storage/databases.html.

  • That doesn't really make sense. You say [drop] abstract from the method with an implementation, but, by definition, a method with an implementation wouldn't have the abstract tag. The methods need to be static because Book.dropTable() is independent of any instance of book, but relevant to the books as a whole. – mowwwalker Aug 25 '15 at 23:35
  • A method with an implementation shouldn't have the abstract tag, but your code does. That's why you need to get rid of it. – soru Aug 25 '15 at 23:41
  • I didn't mean to add "abstract" to the dropTable method, but that wasn't the main problem here – mowwwalker Aug 25 '15 at 23:43
  • in your code: public static abstract void dropTable { /* implementation */ } – soru Aug 25 '15 at 23:44
0

Easy.

  • Pass the table name from Book (and all other concrete classes) into a constructor of the abstract class.
  • Store the table name in the abstract class and use it directly where needed.
  • Remove the getTableName method

Sorry my answer is so brief, I'm editing in the mobile app.

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.