David
David

Reputation: 10738

java - design patterns - inheritance with static variables

I have a Person class that extends my Record class and i'd like to define the database table name, columns, and column types as static variables in the Person class. I'd like to do something like the following but i can't because i can't modify objects when not in a method(i think? java noob here).

class Person extends Record{
    protected static final String dbTable = "people";
    protected static LinkedHashMap<String, String> dbColumns = new LinkedHashMap<String, String>();
    dbColumns.put("id","integer");
    dbColumns.put("name", "text");
}

I could do the following but it looks messy and not very readable especially if my table has several columns

class Person extends Record{
    protected static final String dbTable = "people";
    protected static final String[] dbColumns= {"id","name"};
    protected static final String[] dbColumnTypes= {"integer","text"};

}

I don't want to define these in the constructor because I want a static method in the parent class(Record) that i can do something like the following to get a list of Person records

List<Person> people = Person.getAll();

My initial thought was to create the following abstract methods in my Record class and their implementation in the Person class would return the appropriate static variables.

public abstract String getTableName();
public abstract String[] getColumnNames();
public abstract String[] getColumnTypes();

BUT i can't do that because my static method, getAll(), can't reference non-static methods. How do i let my static method, getAll(), aware that those static variables exist in an extended class and can use them?

I'm know there's a correct way to go about doing this, i just can't figure it out.

Upvotes: 0

Views: 658

Answers (5)

Dariusz
Dariusz

Reputation: 22241

You might consider using enums. You can also use an interface to provide abstraction between various Db-based classes.

interface DbColumn{
  String getName();
  String getType();
}

enum PersonDbColumns implements DbColumn {
  ID("integer"),
  NAME("text");

  PersonDbColumns(String type) {
    this.type=type;
  }

  private String type;

  String getName() {
    return this.toString();
  }

  String getType() {
    return type;
  } 

}

You can add more fields to each column. You gain the advantage of compile-time error if you do not fill all elements of the enum, provided you use the constructor for initialization. You have valuOf() and Class.getEnumConstants() to get the enum from string or to get all columns from given table.

Upvotes: 1

scott_fakename
scott_fakename

Reputation: 10789

You could do what you're doing with the abstract methods, and then all you need to do is change your static getAll() to be something like getAll(Record record) and just have it call those methods.

You're on the right track. I would avoid relying on static things for anything outside of the class itself in favor of exposing instance methods that may themselves call private or protected static fields, personally.

Upvotes: 1

Shurmajee
Shurmajee

Reputation: 1047

Your class Record contains static final variables. There is no need to use a getter method to fetch the value of your ststic variables. As far as I can understand you are planning to call a db query inside getAll() method. you should simply access the static variables using Classname.variable_name

Record.dbTable;
Record.dbColumns;
Record.dbColumnTypes;

Upvotes: 0

aymankoo
aymankoo

Reputation: 671

The best practics for this is to Have Utility class that contains all these stuff methods and variabls as static. The Utility class usually has no construction. you could also use static block

  static {
   initialize your static variables here
  }

Upvotes: 0

Patashu
Patashu

Reputation: 21773

In Java, you can do static initializer blocks in a class. They look like this:

static
{
    dbColumns.put("id","integer");
    dbColumns.put("name", "text");
}

Static initializer blocks run once before the class is used - anywhere between the program starting up and the class being loaded.

Upvotes: 1

Related Questions