Spring Boot分销管理系统三类角色类设计优化方案咨询
现有设计的遗漏问题
- 未实现零售商与分销商的关联关系:当前Retailer实体未定义和Distributor的绑定逻辑,无法支撑「零售商可关联指定城市内不同公司的分销商」的业务规则
- User类的company属性标注为@Transient不会持久化存储,管理员、分销商的所属公司分别存储在各自独立的实体中,属性冗余且无法通过User统一获取所属公司信息
- 业务规则未在数据层落地:现有表结构未添加唯一约束,无法保证「每家公司仅1名管理员」「特定公司单个城市仅1名分销商」的规则,容易产生脏数据
- 实体冗余:Admin、Distributor、Retailer三个实体仅存在和Company关联的差异,无其他专属业务属性,单独建表会大幅提升CRUD逻辑的复杂度
优化方案
直接合并冗余实体,补全业务约束即可:
- 移除Admin、Distributor、Retailer三个独立实体,将差异化属性合并到User类中
- 取消User类company属性的@Transient注解,添加
@ManyToOne关联持久化存储,零售商用户该字段允许为空 - 新增零售商和分销商的多对多关联,通过中间表存储绑定关系
- 在User表添加组合唯一约束,分别实现公司下管理员唯一、同公司同城市分销商唯一的业务规则
适用设计模式
采用策略模式处理不同角色的差异化业务逻辑:
定义角色业务策略接口,分别为管理员、分销商、零售商实现对应的策略类,运行时根据User的role属性动态获取对应策略实现,避免大量角色判断的if-else代码,逻辑拆分清晰,新增角色时仅需新增对应策略实现即可,符合开闭原则。
核心代码示例
优化后的User实体
@Entity @Table(name = "tbl_user", uniqueConstraints = { // 公司+管理员角色唯一约束 @UniqueConstraint(columnNames = {"company_id", "role_id"}, name = "uk_company_admin"), // 公司+城市+分销商角色唯一约束 @UniqueConstraint(columnNames = {"company_id", "city_id", "role_id"}, name = "uk_company_city_distributor") }) public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "user_id") private Long userId; @NotNull(message = "first Name cannot be null") @Column(name = "first_Name") private String firstName; @NotNull(message = "last Name cannot be null") @Column(name = "last_Name") private String lastName; @ManyToOne() @JoinColumn(name = "role_Id") private Role role; @NotNull @Size(min = 10, max = 10, message = "Contact must be of 10 characters") @Column(name = "contact") private String contact; @NotNull @Email(message = "Email should be valid") @Column(name = "email", unique = true) private String email; @NotNull @Size(min = 10, max = 255, message = "Local address must be between 10 and 255 characters") @Column(name = "local_Address") private String localAddress; @ManyToOne() @JoinColumn(name = "city_Id") private City city; @NotNull @Column(name = "user_Name") private String userName; @NotNull @Column(name = "password") private String password; @Column(name = "registered_On") private LocalDateTime registeredOn; @Column(name = "updated_On") private LocalDateTime updatedOn; @Column(name = "approved_By") private Long approvedBy; @NotNull @Size(min = 1, max = 1, message = "Approval status must be of 1 character.") @Column(name = "approval_Status") private String approvalStatus; @NotNull @Column(name = "active_Status") private boolean activeStatus; // 取消Transient注解,持久化存储所属公司 @ManyToOne @JoinColumn(name = "company_id") private Company company; // 零售商关联的分销商,仅零售商角色该字段有值 @ManyToMany @JoinTable( name = "tbl_retailer_distributor", joinColumns = @JoinColumn(name = "retailer_id"), inverseJoinColumns = @JoinColumn(name = "distributor_id") ) private List<User> relatedDistributors; }
策略模式实现
// 角色业务策略接口 public interface UserBusinessStrategy { void execute(User user); RoleEnum getSupportRole(); } // 管理员业务实现 @Component public class AdminBusinessStrategy implements UserBusinessStrategy { @Override public void execute(User user) { // 管理员专属业务逻辑 } @Override public RoleEnum getSupportRole() { return RoleEnum.ADMIN; } } // 分销商业务实现 @Component public class DistributorBusinessStrategy implements UserBusinessStrategy { @Override public void execute(User user) { // 分销商专属业务逻辑 } @Override public RoleEnum getSupportRole() { return RoleEnum.DISTRIBUTOR; } } // 策略工厂,自动注入所有实现类 @Component public class UserStrategyFactory implements InitializingBean, ApplicationContextAware { private ApplicationContext applicationContext; private Map<RoleEnum, UserBusinessStrategy> strategyMap; @Override public void afterPropertiesSet() { Map<String, UserBusinessStrategy> beans = applicationContext.getBeansOfType(UserBusinessStrategy.class); strategyMap = beans.values().stream() .collect(Collectors.toMap(UserBusinessStrategy::getSupportRole, Function.identity())); } @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; } public UserBusinessStrategy getStrategy(RoleEnum role) { return strategyMap.get(role); } }
内容的提问来源于stack exchange,提问作者Deepak Bhalode
相关产品推荐
相关产品推荐

