避免许多if语句,代码改进

时间:2017-10-19 06:33:08

标签: java design-patterns spring-security

我有oracle数据库,我无法改变。在这个数据库中,我有一个带有权限字段的用户表。

CREATE TABLE USER (
    ID NUMBER(38,0), 
    LOGIN VARCHAR2(6 BYTE) NOT NULL ENABLE, 
    PASSWORD VARCHAR2(200 BYTE) NOT NULL ENABLE, 

    BOOK_READ NUMBER(1,0), 
    BOOK_UPD NUMBER(1,0), 
    R_READ NUMBER(1,0), 
    R_UPD NUMBER(1,0), 
    ... 
    ...
)

例如:

book_read = 1;  - means that user has authority 
book_upd  = 0;  - means that user he does not
report_read = 1;

现在我正在检查这个:

List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
if (user.getBook_read() == 1) {
    authorities.add(new SimpleGrantedAuthority("ROLE_BOOK_READ"));
}
if (user.getBook_upd() == 1) {
    authorities.add(new SimpleGrantedAuthority("ROLE_BOOK_UPD"));
}
if (user.getReport_read() == 1) {
    authorities.add(new SimpleGrantedAuthority("ROLE_REPORT_READ"));
}

我有很多权威机构(大约20个,他们在表格中都有一个单独的专栏)。有人建议我如何改进代码?

2 个答案:

答案 0 :(得分:1)

现在,您似乎在数据库中有20个权限,并且User模型对象包含20个字段,20个 getters < / em>和20 setter ,您需要20 if个语句来构建List<GrantedAuthority>

为了简化这一点,我建议从Model对象和DAO开始。

为了提高灵活性,请使用20个权限创建enum,并明确命名数据库列名称和角色名称,例如

public enum User_Authority {
    BOOK_READ("BOOK_READ", "ROLE_BOOK_READ"),
    BOOK_UPD ("BOOK_UPD" , "ROLE_BOOK_UPD"),
    // more enums

    // fields here

    private User_Authority(String columnName, String roleName) {
        // assign to fields here
    }

    // getters here
}

然后,您的User模型对象可以使用EnumSet<User_Authority>来存储授予用户的权限。

然后,您的Spring JDBC模板可以使用RowMapper,其逻辑如下:

public final class UserRowMapper implements RowMapper<User> {
    @Override
    public User mapRow(ResultSet rs, int rowNum) {
        User user = new User();
        // get other columns here
        EnumSet<User_Authority> granted = EnumSet.noneOf(User_Authority.class);
        for (User_Authority auth : User_Authority.values())
            if (rs.getInt(auth.getColumnName()) == 1)
                granted.add(auth);
        user.setAuthorities(granted);
        return user;
    }
}

构建List<GrantedAuthority> authorities的代码现在就像这样简单:

List<GrantedAuthority> authorities = new ArrayList<>();
for (User_Authority auth : user.getAuthorities())
    authorities.add(new SimpleGrantedAuthority(auth.getRoleName()));

正如您所看到的,您现在只有一个地方有20个“重复”:enum值。

如果您稍后需要添加更多内容,您当然会在用户表中添加新列,然后您只需要在代码中添加两个项目:

  • 将列添加到提供给Spring JDBC Template的SQL语句的SELECT子句中。
  • 添加新的enum值。

这是代码的简化/改进,对吗?

答案 1 :(得分:0)

如何创建存储方法与SimpleGrantedAuthority

之间关系的类List
public class RoleChecker
{
    Function<User, Integer> roleCheckFunction;
    SimpleGrantedAuthority theAuthority;

    public RoleChecker(Function<User, Integer> roleCheckFunction, SimpleGrantedAuthority theAuthority)
    {}
}

并使用循环执行检查。

List<RoleChecker> roles = new ArrayList<>();
roles.add(new RoleChecker(User::getBook_read, new SimpleGrantedAuthority("ROLE_BOOK_READ")));
roles.add(new RoleChecker(User::getBook_upd, new SimpleGrantedAuthority("ROLE_BOOK_UPD")));
// ....
for (RoleChecker check : roles)
{
    if (check.roleCheckFunction.apply(user) == 1)
        authorities.add(check.theAuthority);
}