重构 - 将相似或不相同的实体的 arrayList 值放入的代码

Refactoring - a code that puts the arrayList value of an entity that is similar or not the same

目前正在利用Spring Boot 2.2开发应用程序。

我对重构感到好奇的部分位于用户实体上。

用户实体收到用户最喜欢的工作和类型。

该流派和职位由用户实体和1:N结构组成,每个实体都可以多选,不重复。

@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class User {

    @Id
    @Column(name = "user_id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String userName;
    private String email;
    private String password;

    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
    @JoinColumn(name = "user_id")
    private List<Job> likeJobs = new ArrayList<>();

    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
    @JoinColumn(name = "user_id")
    private List<Genre> likeGenres = new ArrayList<>();
     
    ...

例如,流派包括 'Hip-hop, Pop, K-POP' 和职位,例如 'Drummer, DJ, Beatmaker, and Singer'。

类型和工作结构本身可以认为是相同的。

因此,重复代码较多,如下所示。

public void addJobs(Job job){
        this.likeJobs.add(job);
        List<Job> jobsWithoutDuplicates = removeDuplicateFromJobs(this.likeJobs);
        this.likeJobs.clear();
        this.likeJobs.addAll(jobsWithoutDuplicates);
    }

    public void addJobs(List<Job> jobs){
        this.likeJobs.addAll(jobs);
        List<Job> jobsWithoutDuplicates = removeDuplicateFromJobs(this.likeJobs);
        this.likeJobs.clear();
        this.likeJobs.addAll(jobsWithoutDuplicates);
    }

    public void addGenres(Genre genre){
        this.likeGenres.add(genre);
        List<Genre> genresWithoutDuplicates = removeDuplicateFromGenres(this.likeGenres);
        this.likeGenres.clear();
        this.likeGenres.addAll(genresWithoutDuplicates);
    }

    public void addGenres(List<Genre> genres){
        this.likeGenres.addAll(genres);
        List<Genre> genresWithoutDuplicates = removeDuplicateFromGenres(this.likeGenres);
        this.likeGenres.clear();
        this.likeGenres.addAll(genresWithoutDuplicates);
    }

    public List<Job> removeDuplicateFromJobs(List<Job> jobs){
        return jobs.stream().distinct().collect(Collectors.toList());
    }

    public List<Genre> removeDuplicateFromGenres(List<Genre> genres){
        return genres.stream().distinct().collect(Collectors.toList());
    }

我想我绝对可以重构它,但我不知道该怎么做。

  1. 重构的代码必须是类型安全的。
  2. 重构的代码必须是线程安全的。
  3. 重构后不要出现故障

在这种情况下,有什么方法可以在不违反OOP的SOLID原则的情况下进行良好的重构?

我做的第一种方法是泛型。 我创建了 addJobsOrGenres(List<?> JobsOrGenres).

然后我创建了一个名为 isInstanceOf() 的附加方法。

通过以上两种方法,job和genre对象都处理了进入whatever的方法,不知道是不是一个漂亮的重构。

评论太长;添加为答案。

  1. 如果您的 addXXX 方法使用 Set 而不是 List,您可以摆脱 removeDuplicateFromXXXX 方法。 如果您继续使用 Set,请记住正确实施 equalshashcode 方法。

  2. 你可以去掉addJobs(Job job)。并且只有addJobs(Set<Job> jobs)。我认为这没有什么坏处。这样,您将有一种方法可以修改,以防将来出现 pre-processing 或 post-processing 逻辑。 addGenres.

    也是如此
  1. The refactored code must be type-safe.

当您执行 List<Job>List<Genere> 时,type-safety 会得到处理。我不会选择 addJobsOrGenres (List<?> JobsOrGenres) - jobgenere 有一个新要求,您开始添加更多 if-else。这使得它更容易将 jobs 误认为是 genere 或 vice-versa。另外,请参阅上面关于 pre 和 post 处理 的第 2 点,这是您不应该这样做的另一个原因。

  1. The refactored code must be threaded safe.

您的代码会更改共享变量,这不是线程安全的。您需要添加某种锁定机制。根据您的 use-case(如果有很多读取或写入),选择一种 Lock 策略。