我正在设计一些有用户和团队的Java应用程序:
public abstract class AbstractUser()
public class BasicUser extends AbstractUser()
public class AnotherUser extends AbstractUser()
现在我有了包含用户的团队:
public abstract class AbstractTeam() {
protected List<AbstractUser> members;
}
public class PublicTeam extends AbstractTeam()
现在我需要管理团队,所以每个用户都应该有一个团队状态,例如成员,版主,管理员,所有者等。
所以我想做一些接口:
public Interface TeamRole
public Interface Member extends TeamRole
public Interface Moderator extends TeamRole
并让AbsractUser类实现TeamRole:
public abstract class AbstractUser implements TeamRole
现在我想要做的是:让我们有一个控制器来处理删除用户创建的条目:
public boolean deleteEntry(User u, Entry e, requestingUser r) {
}
我怎样才能得到一个干净的表示,这样我就可以做一些事情了:
u.getEntries().removeIf(entry -> entry.equals(e));
以一种干净的方式,而不是“尝试”if语句中的所有角色?
更新:这听起来可能不是很好,但它只是为了描述在执行操作时检查权限的问题
发布于 2018-10-05 21:46:14
首先,充斥着Eels的气垫船说得对,AbstractUser
应该编写TeamRole
,而不是继承它(因为它是一种‘有’关系,而不是‘是’关系)。
现在来看手头的问题。我不确定我是否完全理解您在问什么,但是我假设您是在问如何在不使用if
或switch
语句进行检查的情况下检查AbstractUser
是否有权限(或权利)执行操作。如果是这样,那么这里有一种方法(在我能想到的几种方法中)。创建一个权限级别的Enum
,每个权限级别都有一个与权限级别直接相关的序号。下面是一个基本的例子:
class enum PermissionLevel {
MEMBER(0),
MODERATOR(1)
private final int level;
PermissionLevel(int level) {
this.level = level;
}
public int getLevel() {
return level;
}
}
现在,为TeamRole
接口提供一个方法,该方法返回与该角色关联的权限级别
public Interface TeamRole {
PermissionLevel getPermissionLevel();
...
}
现在,当检查一个成员是否有权限时,您需要做的就是对AbstractUser
拥有的TeamRole
的权限级别进行整数比较。
if (user.getTeamRole().getPermissionLevel().getLevel() > PermissionLevel.MEMBER.getLevel()) {
// User has permission to do this action
}
发布于 2018-10-05 21:54:10
TeamRole成为删除策略(也许可以重命名?)。可以使用更多的重构,但我认为一般的想法是可行的。如果我们有更多的角色,我们可以添加更多的类,并实现它们如何处理删除。
public class Entry{
}
public class User extends AbstractUser{
}
public abstract class AbstractUser {
TeamRole role;
List<Entry> entries;
//self deletes are always ok
public void deleteEntry(Entry e){
this.getEntries().removeIf(entry -> entry.equals(e));
}
//delete depending on requested user role
public void deleteEntry(User requestBy, Entry e){
role.delete(this, e, requestBy);//mod or other poeple with ability to delete.
}
public List<Entry> getEntries() {
return entries;
}
};
public class BasicUser extends AbstractUser {
};
public class AnotherUser extends AbstractUser {
};
public abstract class AbstractTeam {
protected List<AbstractUser> members;
}
public class PublicTeam extends AbstractTeam {
};
public interface TeamRole{
public void delete(AbstractUser user, Entry entry, User requester);
}
public class Member implements TeamRole{
@Override
public void delete(AbstractUser user, Entry entry, User requester) {
if(user==requester) {
user.deleteEntry(entry);
}
}
}
public class Moderator implements TeamRole{
@Override
public void delete(AbstractUser user, Entry entry, User requester) {
user.deleteEntry(entry);
}
}
发布于 2018-10-06 06:21:44
我知道已经有了答案,但我想我可以分享一个不同的想法,我们可以使用继承来表示角色层次结构,并使用方法签名来约束操作。
下面是总体设计思想:
用法:
public class TeamApplicationService {
public void doSomethingSpecial(final String teamId) {
final Team team = teamRepository.teamOfId(teamId);
final TeamModerator moderator = team.findModerator(currentUserId);
team.doSomethingSpecial(moderator);
}
}
public class Team {
final Map<String, TeamMember> teamMembers;
public Team() {
teamMembers = new HashMap<String, TeamMember>();
}
public void addMember(final TeamMember member) {
teamMembers.put(member.userId(), member);
}
private <T> T findMemberOfRole(final Class<T> clazz, final String userId) {
if (!teamMembers.containsKey(userId)) throw couldNotFindMember();
try {
return (T)clazz.cast(teamMembers.get(userId));
} catch (java.lang.ClassCastException e) {
throw couldNotFindMember();
}
}
private RuntimeException couldNotFindMember() {
return new RuntimeException("Could not find member");
}
public TeamModerator findModerator(final String userId) {
return this.<TeamModerator>findMemberOfRole(TeamModerator.class, userId);
}
public TeamMember findMember(final String userId) {
return this.<TeamMember>findMemberOfRole(TeamMember.class, userId);
}
public void doSomethingSpecial(TeamModerator moderator) {
//Moderator only
}
public void doSomethingGeneral(TeamMember member) {
//Any member
}
}
编辑:我不能完全确定需求,但这里有一个基于注释的more complex example。
https://stackoverflow.com/questions/52666363
复制相似问题