有生命力的系统会不断进化与生长,对并发的要求会越来越高,当优化 sql 与引入 cache 这两种方式无法满足需要后,就进入了集群 + 分布式进化阶段
分布式需要将大系统拆分成多个小型系统,而 Model 集中管理有利于这种拆分。将所有 Model 放在 common.model 这个包下非常容易抽取成一个maven 模块共享给分布式系统的其它模块
使用 Generator 生成的 model 符合 java bean 规范,并立即拥有 getter、setter 方法,有利于大量依靠 java bean 规范而工作的第三方工具,例如 fastjson、jackson。
此外,生成的 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; } }
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 避免外界对该对象的使用。同时也避免了线程安全问题。