2.2 Model层

1 集中管理

    有生命力的系统会不断进化与生长,对并发的要求会越来越高,当优化 sql 与引入 cache 这两种方式无法满足需要后,就进入了集群 + 分布式进化阶段

    分布式需要将大系统拆分成多个小型系统,而 Model 集中管理有利于这种拆分。将所有 Model 放在 common.model 这个包下非常容易抽取成一个maven 模块共享给分布式系统的其它模块

2 使用Generator

   使用 Generator 生成的 model 符合 java bean 规范,并立即拥有 getter、setter 方法,有利于大量依靠 java bean 规范而工作的第三方工具,例如 fastjson、jackson。

   此外,生成的 model 拥有静态语言的好处,无需记忆字段名称,便于重构

3 Model代码

    Model 中不要放业务逻辑,仅仅放一些纯粹 model 自己内部状态有关的通用方法,model 是要被其它业务模块共用的,不要放与具体某个业务有前端的代码,同样这也有利于未来的分布式

   例如有一张 account 表,其中有一个 int status 字段,以下是代码示例:

public class Account extends BaseAccount<Account> {
  
  public static final int STATUS_LOCK_ID = -1;  // 锁定账号
  public static final int STATUS_REG = 0;       // 注册、未激活
  public static final int STATUS_OK = 1;        // 正常、已激活

  public boolean isStatusOk() {
    return getStatus() == STATUS_OK;
  }

  public boolean isStatusReg() {
    return getStatus() == STATUS_REG;
  }

  public boolean isStatusLockId() {
    return getStatus() == STATUS_LOCK_ID;
  }
}

4:避免Model中创建dao

    JFinal 以往提供 demo 的 Model 中做了一个不好的示范,在其中创建了 public static final Xxx dao 对象,原本是为了在查询时可以少创建一次对象,但发现有很多用户使用该 dao 对象进行了查询以外的操作,例如 save()、update()、set() 等操作

    由于 static Xxx dao 对象是全局共享的,所以会有线程安全问题,为了彻底杜绝新手的误用,jfinal 最佳实践需要将 dao 对象从 Model 中删除,转而在 Service 中创建,例如:

public class AccountService {

  private Account dao = new Account();
  
  public Ret login(String userName, String password) {
    String sql= "select * from account where userName=? limit 1";
    Account account = dao.findFirst(sql, userName);
    // ... 其它代码
  }
}

   如上代码所示, dao 对象从 Account 中转移到了 AccountService 中,并声明为 private 避免外界对该对象的使用。同时也避免了线程安全问题。