模型类(在 MVC 中)应该使用静态方法还是实例方法?

Posted

技术标签:

【中文标题】模型类(在 MVC 中)应该使用静态方法还是实例方法?【英文标题】:Should a Model class (in MVC) use static method or instance method? 【发布时间】:2013-04-22 02:04:28 【问题描述】:

就MVC框架而言,我应该使用静态方法还是实例方法?

例如假设一个Users 类和一个方法getUserById() 返回一个User 类,哪个是更好的选择?

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

User ret = Users.getUserById(123);

假设类Users中没有实例变量, 哪个是更好的选择?

【问题讨论】:

这在很大程度上取决于您使用的框架。 这里有一些讨论 - ***.com/questions/538870/…。我个人不会使用静态方法,因为它们通常更难测试。此外,如果您的应用支持多租户(即两个或更多不同的用户集),那么这可能会变得更加困难。 在我的拙见中,MVC模式被用来发扬封装的概念,从某种意义上说,任何其他类都不能直接访问它的data members,并在一定程度上扩展了member functions。因此我猜想创建实例方法,应该是首选... :-) 你不认为将对象创建与域逻辑混合会违反 SRP 吗? 【参考方案1】:

我倾向于实例变量。仅仅是因为它会更容易编写测试。另外,很多当前的服务器技术(Spring、JavaEE 等)都很好地支持注入 bean/资源。哪个更好地支持这个而不是静态方法。

【讨论】:

【参考方案2】:

如果您有一个 User 类,例如 Product 类,并且其中有带有 id 的对象,我建议您扩展 'User' 和 'Category' 以拥有一个 'getById' 方法,该方法接收要运行的 $id。

这样,您可以在两种不同类型的对象中使用相同的方法。

我希望这个例子有点意义:

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

【讨论】:

这不是使用子类作为 is-a 关系的一个很好的例子。您基本上是在使用继承来继承代码。【参考方案3】:

坚决不。其实你应该看看DAO(数据访问对象)模式。

模型类本身只负责将信息从一个逻辑实例传输到另一个逻辑实例,并且应该只包含 geter 和 setter 方法。

DAO 类负责从某些数据源(数据库)存储更新或检索信息。这是 DAO 模式的示例:

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

【讨论】:

以上是关于模型类(在 MVC 中)应该使用静态方法还是实例方法?的主要内容,如果未能解决你的问题,请参考以下文章

MVC - 除了设置/获取成员之外,模型类中应该都有哪些方法?

PHP MVC 原理

静态方法与实例方法

内部类方法应该返回值还是只修改实例变量?

Java中的静态和枚举

Netty 4 标头:我应该使用静态方法还是实例方法?