最近学习了下设计模式之State(状态模式),联想到之前做的web程序,并将State模式应用到了用户的权限管理上.具体见代码:
User.java: 用户类确定身份信息用了两个字段.StateService是一个用户身份信息接口,为了在数据库中仍然能正确映射,所以我屏蔽了StateService并新建了一个字段status作为身份标识,实际功能是通过StateService完成的.
@Entity
public class User{
/** The id. */
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
/** The name. */
@Column(unique = true, nullable = false)
private String name;
/** 用户身份: 游客,会员,vip. */
private String status;
/** 用户身份接口: 游客,会员,vip. */
@Transient
private StatusService statusService;
MemberStatusService.java: 用户身份接口的实现,这里只提供这一个,其他类似.
public class MemberStatusService implements StatusService{
//仅用于测试,不访问数据库,所以不使用此变量.
@SuppressWarnings("unused")
@Autowired
private UserRepository userRepository;
@Override
public boolean publish(User user) {
Logger logger = Logger.getLogger(this.getClass());
logger.info("会员: 发表文章");
return true;
}
@Override
public boolean follow(User user, User followedUser) {
Logger logger = Logger.getLogger(this.getClass());
logger.info("会员: 关注 -> 无权限");
return false;
}
}
StatusService.java: 身份信息接口,里面定义了与权限相关的方法.
@Repository
public interface StatusService{
/**
* vip和会员: 发表文章.
*
* @param user the user
* @return true, if successful
*/
public boolean publish(User user);
/**
* vip: 关注某人.
*
* @param user the user
* @param followedUser the followed user
* @return true, if successful
*/
public boolean follow(User user, User followedUser);
}
UserService.java: 用户的常用方法会被定义在这里,这些方法所有用户都拥有执行权,从StatusService接口实现的方法将不做直接处理.
@Service
public class UserService implements StatusService{
@Autowired
private UserRepository userRepository;
/**
* 所有用户: 注册更新..
*
* @param user the user
* @return true, if successful
*/
public boolean registOrUpdate(User user) {
return
userRepository.saveAndFlush(user) == null ? false : true;
}
/**
* 所有用户: 登录.
*
* @param user the user
* @return true, if successful
*/
public boolean login(User user) {
return userRepository.getByName(user.getName()) != null ? true : false;
}
@Override
public boolean publish(User user) {
return user.getStatusService().publish(user);
}
@Override
public boolean follow(User user, User followedUser) {
return user.getStatusService().follow(user, followedUser);
}
}
到这里代码基本就完了,下面是测试代码:
@Test
public void testPublish() throws Exception {
// StatusService statusService = new MemberStatusService();
StatusService statusService = new VisitorStatusService();
// StatusService statusService = new VipStatusService();
User user = new User();
user.setStatusService(statusService);
user.setName("ramer");
Logger logger = Logger.getLogger(getClass());
logger.info("登录 : " + userService.login(user));
logger.info("发表文章 : " + userService.publish(user));
logger.info("关注 : " + userService.follow(user, user));
测试结果如下:
15:12:58,628 INFO UserTest:51 - 登录 : true
15:12:58,629 INFO MemberStatusService:24 - 会员: 发表文章
15:12:58,629 INFO UserTest:52 - 发表文章 : true
15:12:58,629 INFO MemberStatusService:31 - 会员: 关注 -> 无权限
15:12:58,629 INFO UserTest:53 - 关注 : false
既然这里使用这种模式,就有它的好处:
如果将来需求变动,比如’关注用户’功能也为’会员’开通.如果是以前的实现可能要改很多代码,但是使用了State模式后,只需要修改相应的MemberStatusService.java中的follow方法就可以了.学设计模式最大的感触就是好神奇.