Open daminzzi opened 9 months ago
์ด์์์ ์ธ๊ธ๋ ๊ฒ์ฒ๋ผ, TO๋ Transfer Object
ํจํด์ ์๋ฏธํ๊ณ , ํจ๊ป ์ธ๊ธ์ด ๋๋ VO๋ Value Object
ํจํด์ ์๋ฏธํ๋ค. ์ด๋ฆ์์ ์ ์ถํ ์ ์๋ฏ์ด ํด๋น ํจํด๋ค์ ๋ฐ์ดํฐ๋ฅผ ์ ์กํ๊ธฐ ์ํ ๋์์ธ ํจํด์ด๋ค.
์ฌ์ค, VO ํจํด์ ๋ณ๊ฒฝ ๋ถ๊ฐ๋ฅํ ๊ฐ์ฒด๋ฅผ ๋ํ๋ด๋๋ฐ ์ฌ์ฉ๋๋ ๊ฐ์ฒด ์์ฑ ๋์์ธ ํจํด์ด๋ค. ์ผ๋ฐ์ ์ผ๋ก ์์ฃผ ๋ณ๊ฒฝ๋์ง ์๊ณ ๋จ์ผ ๋จ์๋ก ์ ๋ฌ๋ ์ ์๋ ๋ฐ์ดํฐ๋ฅผ ๋ํ๋ด๋๋ฐ ์ฌ์ฉ๋๋ค. ๋ ์ง
,ํตํ
,์๋
๋ฑ์ ๋ํ๋ผ ๋ ์ฌ์ฉํ ์ ์๋ค.
์กฐ๊ธ ๋ ๊ฐ๋ฐ์ ์ผ๋ก ์ด์ผ๊ธฐํ๋ฉด, Client์์ ๋ณด๋ด๋ Request
๋ ๋ฐฑ์๋์์ ๋ณ๊ฒฝํ ์ผ์ด ์์ผ๋ฏ๋ก ์ด๋ฅผ VO๋ก ๋ฐ์ ์ ์๋ค.
ํ์ง๋ง, ์ค์ ๋ก๋ ๋ช ํํ ๊ตฌ๋ถ๋ ์๊ณ ์๊ฒฉํ๊ฒ ๋๋์ง๋ ์๋๋ค. ๊ฐ๋ฐ์๋ง๋ค ๊ฐ์ฒด๋ฅผ ๊ตฌ๋ถํ๊ณ ์ ์ํ๋ ์คํ์ผ์ด ๋ฌ๋ผ์ DB์์ ๋ฐ์ดํฐ๋ฅผ ๊บผ๋ด์ฌ ๋ DTO๋ฅผ ์ฐ๋ ๊ฒฝ์ฐ๋ ์๊ณ , VO๋ฅผ ์ฐ๋ ๊ฒฝ์ฐ๋ ์๋ค. ๋, VO๋ฅผ ๋ถ๋ณ์ผ๋ก ์ฐ์ง ์๋ ๊ฒฝ์ฐ๋ ๋ง๋ค.
๊ทธ๋์ ์๋ ๋ด์ฉ์์๋, TO ํจํด์ ๊ธฐ์ค์ผ๋ก ์ค๋ช ํ๊ณ ์ ํ๋ค.
Transfer Object
๋ฅผ ๋ง๋ค์ด ํ๋์ ๊ฐ์ฒด๋ฅผ ํตํด ์ฌ๋ฌ ํ์
์ ๊ฐ์ ์ ๋ฌํ๋ ๊ฒ์ด TO ํจํด์ ๋ชฉ์ ์ด๋ค. ์ด๋ฅผ ์ฌ์ฉํ๋ค๊ณ ์์ฒญ๋ ์ฑ๋ฅ ๊ฐ์ ํจ๊ณผ๊ฐ ๋ฐ์ํ๋ ๊ฒ์ ์๋์ง๋ง, ํ ๊ฐ์ฒด์ ๊ฒฐ๊ณผ ๊ฐ์ ๊ฐ์ ธ์ฌ ์ ์๊ธฐ ๋๋ฌธ์ ์ฌ๋ฌ ๋ฒ ์์ฒญ์ ์ค์ฌ์ฃผ๋ฏ๋ก ํด๋น ํจํด ์ฌ์ฉ์ด ๊ถ์ฅ๋๋ค.
๋ํ, ์์ฑ ๊ฐ์ด null
์ธ ๊ฒฝ์ฐ ๊ธธ์ด๊ฐ 0์ธ String์ return ํ๋ ๋ฑ Transfer Object
๋ฅผ null
์ฒ๋ฆฌ ๊ณผ์ ์ ํธํ๊ฒ ํ ๋๋ ์ฌ์ฉํ ์ ์๋ค.
DTO๋ Data Transfer Object
์ ์ค์๋ง๋ก, ๊ณ์ธต๊ฐ ๋ฐ์ดํฐ ์ ์ก์ ์ํ JavaBeans์ ์๋ฏธํ๋ค. DAO
(Data Access Object) ํจํด์์ ์ ๋๋ ๋จ์ด๋ก, DAO
์์ DB ์ฒ๋ฆฌ ๋ก์ง์ ์จ๊ธฐ๊ณ DTO
๋ผ๋ ๊ฒฐ๊ณผ๊ฐ์ ๋ด๋ณด๋ด๋ ์ฉ๋๋ก ํ์ฉ๋๋ค.
๋น์ฆ๋์ค ๋ก์ง์ ๊ฐ์ง์ง ์๊ณ , ๋ฐ์ดํฐ๋ฅผ ์ ์กํ๋๋ฐ ํ์ํ getter
์ setter
๋ฉ์๋๋ง ๊ฐ์ง๋ ๋จ์ํ ๊ฐ์ฒด์ด๋ค.
Controller ๊ฐ์ ํด๋ผ์ด์ธํธ๋จ๊ณผ ์ง์ ๋ง์ฃผํ๋ ๊ณ์ธต์์๋ DTO
๋ฅผ ์ฌ์ฉํด์ ๋ฐ์ดํฐ๋ฅผ ๊ตํํ๋ฉฐ, Controller ์ธ์๋ ์ฌ๋ฌ ๋ ์ด์ด ์ฌ์ด์์ DTO๋ฅผ ์ฌ์ฉํ ์ ์๋ค.
๊ทธ์น๋ง ์ฃผ๋ก View์ Controller ์ฌ์ด์์ ๋ฐ์ดํฐ๋ฅผ ์ฃผ๊ณ ๋ฐ์ ๋ ํ์ฉ์ฑ์ด ๋๋ค.
์ถ๊ฐ๋ก, DTO๋ JSON serialization ๊ณผ ๊ฐ์ ์ง๋ ฌํ์๋ ์ฌ์ฉ๋๋ค.
public class GillogTO implements Serializable {
private String name;
private String id;
public GillogTO() {
super();
}
public GillogTO(String name, String id) {
super();
this.name = name;
this.id = id;
}
public String getName() { return name;}
public String getID() { return id; }
public void setName(String name) { this.name = name;}
public void setID(String id) { this.id = id;}
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("name=")
.append(name)
.append("id=")
.append(id)
return sb.toString();
}
}
@Getter
@NoArgsConstructor
public class PostssaveRequestDto{
private String title;
private String content;
private String author;
@Builder
public PostsSaveRequestDto(String title,String content,Strign author) {
this.title = title;
this.content = content;
this.author = author;
}
public Posts toEntity() {
return Posts.builder().title(title).content(content).author(author).build();
}
}
Entity ํด๋์ค๋ ์ค์ DB
ํ
์ด๋ธ๊ณผ ๋งคํ๋๋ ํต์ฌ ํด๋์ค๋ก, DB ์ปฌ๋ผ๋ค์ ํ๋๋ก ๊ฐ์ง๋ ๊ฐ์ฒด์ด๋ค.
๋ฐ์ดํฐ๋ฒ ์ด์ค ์์์ฑ ์ ๋ชฉ์ ์ผ๋ก ์ฌ์ฉ๋๋ ๊ฐ์ฒด๊ธฐ ๋๋ฌธ์, ์์ฒญ์ด๋ ์๋ต๊ฐ์ ์ ๋ฌํ๋ ํด๋์ค๋ก ์ฌ์ฉํ๋ ๊ฒ์ ์ข์ง ์๋ค.
๋ํ, ๋ง์ ์๋น์ค ํด๋์ค์ ๋น์ฆ๋์ค ๋ก์ง๋ค์ด Entity ํด๋์ค๋ฅผ ๊ธฐ์ค์ผ๋ก ๋์ํ๊ธฐ ๋๋ฌธ์ Entity ํด๋์ค๊ฐ ๋ณ๊ฒฝ๋๋ฉด ์ฌ๋ฌ ํด๋์ค์ ์ํฅ์ ์ค ์๋ ์๋ค.
Entity ํด๋์ค๋ฅผ ๊ธฐ์ค์ผ๋ก ํ ์ด๋ธ์ด ์์ฑ๋๊ณ ์คํค๋ง๊ฐ ๋ณ๊ฒฝ๋๋๋ฐ, ํ๋ฉด ๋ณ๊ฒฝ ๋ฑ์ ์ฌ์ํ ๊ธฐ๋ฅ ๋ณ๊ฒฝ์ ์ํด ํ ์ด๋ธ๊ณผ ์ฐ๊ฒฐ๋ Entity ํด๋์ค๋ฅผ ๋ณ๊ฒฝํ๋ ๊ฒ์ ๋๋ฌด๋ ํฐ ๋ณ๊ฒฝ์ด ๋๋ค.
๋ํ, View Layer
์ DB Layer
์ ์ญํ ์ ์ฒ ์ ํ๊ฒ ๋ถ๋ฆฌํ๋ ๊ฒ์ด ์ข๋ค. ํ์ง๋ง ์ค์ ๋ก๋ Controller
์์ ๊ฒฐ๊ณผ๊ฐ์ผ๋ก ์ฌ๋ฌ ํ
์ด๋ธ์ ์กฐ์ธํด์ ์ค์ผํ๋ ๊ฒฝ์ฐ๊ฐ ๋น๋ฒํ๋ฏ๋ก Entity ํด๋์ค๋ง์ผ๋ก ํํํ๊ธฐ ์ด๋ ค์ด ๊ฒฝ์ฐ๊ฐ ๋ง๋ค.
ํ๋ผ๋ฏธํฐ๋ก Entity ์์ฒด๋ฅผ ๋ฐ๊ฒ ๋๋ฉด, Entity์์ ์ ํด์ง ํฌ๋งท์ ๋ง์ถฐ ๊ฐ๋ฐํด์ผ ํ๋ค. ํ์ง๋ง, DTO๋ ๊ฐ ๋น์ฆ๋์ค ๋ก์ง์ ๋ง์ถ ํ๋๋ค๋ง ์์ฑ์ด ๊ฐ๋ฅํ๋ฏ๋ก DTO๋ฅผ ๋ณด๋ฉด ์ด๋ค ๊ฐ๋ค์ด ๋งคํ๋๋์ง ์ฝ๊ฒ ํ์ ํ ์ ์๋ค. ๋ํ, API ์ค๊ณ ์ํฉ์์ ํ๋์ ๋ค๋ฅธ ์ด๋ฆ์ ๋ถ์ฌํ๋ ์ํฉ์๋ ์ ์ฐํ๊ฒ ๋์ฒํ ์ ์๋ค.
Service๊ฐ ๋ฐ๊ณ ์ถ์ ํ๋ผ๋ฏธํฐ๊ฐ Controller์๊ฒ ์ข ์์ ์ด๋ฉด Service๊ฐ Controller ํจํค์ง์๊ฒ ์์กดํ๊ฒ ๋๋ค. ์ด๋ฅผ ๋ฐฉ์งํ๊ธฐ ์ํด์ Service๊ฐ ์ํ๋ ํฌ๋งท์ ๋ง์ถฐ Controller๋จ์์ DTO๋ฅผ ํตํด ํฌ๋งท์ ๋ง์ถฐ์ฃผ๋ ๊ฒ์ด๋ค.
์์ ๊ฐ์ ๊ฒฝ์ฐ, Service ๋ ์ด์ด๊ฐ Controller ๋ ์ด์ด DTO์ ์์กดํ๊ณ ์๋ค๋ฉด ๋ฌธ์ ๊ฐ ๋ ์ ์๋ค. ๋ฐ๋ผ์, Service ๋ ์ด์ด๋ ์์ ์ด ์ํ๋ ํฌ๋งท์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ๋ฐ์ ์ ์์ด์ผ ํ๋ค.
DTO ๋ฅผ ์ด๋ ์์ญ์์ ์ด๋ ์ ๋๋ก ์ฌ์ฉํด์ผ ํ๋๊ฐ?
DTO์ ์ฌ์ฉ ๋ชฉ์ ์ Client
์ Controller Layer
๊ฐ ์ค๊ณ๋ง ๋ด๋นํ๋ ๊ฒ์ด๊ธฐ ๋๋ฌธ์, Service Layer
๋ก ๋์ด๊ฐ๋ ๊ฐ์ฒด๋ Entity
๊ฐ์ฒด์ฌ์ผ ํ๋ค.
Service
๋ก์ง์์ ์ด๋ค ์์
์ ํ ๋, Entity
๊ฐ 2๊ฐ ์ด์ ํ์ํ๋ค๋ฉด, Controller
์์ ์ฌ๋ฌ Entity
๋ค์ ๋ชจ์ DTO๋ฅผ Service
์ ๋๊ฒจ์ฃผ๋ฉด ๋๊ธฐ ๋๋ฌธ์ Controller
๊ฐ Service
์ ์์กด์ ์ด์ง ์๋ ์ฅ์ ์ด ์๋ค.
DTO๋ฅผ Service
์ ๋๊ธฐ์ง ์์ผ๋ฉด, Response
์ ํฌํจ๋ ํ์๊ฐ ์๋ ํ๋๊น์ง Controller
์ ๋ค์ ResponseDTO
๋ก ๋์๊ฐ๊ฒ ๋์ด ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ค.
Entity์์๋ ๊ฐ์ฒด์ ์ผ๊ด์ฑ, ์์ ์ฑ์ ๋ณด์ฅํ๊ธฐ ์ํด setter
๋ฉ์๋์ ์ฌ์ฉ์ ์ง์ํด์ผ ํ๋ค. ๋ฐ๋ผ์, setter
๋์ Constructor
๋๋ Builder
๋ฅผ ์ฌ์ฉํด์ผํ๋ค.
Constructor
๋ฅผ ์ด์ฉํด์ ์ด๊ธฐํํ๋ ๊ฒฝ์ฐ, ๋ถ๋ณ ๊ฐ์ฒด๋ก ํ์ฉํ ์ ์๊ณ , ๋ถ๋ณ ๊ฐ์ฒด๋ก ๋ง๋ค๋ฉด ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ๋ ๊ณผ์ ์์ ๋ฐ์ดํฐ๊ฐ ๋ณ์กฐ๋์ง ์์์ ๋ณด์ฅํ ์ ์๋ค.
Builder
๋ฅผ ์ฌ์ฉํ๋ฉด, ๋ฉค๋ฒ ๋ณ์๊ฐ ๋ง์์ง๋๋ผ๋ ์ด๋ค ๊ฐ์ ์ด๋ค ํ๋๋ฅผ ๋ฃ๋์ง ์ฝ๋๋ฅผ ํตํด ํ์ธ์ด ๊ฐ๋ฅํ๋ค. ๋ํ, ํ์ํ ๊ฐ๋ง ๋ฃ๋ ๊ฒ์ด ๊ฐ๋ฅํ๋ค๋ ๊ฒ๋ ์ฅ์ ์ด๋ค.
@Builder
@Getter
@Entity
@NoArgsConstructor
public class Membmer { @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long idx;
private String name;
private String email;
public Member(Long idx, String name, String email) {
this.idx = idx;
this.name = name;
this.email = email;
}
}
// ์ฌ์ฉ ๋ฐฉ๋ฒ
Member member = Member.builder()
.name("Jan")
.email("Jan@Jan.com")
.build();
https://akku-dev.tistory.com/26 https://velog.io/@gillog/Transfer-Object-Pattern https://wildeveloperetrain.tistory.com/m/101 https://wildeveloperetrain.tistory.com/101 https://velog.io/@pjy05200/DTO%EC%99%80-Entity-Class%EC%9D%98-%EC%B0%A8%EC%9D%B4 https://studyandwrite.tistory.com/402
๐ ๋ฌธ์
๊ต์ฌ
p.426
์์๋ผ๋ ๋ฌธ์ฅ์ ๋ง๋ ์ ์๋ค. TO..? VO..? ์ด๋ณด๋ผ ์ฃ์กํฉ๋๋ค. ์๋ชป ์์๋ค์์ต๋๋ค.. ๊ตฌ๊ธ์ ๊ฒ์ํด๋ณด๋ Transfer Object Pattern์ด๋ผ๊ณ ํ๋ค. ๊ทธ๋ฆฌ๊ณ ํจ๊ป ๋ง์ด ๋ด์ฉ์ผ๋ก๋ ํด๋น ํจํด๊ณผ DB์์์ Entity์์ ์ฐจ์ด์ ๋ํด์ ๋ค๋ฃฌ ๊ธ๋ ๋ง์๋ค. ๊ทธ๋ผ ์ฌ๊ธฐ์ ๋ฌธ์
โ๏ธ ์ ์ ๋ฐฐ๊ฒฝ
์์ ์์ DTO๋ ๋ค์ด๋ดค๋๋ฐ ์ด๋ฐ ๊ฒ๋ ํจํด์ธ์ง ์ด์ ์์๋ค. ์ด๋ฏธ ์๊ณ ์์ง๋ง ๋ช ํํ๊ฒ ๋ค๋ค๋ณธ์ ์ ์์์ง๋..?
๐บ ๊ด๋ จ ์ฑํฐ ๋ฐ ๋ ํผ๋ฐ์ค
ch24. ์ ํ๋ฆฌ์ผ์ด์ ์์ ์ ๊ฒํด์ผ ํ ๋์๋ค
๐ณ ๋น๊ณ
๋ง์ง๋ง๊น์ง ํ์ดํ !