8

In term of a MVC framework, should I use a static method or instance method?

e.g. Assume a Users class, and a method getUserById() which return a User class, which one is better choice?

Users users = new Users();
User ret = users.getUserById(123);

or

User ret = Users.getUserById(123);

Assume there is no instance variable in the class Users, which one is a better choice?

Howard
  • 19,215
  • 35
  • 112
  • 184
  • That depends heavily on the framework you use. – maba Apr 28 '13 at 08:48
  • Some discussion here - http://stackoverflow.com/questions/538870/java-static-methods-best-practices. I would not use static methods personally, as they are often harder to test. Also, if your app supported multi-tenancy (i.e. two or more distinct sets of users) then this might get a lot harder. – Paul Grime Apr 28 '13 at 09:05
  • In my humble opinion, MVC pattern is used to carry forward the concept of Encapsulation, in the sense, that, no other Class shall access its `data members` directly and to certain extend `member functions`. Hence I guess creating instance methods, should be the first choice ... :-) – nIcE cOw Apr 28 '13 at 09:23
  • Don't you think that mixing object creation with domain logic would mean violation of SRP? – tereško Apr 28 '13 at 10:33

3 Answers3

4

I would lean toward instance variable. Simply because it will be easier to write tests for. Plus, a lot of the current server technologies (Spring, JavaEE, etc) support injecting beans/resource very well. Which better supports this rather than static methods.

EdH
  • 4,918
  • 4
  • 24
  • 34
2

Defiantly nope. Actually you should look at DAO (Data Access Object) pattern.

Model classes itself are responsible only for transferring information from one logic instance to another and should contain only geter and setter methods.

DAO classes are responsible for storing updating or retrieving info form some Data Source (database).Here is example of DAO pattern:

public class BookDAO {

  private PreparedStatement saveStmt;
  private PreparedStatement loadStmt;

  public DBBookDAO(String url, String user, String pw) {
    Connection con = DriverManager.getConnection(url, user, pw);
    saveStmt = con.prepareStatement("INSERT INTO books(isbn, title, author) "
                                   +"VALUES (?, ?, ?)");
    loadStmt = con.prepareStatement("SELECT isbn, title, author FROM books "
                                   +"WHERE isbn = ?");
  }

  public Book loadBook(String isbn) {
    Book b = new Book();
    loadStmt.setString(1, isbn);
    ResultSet result = loadStmt.executeQuery();
    if (!result.next()) return null;

    b.setIsbn(result.getString("isbn"));
    b.setTitle(result.getString("title"));
    b.setAuthor(result.getString("author"));
    return b;
  }

  public void saveBook(Book b) {
    saveStmt.setString(1, b.getIsbn());
    saveStmt.setString(2, b.getTitle());
    saveStmt.setString(3, b.getAuthor());
    saveStmt.executeUpdate();
  }
}
Artemis
  • 4,821
  • 3
  • 21
  • 24
1

If you have an User class and, for example, a Product class, and you have objects in there with ids, I'd suggest extending the 'User' and 'Category' to have one 'getById' method, which received an $id to be ran.

This way, you can use the same method in two different types of objects.

I hope this example makes some sense:

class User extends SuperClass {
    public function getTableName() {
        return 'table_name_for_user';
    }
    public function getPK() {
        return 'primary_key_for_user';
    }
}

class Category extends SuperClass {
    public function getTableName() {
        return 'table_name_for_category';
    }
    public function getPK() {
        return 'primary_key_for_category';
    }
}

class SuperClass {
    public function getById($id) {
        $query = $this->db->query("SELECT * FROM " . $this->getTableName() . " WHERE " . $this->getPK() . " = $id");
        return $query->result();
    }
}
ran
  • 17
  • 2
  • 2
    This isn't a great example of using subclasses as a *is-a* relationship. You're basically using inheritance to inherit code. – Paul Grime Apr 28 '13 at 09:11