๐๊ฐ์
๊ธฐ์กด ์ฝ๋๊ฐ ๋กฌ๋ณต์ @Builder๋ฅผ ์ฌ์ฉํ์ฌ ๋น๋ ํจํด์ ๊ตฌํํ๋๋ฐ, ์ฌ์ฉํ๋ค ๋ณด๋ ํ๋ ๊ฐ์ด ๋ง์ ์ง ๋, ๋์ถฉ ๋ง๊ฒ ์ง ํ๋ฉด์ ๊ฐ์ ์
๋ ฅํ๋๋, ๊ฐ๋ฐํ๋ค ๋ณด๋ Builder๋ฅผ ํตํด ์ธ์คํด์ค ์์ฑ์, ๋์ค์ null์ด ๋ค์ด๊ฐ๋ ๋ถ๋ถ์ด ๊ณ์ ์๊ฒจ๋ฌ๋ค. ๊ทธ๋ฅ ๋ด ์ค์๋ ค๋ ํ๊ณ ๋์ด๊ฐ๋ค๊ฐ ๋ฐ๋ณต๋๋, ์ด๊ฑด ์ฝ๋์ ๋ฌธ์ ๋ค ์ถ์ด์, ๊ฐ์ฒด ์ด๊ธฐํ ํ ๋, ๊ฐ๋จํ๊ฒ ํ์ ๊ฐ์ ๊ฒ์ฆํด์ผ๊ฒ ๋ค! ๋ผ๋ ์๊ฐ๋ถํฐ ์์๋๊ฒ ๋์๋ค.
์ด๋ฐ ์์ ์ฝ๋์ฒ๋ผ.. title์ ๋นผ๋จน๋๋ค๊ฑฐ๋…
๐ํด๊ฒฐ๋ฐฉ๋ฒ
1. ์ง์ Null ์ฒดํฌ
๊ฐ์ฅ ์ง์ ์ ์ธ ๋ฐฉ๋ฒ์ Null์ฒดํฌ ํ๋ ๋ฉ์๋๋ฅผ ์ค์ ๋ก ๋ง๋ค์ด์ ์ฒดํฌํ๋ ๋ฐฉ๋ฒ์ด๋ค.
class Post {
private final String title;
private final String content;
@Builder
private Post(String title, String content) {
checkNull(title, "title์ด Null์ผ ์ ์์ต๋๋ค.");
checkNull(content, "content๊ฐ Null์ผ ์ ์์ต๋๋ค.");
this.title = title;
this.content = content;
}
private void checkNull(Object o, String msg) {
if (o == null) {
throw new NullPointerException(msg);
}
}
}
์ฐ์ @AllArgsConstrucor๋ ์ธ์คํด์ค ์ ์ธ ์์์ ์ํฅ์ ๋ฐ๊ธฐ ๋๋ฌธ์ ์ง์ ์์ฑ์๋ฅผ ์์ฑํ์ฌ ์์ฑ์ ์์@Builder (lombok document ๊ถ์ฅ)๋ฅผ ๋ถ์ด๊ณ checkNull๋ฉ์๋๋ฅผ ๋ง๋ค์ด Null์ผ์ NullPointerException์ ๋ฐํํ๋๋ก ํ์๋ค..
๋ ๋์๊ฐ ํ๋ผ๋ฏธํฐ๊ฐ ๋ง์์ง๊ฑฐ๋ , ๊ฒ์ฆ ๋ฉ์๋๋ฅผ ๋ถ๋ฆฌํ๊ณ ์ถ๋ค๋ฉด,
class Post {
private final String title;
private final String content;
@Builder
private Post(String title, String content) {
checkNullParams(List.of(title, content));
this.title = title;
this.content = content;
}
private void checkNull(Object o) {
if (o == null) {
throw new NullPointerException();
}
}
private void checkNullParams(List<Object> params) {
params.forEach(this::checkNull);
}
}
์์ ๊ฐ์ด ์ฌ์ฉํ ์๋ ์์ ๊ฒ์ด๋ค.
2. ๋กฌ๋ณต์ @NonNULL์ฌ์ฉ
class Post {
private final String title;
private final String content;
@Builder
private Post(@NonNull String title, @NonNull String content) {
this.title = title;
this.content = content;
}
}
์์ฑ์์ ํ์ ๊ฐ ํ๋ผ๋ฏธํฐ ์์ @NonNull์ ๋ถ์ฌ ์์ฑ๋ ๋ ๋ณ์์ null์ ์ฒดํฌํ ์ ์๋ค.
Post p = Post.builder()
.title("t")
.build();
์์ ์ฝ๋์ ๊ฐ์ด content๊ฐ์ ๋นผ๋จน๋๋ค๋ฉด,
๋ค์๊ณผ ๊ฐ์ด NullPointerException์ ๋์ธ ๊ฒ์ด๋ค.
3. Assert ์ฌ์ฉ
class Post {
private String title;
private String content;
@Builder
private Post(String title, String content) {
Assert.notNull(title, "title์ด Null์ผ ์ ์์ต๋๋ค.");
Assert.notNull(content, "content๊ฐ Null์ผ ์ ์์ต๋๋ค.");
this.title = title;
this.content = content;
}
}
์คํ๋ง ์ ํธ์ ์๋ Assert์ notNull์ ํ์ฉํ ์๋ ์๋ค. ์์ ๊ฐ์ด ํ์ ๊ฐ์ Assert๋ก ๊ฒ์ฆ ํด๋ณผ ์ ์๋ค.
public static void notNull(@Nullable Object object, String message) {
if (object == null) {
throw new IllegalArgumentException(message);
}
}
Assert.notNull๋ฉ์๋๊ฐ ๋ค์๊ณผ ๊ฐ์ด ๊ตฌํ๋์ด ์์ผ๋ฉฐ, ๋ฉ์์ง๋ฅผ ์ค์ ํ ์ ์๋ค. ์ฌ์ค ์ง์ ๊ตฌํํ ์ฝ๋์ ๋ค๋ฅด์ง ์์ ํฐ ์ฐจ์ด๋ ์๋ค.
content๋ฅผ ์ ์ธํ๊ณ ์์ฑํ์ ๋ ๋จ๋ ์ค๋ฅ ๋ฉ์์ง๋ ๋ค์๊ณผ ๊ฐ๋ค.
๐์ ๋ฆฌ
๊ฐ๋จํ Null์ฒ๋ฆฌ๋ฅผ ํ ๋์๋ @NonNull์ ์ฌ์ฉํ๋ ๊ฒ์ด ์ฝ๋ ๋์ ์ค์ผ ์๋ ์๊ณ ๊ฐํธํด์ ์ ํฉํ ๊ฒ์ด๋ค.
์ํ๋ ์ค๋ฅ ๋ฉ์์ง๋ฅผ ์ถ๋ ฅํ์ฌ ์ค๋ฅ์ ๋ํ ๊ฐ๋
์ฑ์ ๋์ผ ๋, Assert๋ฅผ ์ฌ์ฉํ์ฌ ๊ตฌํํ๋ ๋ฐฉ๋ฒ์ด ์๋ค.
์์ธ์ ๋ํ ์ถ๊ฐ์ ์ธ ์ฒ๋ฆฌ๋ฅผ ํ ๋(ex. ์ปค์คํ
์์ธ๋ฅผ ๋์์ผ ํ๋ค๊ฑฐ๋ ๋ฑ)์ ์ง์ ๊ตฌํํ๋ ๋ฐฉ๋ฒ๋ ์๊ฐํด ๋ณผ ์ ์์ ๊ฒ ๊ฐ๋ค.