You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot分销管理系统三类角色类设计优化方案咨询

现有设计的遗漏问题
  • 未实现零售商与分销商的关联关系:当前Retailer实体未定义和Distributor的绑定逻辑,无法支撑「零售商可关联指定城市内不同公司的分销商」的业务规则
  • User类的company属性标注为@Transient不会持久化存储,管理员、分销商的所属公司分别存储在各自独立的实体中,属性冗余且无法通过User统一获取所属公司信息
  • 业务规则未在数据层落地:现有表结构未添加唯一约束,无法保证「每家公司仅1名管理员」「特定公司单个城市仅1名分销商」的规则,容易产生脏数据
  • 实体冗余:Admin、Distributor、Retailer三个实体仅存在和Company关联的差异,无其他专属业务属性,单独建表会大幅提升CRUD逻辑的复杂度
优化方案

直接合并冗余实体,补全业务约束即可:

  1. 移除Admin、Distributor、Retailer三个独立实体,将差异化属性合并到User类中
  2. 取消User类company属性的@Transient注解,添加@ManyToOne关联持久化存储,零售商用户该字段允许为空
  3. 新增零售商和分销商的多对多关联,通过中间表存储绑定关系
  4. 在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 01:54:04