규칙 2 생성자 인자가 많을 때는 Builder 패턴 적용을 고려하라.
Builder pattern은 객체에서 생성자에 들어갈 파라미터가 많든 적든 차례차례 파라미터를 받아들이고 모든 파라미터를 받은 뒤에 이 변수들을 통합해서 한번에 사용을 할 수 있다.
사진. 고도화된 빌더패턴
안드로이드에서도 이 패턴을 유용하게 많이 사용했는데, 이게 어떻게 이루어지고 사용을 했는지 몰랐다. AlertDialog가 그 예이다. 아래는 AlertDialog의 예시이다.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
AlertDialog.Builder builder = new AlertDialog.Builder(this); | |
builder.setTitle("종료 확인 대화 상자") .setMessage("앱을 종료 하시 겠습니까?").setCancelable(true) | |
.setPositiveButton("확인",new DialogInterface.OnClickListener() { | |
public void onClick(DialogInterface dialog,int whichButton) { | |
finish(); | |
} | |
} | |
).setNegativeButton("취소",new DialogInterface.OnClickListener() { | |
public void onClick(DialogInterface dialog,int whichButton) { | |
dialog.cancel(); | |
} | |
} | |
); | |
AlertDialog dialog = builder.create(); | |
dialog.show(); |
안드로이드를 하다보면 이 패턴을 자주보게 된다. AlertDialog 뿐만아니라 Uri, Geofence 등등 해당 패턴을 많이 사용하고 있다는 것을 알 수 있었다.
기존에는 오버로딩(Overloading)을 활용하여 객체를 생성했으나 이는 어떤 파라미터를 받는지 쉽게 알 수 없고, 유지보수가 힘들 다는 단점이 있다. 그 사례는 아래에서 볼 수 있다.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class Person { | |
private final string name; | |
private final string blood; | |
private final int age; | |
private final int hairColor; | |
public Person(string name, string blood) { | |
this(name, blood, 0, 0); | |
} | |
public Person(string name, string blood, int age) { | |
this(name, blood, age, 0); | |
} | |
public Person(string name, string blood, int hairColor) { | |
this(name, blood, 0, hairColor); | |
} | |
public Person(string name, string blood, int age, int hairColor) { | |
this.name = name; | |
this.blood = blood; | |
/..etc../ | |
} | |
public static void main(String args[]) { | |
Person somin = new Person("somin","A"); | |
Person wonYoung = new Person("won young","B",14); // what means 14? | |
Person hyunJun = new Person("hyun jun","C",12,124); // what means 12, 124? | |
} | |
} |
이와 같이 12,14,124가 어떤 파라미터인지 알아보려면 해당 클래스에 대해서 알아야 하며 또한, 생성자의 파라미터 위치가 바뀌게 되면 이미 생성한 모든 생성자도 바꿀뿐더러, 추가, 수정도 매우 어렵게 됨을 알 수 있다. 이것을 간단하게 Builder pattern을 활용하면 유지보수를 편하게 만들고 가독성도 좋게 만들 수 있다. 자세한것은 아래의 코드를 보고 판단 가능하다.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class Person { | |
private final string name; | |
private final string blood; | |
private final int age; | |
private final int hairColor; | |
public static class Builder { | |
private final string name; | |
private final string blood; | |
private int age; | |
private int hairColor; | |
public Builder(string name, string blood) { | |
//객체 생성에 반드시 받아야 하는 파라미터는 Builder에서 받음. | |
this.name = name; | |
this.blood = blood; | |
} | |
public Builder age(int age) { | |
this.age = age; | |
return this; | |
} | |
public Builder hairColor(int hairColor) { | |
this.hairColor = hairColor; | |
return this; | |
} | |
public Rects build() { | |
return new Person(this); | |
//마지막 build에서 완성. | |
} | |
} | |
public static void main(String args[]) { | |
//Person somin = new Person("somin","A"); | |
//Person wonYoung = new Person("won young","B",14); // what means 14? | |
//Person hyunJun = new Person("hyun jun","C",12,124); // what means 12, 124? | |
//with builder pattern | |
Person somin = new Person("somin","A"); | |
Person wonYoung = new Person("won young","B").age(14); | |
Person hyunJun = new Person("hyun jun","c").age(12).hairColor(124); | |
} | |
} |
End of Document
반응형
'개발이야기 > Effective Java' 카테고리의 다른 글
[Effective Java]실패 원자성 달성을 위해 노력하라 (0) | 2017.03.04 |
---|---|
[Effective Java]어떤 오류인지를 드러내는 정보를 상세한 메시지에 담으라 (0) | 2017.03.04 |
[Effective Java]메서드에서 던져지는 모든 예외에 대해 문서를 남겨라 (0) | 2017.03.04 |
[Effective Java]표준 예외를 사용하라 (0) | 2017.03.04 |
[Effective Java]불필요한 점검지정 예외 사용은 피하라 (0) | 2017.02.23 |
[Effective Java]예외는 예외적 상황에만 사용하라 (0) | 2017.02.22 |