使用者、機構、角色管理這些子產品,基本上使用的都是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);
}
根據實際情況來,如果不公布通信接口和異常判斷,可以寫在一起。
建議是接口一定要做到單一職責,類的設計盡量做到隻有一個條件引起變化,這個條件在一個接口裡面二種不同的實作規則互相引起變化
來自設計模式之禅