重构 - 将相似或不相同的实体的 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());
}
我想我绝对可以重构它,但我不知道该怎么做。
- 重构的代码必须是类型安全的。
- 重构的代码必须是线程安全的。
- 重构后不要出现故障
在这种情况下,有什么方法可以在不违反OOP的SOLID原则的情况下进行良好的重构?
我做的第一种方法是泛型。
我创建了 addJobsOrGenres(List<?> JobsOrGenres)
.
然后我创建了一个名为 isInstanceOf()
的附加方法。
通过以上两种方法,job和genre对象都处理了进入whatever的方法,不知道是不是一个漂亮的重构。
评论太长;添加为答案。
如果您的 addXXX
方法使用 Set
而不是 List
,您可以摆脱 removeDuplicateFromXXXX
方法。 如果您继续使用 Set
,请记住正确实施 equals
和 hashcode
方法。
你可以去掉addJobs(Job job)
。并且只有addJobs(Set<Job> jobs)
。我认为这没有什么坏处。这样,您将有一种方法可以修改,以防将来出现 pre-processing 或 post-processing 逻辑。 addGenres
.
也是如此
- The refactored code must be type-safe.
当您执行 List<Job>
或 List<Genere>
时,type-safety 会得到处理。我不会选择 addJobsOrGenres (List<?> JobsOrGenres)
- job
或 genere
有一个新要求,您开始添加更多 if-else
。这使得它更容易将 jobs
误认为是 genere
或 vice-versa。另外,请参阅上面关于 pre 和 post 处理 的第 2 点,这是您不应该这样做的另一个原因。
- The refactored code must be threaded safe.
您的代码会更改共享变量,这不是线程安全的。您需要添加某种锁定机制。根据您的 use-case(如果有很多读取或写入),选择一种 Lock
策略。
目前正在利用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());
}
我想我绝对可以重构它,但我不知道该怎么做。
- 重构的代码必须是类型安全的。
- 重构的代码必须是线程安全的。
- 重构后不要出现故障
在这种情况下,有什么方法可以在不违反OOP的SOLID原则的情况下进行良好的重构?
我做的第一种方法是泛型。
我创建了 addJobsOrGenres(List<?> JobsOrGenres)
.
然后我创建了一个名为 isInstanceOf()
的附加方法。
通过以上两种方法,job和genre对象都处理了进入whatever的方法,不知道是不是一个漂亮的重构。
评论太长;添加为答案。
如果您的
addXXX
方法使用Set
而不是List
,您可以摆脱removeDuplicateFromXXXX
方法。 如果您继续使用Set
,请记住正确实施equals
和hashcode
方法。你可以去掉
也是如此addJobs(Job job)
。并且只有addJobs(Set<Job> jobs)
。我认为这没有什么坏处。这样,您将有一种方法可以修改,以防将来出现 pre-processing 或 post-processing 逻辑。addGenres
.
- The refactored code must be type-safe.
当您执行 List<Job>
或 List<Genere>
时,type-safety 会得到处理。我不会选择 addJobsOrGenres (List<?> JobsOrGenres)
- job
或 genere
有一个新要求,您开始添加更多 if-else
。这使得它更容易将 jobs
误认为是 genere
或 vice-versa。另外,请参阅上面关于 pre 和 post 处理 的第 2 点,这是您不应该这样做的另一个原因。
- The refactored code must be threaded safe.
您的代码会更改共享变量,这不是线程安全的。您需要添加某种锁定机制。根据您的 use-case(如果有很多读取或写入),选择一种 Lock
策略。