目前,该应用程序正在利用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<>();
...
例如,流派包括"嘻哈、流行、K-Pop"one_answers"鼓手、DJ、Beatmaker和歌手"等工作。
性别和工作结构本身可以被认为是相同的。
因此,存在许多重复代码,如下所示。
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());
}
我想我肯定可以重新考虑,但我不知道该怎么办。
- 重构的代码必须是类型安全的
- 重构的代码必须是线程安全的
- 重构后不要出现故障
在给定条件下,是否有任何方法可以在不违反OOP的SOLID原则的情况下进行良好的重构?
我做这件事的第一种方式是泛型类型。我创建了addJobsOrGenres(List<?> JobsOrGenres)
。
然后我创建了一个名为isInstanceOf()
的附加方法。
通过以上两种方法,job和流派对象都处理了进入what的方法,但我不知道这是否是一个漂亮的重构。
注释太长;添加作为答案。
-
如果您的
addXXX
方法采用Set
而不是List
,则可以取消removeDuplicateFromXXXX
方法如果继续使用Set
,请记住equals
和hashcode
方法的正确实现 -
你可以去掉
addJobs(Job job)
。并且只存在addJobs(Set<Job> jobs)
。我不认为这有什么害处。通过这种方式,您将有一种方法可以修改,以防将来出现预处理或后处理逻辑。addGenres
也是如此。
- 重构的代码必须是类型安全的
执行List<Job>
或List<Genere>
时,会注意类型安全。我不会选择addJobsOrGenres (List<?> JobsOrGenres)
——job
或genere
有一个新的要求,你开始添加更多的if-else
s。这使得它更容易将jobs
误认为genere
,反之亦然。此外,请参阅上面关于前处理和后处理的第2点,这是您不应该这样做的另一个原因。
- 重构的代码必须是线程安全的
您的代码会对共享变量进行突变,这不是线程安全的。您需要添加某种类型的锁定机制。根据您的用例(如果有许多读取或写入(,选择Lock
策略之一。