IntelliJ에서 작성기 패턴 작성을 자동화하는 방법이 있습니까?
예를 들어 다음과 같은 간단한 클래스가 있습니다.
class Film {
private String title;
private int length;
public void setTitle(String title) {
this.title = title;
}
public String getTitle() {
return this.title;
}
public void setLength(int length) {
this.length = length;
}
public int getLength() {
return this.length;
}
}
IDE에서 이것을 생성하거나 비슷한 방법을 얻을 수 있습니까?
public class FilmBuilder {
Film film;
public FilmBuilder() {
film = new Film();
}
public FilmBuilder withTitle(String title) {
film.setTitle(title);
return this;
}
public FilmBuilder withLength(int length) {
film.setLength(length);
return this;
}
public Film build() {
return film;
}
}
답변
생성자를 빌더로 교체 리팩토링을 사용 하십시오 .
이 기능을 사용하려면 코드에서 생성자의 서명을 클릭 한 다음 마우스 오른쪽 버튼을 클릭하고 “리팩터링”메뉴를 선택한 다음 “생성자를 빌더로 대체 …”를 클릭하여 코드를 생성하는 대화 상자를 불러옵니다.
답변
IntelliJ의 빌트인 빌더 패턴 생성이 몇 가지 이유로 약간 어색하다는 것을 알았습니다.
- 기존 생성자를 참조로 사용해야합니다.
- “생성”메뉴 (
command+N
OS X의 경우) 를 통해 빠르게 액세스 할 수 없습니다 . - 외부 Builder 클래스 만 생성합니다. 다른 사람들이 언급했듯이 빌더 패턴을 구현할 때 정적 내부 클래스를 사용하는 것은 매우 일반적입니다.
InnerBuilder 플러그인 이 모든 단점의 주소를, 어떤 설정이나 구성이 필요하지 않습니다. 다음은 플러그인에 의해 생성 된 샘플 빌더입니다.
public class Person {
private String firstName;
private String lastName;
private int age;
private Person(Builder builder) {
firstName = builder.firstName;
lastName = builder.lastName;
age = builder.age;
}
public static final class Builder {
private String firstName;
private String lastName;
private int age;
public Builder() {
}
public Builder firstName(String firstName) {
this.firstName = firstName;
return this;
}
public Builder lastName(String lastName) {
this.lastName = lastName;
return this;
}
public Builder age(int age) {
this.age = age;
return this;
}
public Person build() {
return new Person(this);
}
}
}
답변
Mansoor Siddiqui가 언급 한 단점 을 극복하는 방법은 다음과 같습니다 .
1) 기존 생성자를 참조로 사용해야합니다.
생성하기 매우 쉽습니다. 그냥 히트 Alt+를 Ins메뉴를 생성하고 선택 호출 Windows에서 Constructor
.
2) “생성”메뉴 (OS X의 경우 command + N)를 통해 빠르게 액세스 할 수 없습니다.
로 이동 하여 원하는 바로 가기를 Settings -> Keymap
검색하여 Builder
할당하십시오 (이 기능을 자주 사용하는 경우는 드물지만). 예를 들어 Alt+ B를 할당 할 수 있습니다 .
또 다른 대안은 Ctrl+ Shift+ A(액션 찾기)입니다. 입력을 시작 Builder
하면 즉시 명령에 액세스 할 수 있습니다.
이 바로 가기를 사용하여 IntelliJ IDEA 기능에 빠르게 액세스 할 수 있습니다 (명령이 호출 된 내용과 명령 위치를 정확히 기억하지 못하는 경우 많은 도움이 됨).
3) 외부 Builder 클래스 만 생성합니다. 다른 사람들이 언급했듯이 빌더 패턴을 구현할 때 정적 내부 클래스 를 사용하는 것은 매우 일반적 입니다.
또한 내 빌더를 정적 내부 클래스로 선호합니다. 안타깝게도 간단한 방법은 없지만 여전히 가능합니다. 중첩 된 내부 클래스를 직접 정의하고 (비워두면) Replace Constructor with Builder
대화 상자 를 호출 할 때 Use existing
옵션을 선택하고 내부 클래스를 선택하면됩니다. 매력처럼 작동합니다! 하지만이 옵션을 구성 가능하게 만드는 것이 더 쉬웠을 것입니다.
답변
이것이 Joshua Block이 설명 하는 내부 빌더 클래스를 사용하여 클래스를 생성하는 데 사용할 수 있는지 궁금하다면 먼저 빈 내부 클래스를 정의한 다음 “기존 클래스 사용”을 선택하고 새로 생성 된 (내부 클래스 ) “리팩터링”을 누르십시오.
추신! “생성자를 빌더로 교체”리팩토링 기능을 사용하려면 커서가 생성자 (미리 작성된) 내에 있어야합니다.
답변
이에 대한 IntelliJ 방식은 IMHO입니다. 목적을 훨씬 더 잘 제공하는 두 가지 플러그인 ( https://plugins.jetbrains.com/plugin/7354 )이 있습니다.
예를 들어, 저는 Builder 클래스를 PoJo의 내부 클래스로 사용하는 것을 선호합니다. IntelliJ로이를 달성하려면 몇 번의 추가 스트로크가 필요합니다.
플러그인의 또 다른 장점은 Generate...
컨텍스트 메뉴 에서 기능의 위치입니다 .
답변
롬복은 가장 쉬운 방법입니다! ( https://plugins.jetbrains.com/plugin/6317-lombok-plugin 구문 지원을위한 Intellij 플러그인이 있습니다. )
@Builder
주석 만 추가 하면 벽 뒤에는 객체 내부에 빌더 구현이 추가됩니다.
Lombok 사용 :
import lombok.Builder;
import lombok.Singular;
import java.util.Set;
@Builder
public class BuilderExample {
@Builder.Default private long created = System.currentTimeMillis();
private String name;
private int age;
@Singular private Set<String> occupations;
}
롬복없이 :
import java.util.Set;
public class BuilderExample {
private long created;
private String name;
private int age;
private Set<String> occupations;
BuilderExample(String name, int age, Set<String> occupations) {
this.name = name;
this.age = age;
this.occupations = occupations;
}
private static long $default$created() {
return System.currentTimeMillis();
}
public static BuilderExampleBuilder builder() {
return new BuilderExampleBuilder();
}
public static class BuilderExampleBuilder {
private long created;
private boolean created$set;
private String name;
private int age;
private java.util.ArrayList<String> occupations;
BuilderExampleBuilder() {
}
public BuilderExampleBuilder created(long created) {
this.created = created;
this.created$set = true;
return this;
}
public BuilderExampleBuilder name(String name) {
this.name = name;
return this;
}
public BuilderExampleBuilder age(int age) {
this.age = age;
return this;
}
public BuilderExampleBuilder occupation(String occupation) {
if (this.occupations == null) {
this.occupations = new java.util.ArrayList<String>();
}
this.occupations.add(occupation);
return this;
}
public BuilderExampleBuilder occupations(Collection<? extends String> occupations) {
if (this.occupations == null) {
this.occupations = new java.util.ArrayList<String>();
}
this.occupations.addAll(occupations);
return this;
}
public BuilderExampleBuilder clearOccupations() {
if (this.occupations != null) {
this.occupations.clear();
}
return this;
}
public BuilderExample build() {
// complicated switch statement to produce a compact properly sized immutable set omitted.
Set<String> occupations = ...;
return new BuilderExample(created$set ? created : BuilderExample.$default$created(), name, age, occupations);
}
@java.lang.Override
public String toString() {
return "BuilderExample.BuilderExampleBuilder(created = " + this.created + ", name = " + this.name + ", age = " + this.age + ", occupations = " + this.occupations + ")";
}
}
}
답변
제 생각에는 별도의 클래스 대신 내부 정적 클래스를 얻는 가장 간단한 방법은 다음과 같습니다.
- 아직 생성자가없는 경우 생성자 생성 대화 상자를 사용하여 생성하십시오.
- 그런 다음 생성자를 빌더로 대체를 사용 하십시오.
- Move 리팩토링 (핫키 : F6)을 사용하여 새로 생성 된 클래스를 초기 클래스로 다시 이동합니다 .