用户、机构、角色管理这些模块,基本上使用的都是RBAC模型(Role-Based Access Control,基于角色的访问控制,通过分配和取消角色来完成。用户权限的授予和取消,使动作主体(用户)与资源的行为(权限)分离),确实是一个很好的解决办法。
用户管理、修改用户的信息、增加机构、增加角色,设计在一个接口中,都是用户管理类
接口设计是有问题:用户属性 和 用户行为没有分开
应该把用户信息抽取成一个BO(业务对象)
行为抽取成一个Biz业务逻辑
interface IUserInfo {
// 设置用户ID
void setUserID(String userID);
// 获取用户名
String getUserID();
// 设置密码
void setPassword(String password);
// 获取密码
String getPassword();
// 设置用户名
void setUserName(String userName);
// 获取用户名
String getUserName();
// 更改密码
boolean changePassword(String oldPassword);
// 删除用户
boolean deleteUser();
// 有权限访问用户
void mapUser();
// 添加权限
boolean addOrg(int orglD);
//添加角色
boolean addRole(int roleID);
}
一个接口拆分成两个接口的动作,就是依赖了单一职责原则
IUserBO的职责就是收集和反馈用户的属性信息
IUserBiz负责用户的行为,完成用户信息的维护和变更
/**
* 负责用户属性
*/
interface IUserBO {
// 设置用户ID
void setUserID(String userID);
// 获取用户名
String getUserID();
// 设置密码
void setPassword(String password);
// 获取密码
String getPassword();
// 设置用户名
void setUserName(String userName);
// 获取用户名
String getUserName();
}
/**
* 负责用户行为
*/
interface IUserBiz {
// 更改密码
boolean changePassword(String oldPassword);
// 删除用户
boolean deleteUser();
// 有权限访问用户
void mapUser();
// 添加权限
boolean addOrg(int orglD);
//添加角色
boolean addRole(int roleID);
}
// 实现
class UserInfo implements IUserInfo {}
/**
* 实现关系 + 泛化关系
* @param args
*/
public void main(String[] args) {
IUserInfo userInfo = new UserInfo();
//我要赋值了,我就认为它是一个纯粹的BO
IUserBO userBO = (IUserBO) userInfo;
userBO.setPassword("abc");
//我要执行动作了,我就认为是一个业务逻辑类
IUserBiz userBiz = (IUserBiz) userInfo;
userBiz.deleteUser();
}
单一职责原则的定义是:应该有且仅有一个原因引起类的变更,如下一个接口
包含了两个职责:一个是协议管理,一个是数据传送。
dial()和hangup()两个方法实现的是协议管理,分别负责拨号接通和挂机
chat()实现的是数据的传送
dial()和hangup()协议管理会引起这个接口实现类 chat()数据传送的变化
chat()数据传送例如可以qq,微信,上网等,会引起接口实现类的dial()hangup()协议的变化
interface IPhone {
//拨通电话
public void dial(String phoneNumber);
//通话完毕,挂电话
public void hangup();
//通话聊天
public void chat(Object o);
}
二个职责的可能会相互影响,那就考虑二个接口,
把二个职责融合在一个类里面, 面向接口编程,对外公布是是接口 而不是实现类。
interface IConnectionManager {
//拨通电话
public void dial(String phoneNumber);
//通话完毕,挂电话
public void hangup();
}
interface IDataTransfer {
//数据传送
void DataTransfer(IConnectionManager cm);
}
/**
*
* 对象依赖关系
*/
class Phone implements IDataTransfer{
@Override
public void DataTransfer(IConnectionManager cm) {
cm.dial("电话号码");
cm.hangup();
}
}
单一职责适用于接口、类,同时也适用于方法
一个方法尽可能做一件事情,比如一个方法修改用户密码,不要把这个方法放到“修改用户信息”方法中
方法职责不清晰,不单一,不要让别人猜测这个方法可能是用来处理什么逻辑
interface IUserManager {
/**
* 更改用户
* @param userBO 用户属性接口
* @param changeOptions 修改类型到用户属性接口上,在保存到db
*/
void changeUser(单一职责.IUserBO userBO, String... changeOptions);
}
修改成如下
interface IUserManager {
//修改用户名称
void changeusername(String newUsername);
// 修改家庭
void changeHomeAddress(String newHomeAddressvoid);
// 修改单体电话
void changeofficete(String telnumber);
}
根据实际情况来,如果不公布通信接口和异常判断,可以写在一起。
建议是接口一定要做到单一职责,类的设计尽量做到只有一个条件引起变化,这个条件在一个接口里面二种不同的实现规则互相引起变化
来自设计模式之禅