๐ ํ ์ด ํ๋ก์ ํธ - 1 ๊ฐ์
โ๏ธํ๋ก์ ํธ ๋ด์ฉ
์ฌํ ๊ธฐ๋ก/์กฐํํ๋ Java ์ฝ์ ์ดํ๋ฆฌ์ผ์ด์
โ๏ธํ๋ก์ ํธ ์ฃผ์ ๋ฐ ํ์ ๊ตฌํ ๊ธฐ๋ฅ ์ ์
์ผ๋์
โ๏ธํ๋ก์ ํธ ๋ชฉํ
1๋จ๊ณ ๋ฌ์ฑ ๋ชฉํ: Java ๋ฌธ๋ฒ, ํ์ผ ์
์ถ๋ ฅ, ์์ธ์ฒ๋ฆฌ, ํด๋์ค ์ค๊ณ
1) ์ฌํ์ ์ฌ์ ์ ๋ณด๋ฅผ ๊ธฐ๋กํ๊ณ ์กฐํํ๋ Java ์ ํ๋ฆฌ์ผ์ด์
๊ฐ๋ฐ
2) ๊ฐ๋ณ ์ฌํ์ ๋ณต์์ ์ฌ์ ์ ๋ณด๋ก ๊ตฌ์ฑ๋จ (์ฌํ : ์ฌ์ = 1 : n)
3) ์ฌ์ ์ ๋ณด๋ ์ด๋ (์ถ๋ฐ์ง, ๋์ฐฉ์ง, ์ถ๋ฐ์๊ฐ, ๋์ฐฉ์๊ฐ)๊ณผ ์๋ฐ(์ฒดํฌ์ธ, ์ฒดํฌ์์)
๋ฑ์ ์ ํ์ด ์์ ์ ์์
4) ์ฌํ ์ ๋ณด์ ํน์ ์ฌํ ์ ๋ณด์ ์ฌ์ ๋ชฉ๋ก์ ๋ฐ์ดํฐ ์ ์ฅ ๊ฒฝ๋ก์ ํ์ผ ํํ๋ก ์
์ฅ (CSV, json ๋ฑ)
โ๏ธํ๋ก์ ํธ ๊ธฐ๊ฐ
2023๋ 9์ 4์ผ(์)~9์ 8์ผ(๊ธ)
โ๏ธํ๋ก์ ํธ ์ ์์
1. ํ์์ ์ฌ๋ฌ ์ฌํ ๊ธฐ๋ก์ ์ ์ฅํ ์ ์์ต๋๋ค. ํ์ ๊ฐ์
์ ๋ค์ ๋จ๊ณ์์ ๊ณ ๋ คํ๊ณ ๋ณธ ํ๋ก์ ํธ๋ ์ฌํ๊ณผ ์ฌ์ ์ ๊ธฐ๋กํ๊ณ ์กฐํํ๋ ๊ธฐ๋ฅ์ ๊ตฌํํ๊ธฐ๋ก ํ๋ค.
2. ์ฌํ์๋ ์ฌ๋ฌ ์ฌ์ ์ด ์์ ์ ์์ต๋๋ค. ์ฌ์ ์ ๋ณด๋ ์ด๋์ ๋ณด(์ถ๋ฐ์ง, ๋ชฉ์ ์ง, ์ถ๋ฐ์๊ฐ, ๋์ฐฉ์๊ฐ), ์๋ฐ์ ๋ณด(์ฒดํฌ์ธ, ์ฒดํฌ์์) ๋ฑ์ ์ข
๋ฅ๋ฅผ ํฌํจํ ์ ์๋ค.
3. ํ์์ ์ฌํ๊ธฐ๋ก ๋ชฉ๋ก์ด ์ถ๋ ฅ๋๋ฉฐ, ๊ฐ ์ฌํ๊ธฐ๋ก ๋ชฉ๋ก์ ์ ํํ๋ฉด ์์ธํ ์ฌ์ ๊ธฐ๋ก์ด ์ถ๋ ฅ๋๋ค.
4. ํ์ ๋ฐ ์ฌํ๊ธฐ๋ก์ ํฅํ ๋ฐ์ดํฐ๋ฒ ์ด์ค ํ
์ด๋ธ๋ก ๊ด๋ฆฌ๋์ด ์ง๋ 1๋จ๊ณ ํ๋ก์ ํธ์์๋ ์ฌํ๋ณ ์ฌ์ ์ ๋ณด๋ json์ด๋ csv ํ์ผ๋ก ๊ด๋ฆฌ๋๋ค.
โ๏ธ ์ปจ๋ฒค์
GitHub Flow
- ๋ธ๋์น ์ ๋ต์ผ๋ก GitHub Flow๋ฅผ ์ฌ์ฉํฉ๋๋ค.
- ๋ชจ๋ ํ์์ Approve๋ฅผ ๋ฐ์์ผ main์ Merge ํ ์ ์์ต๋๋ค.
์ฝ๋ฉ ์ปจ๋ฒค์
- ๊ตฌ๊ธ ์ฝ๋ฉ ์ปจ๋ฒค์
์ ์ฌ์ฉํฉ๋๋ค.
์ปค๋ฐ ๋ฉ์์ง ์ปจ๋ฒค์
- ์ปค๋ฐ ์ ๋ชฉ์ prefix: ์ปค๋ฐ ๋ฉ์์ง ํํ๋ก ํฉ๋๋ค.
- prefix์ ๋ชฉ๋ก๊ณผ ๊ฐ๊ฐ์ ์ฉ๋๋ IntelliJ ํ๋ฌ๊ทธ์ธ์์ ๋ณผ ์ ์์ต๋๋ค.
- ์ปค๋ฐ ๋ด์ฉ์ ์์ธํ๊ฒ ์ ์ต๋๋ค. (์ปค๋ฐ ์ ๋ชฉ๊ณผ ๋ด์ฉ๋ง ๋ณด๋๋ผ๋ ์ฝ๋ ๋ด์ฉ์ด ํ์ ๊ฐ๋ฅํ ์ ๋๋ก)
๊ธฐํ ํฉ์์ฌํญ
- ํ์ ๊ด๋ จ
- ๋ฐ์ผ๋ฆฌ ์คํฌ๋ผ: ํ์ผ 10:00~10:10์ ๋ชจ์ฌ์ ๊ฐ์์ ์งํ์ํฉ ๊ณต์
- ์ ๊ท์๊ฐ์๋ Zoom, ๋๋ ํ์๋ Discord์์ ์์ ๋ชจ๊ฐ์ฝ (ํ์ฐธ ์๋)
- ์ถ๊ฐ ์ฝ๋ฉ ์ปจ๋ฒค์
- ๋ชฉ๋ก์ ๊ฐ์ ธ์ฌ ๋๋ get ๋์ฌ๋ฅผ ์ด๋ค.
- class/enum/interface/record ์ ์ ์ ๋งจ ์์ค์๋ ์ค๋ฐ๊ฟ์ ๋ฃ๊ณ , ๋งจ ์๋ ์ค์ ๋ฃ์ง ์๋๋ค.
โ๏ธ ๊ธฐํ
๊ธฐ์ ์คํ
- ์ธ์ด: Java 17
- ๊ฐ๋ฐ ํ๊ฒฝ: IntelliJ, Gradle
- ๋ผ์ด๋ธ๋ฌ๋ฆฌ: JUnit5, lombok, Jackson
- CI: GitHub Actions
ํจํค์ง ๋ฐ ํด๋์ค ๊ตฌ์ฑ
๋๋ฉ์ธ
Trip.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
|
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@ToString(exclude = "itineraries")
public class Trip {
private Long id;
private String name;
private LocalDate startAt;
private LocalDate endAt;
private final List<Itinerary> itineraries = new ArrayList<>();
@Builder
private Trip(
Long id,
String name,
LocalDate startAt,
LocalDate endAt
) {
this.id = id;
this.name = name;
this.startAt = startAt;
this.endAt = endAt;
}
public void setId(Long id) {
this.id = id;
}
public void addItinerary(Itinerary itinerary) {
itineraries.add(itinerary);
}
}
|
cs |
Itinerary.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
|
import java.time.LocalDateTime;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@ToString(exclude = "trip")
public class Itinerary {
private Long id;
private Route route;
private Lodge lodge;
private Trip trip;
@Builder
private Itinerary(
Long id,
String departure,
String destination,
LocalDateTime departureAt,
LocalDateTime arriveAt,
String accommodation,
LocalDateTime checkInAt,
LocalDateTime checkOutAt,
Trip trip
) {
this.id = id;
this.route = new Route(departure, destination, departureAt, arriveAt);
this.lodge = new Lodge(accommodation, checkInAt, checkOutAt);
this.trip = trip;
}
public void setId(Long id) {
this.id = id;
}
public void setTrip(Trip trip) {
this.trip = trip;
}
}
|
cs |
์ต๋ํ ๋๋ฉ์ธ ์ฃผ๋ ์ค๊ณ(DDD)๋ฅผ ์งํค๊ธฐ ์ํ์ฌ ๋ฐ์ ๋ฐ์ดํฐ๋ ์ฎ๊ธธ ๋ DTO์ ๋ด์ ์ฎ๊ธฐ๊ณ ์ต์ข ํ์ผ์ ์ ๊ทผํ ๋ ๋๋ฉ์ธ์ ๋ด์์ ๋ณด๋ด์ค๋ค.
ํ ์ดํ๋ก์ ํธ1์์ DB์ ์ฐ๋ํ์ง ์๊ณ File์ ์ ์ฅ ํ๊ธฐ ๋๋ฌธ์ Service์์ File์ ์ ๊ทผํ ๋ ๋๋ฉ์ธ์ ๋ด์ ๋ณด๋ด์ฃผ์๋ค.
DTO๋ JDK16 ์ด์๋ถํฐ ์ ์ ์ ๊ณตํ๋ record๋ฅผ ์ฌ์ฉํ์ฌ ๋ง๋ค์๋ค.
ItinerarySaveRequest.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
import java.time.LocalDateTime;
import lombok.Builder;
@Builder
public record ItinerarySaveRequest(
String departure,
String destination,
LocalDateTime departureAt,
LocalDateTime arriveAt,
String accommodation,
LocalDateTime checkInAt,
LocalDateTime checkOutAt
) {
public ItinerarySaveRequest {
if ((departureAt == null && arriveAt == null)
&& (checkInAt == null && checkOutAt == null)) {
throw new IllegalArgumentException();
}
}
}
|
cs |
๋ ์ฝ๋๋ ํ๋ ์ ํ๊ณผ ์ด๋ฆ๋ง ํ์ํ ๋ถ๋ณ ๋ฐ์ดํฐ ํด๋์ค์ด๋ค.
equals, hashcode, tostring ๋ฉ์๋์ private, final field, public constructor๋ Java ์ปดํ์ผ๋ฌ์ ์ํด ์์ฑ๋๋ค. ๋ํ getter() ๋ ๋ง๋ค์ด ์ฃผ์ด ํ๋ ๊ฐ์ ๊ฐ์ ธ์ฌ๋ . ์ฐ๊ณ ํ๋๋ช ์ ์ฐ๋ฉด ๋๋ค.
์์)
1
2
3
4
5
6
7
8
9
10
11
12
|
private Itinerary convertDtoToItinerary(Trip trip, ItinerarySaveRequest itinerarySaveRequest) {
return Itinerary.builder()
.trip(trip)
.departure(itinerarySaveRequest.departure())
.destination(itinerarySaveRequest.destination())
.departureAt(itinerarySaveRequest.departureAt())
.arriveAt(itinerarySaveRequest.arriveAt())
.accommodation(itinerarySaveRequest.accommodation())
.checkInAt(itinerarySaveRequest.checkInAt())
.checkOutAt(itinerarySaveRequest.checkOutAt())
.build();
}
|
cs |
๋ฐ์ดํฐ ํ๋ฆ
- ์ ์ฅ์
๋ทฐ์์ ์ฝ์์์ ๋ฐ์ ์ ๋ ฅ๊ฐ์ ์ฌํ ๋๋ ์ฌ์ ์ ๋ง๋ SaveRequest DTO์ ๋ด์์ Controller๋ก ๋ณด๋ด์ค๋ค. Controller์์ ๋ฐ์ DTO๋ฅผ Service๋ก ๋๊ฒจ์ฃผ๊ณ Service์์ DTO๋ฅผ Domain์ผ๋ก ๋ณํํด์ค ๋ค ํ์ผ ์ ์ฅ ์์คํ ์ผ๋ก ๋ณด๋ด์ฌ ๊ฐ์ ํ์ผ(JSON/CSV)์ ์ ์ฅํ๋ค.
- ์กฐํ์
๋ทฐ์์ ์ฝ์์์ ์กฐํํ๊ณ ์ถ์ FileType์ ๋ฐ๋๋ค. JSON/CSV ํด๋น ํ์ผ์ ๋ง๋ ๊ฐ์ ID๋ก ์ฐพ์์จ๋ค. ์กฐํํ์ฌ ๋์จ ๋ฐ์ดํฐ๋ฅผ Domain์์ Response DTO๋ก ๋ณ๊ฒฝํ๊ณ ๋ทฐ์์ ๋ฐ์ดํฐ ๊ฐ์ ๋ณด์ฌ์ค๋ค.
๐ช์คํ ํ๋ฉด
๐คํ ํ๊ณ
ํ ์ดํ๋ก์ ํธ๊ฐ ๋๋๊ณ ๊ทธ ์ฐจ์ฃผ ํ์์ผ์ ๋ค ๊ฐ์ด ์ค์์ ๋ง๋์ 1์๊ฐ ๊ฐ๋ ํ ํ๊ณ ๋ฐ ํผ๋๋ฐฑ์ ์งํํ์๋ค.
์กฐ๊ธ ํ๋ค์๋ค.
- ์ฝ๋๋ฆฌ๋ทฐ ํ๋๊ฒ
- SOLID ๋ค ์งํค๋ฉด์ ํ๋๊ฒ
- ํ์
์ด ์ฒ์์ด๋ผ
- ์ปจ๋ฒค์
๊ฐ์ ๊ฒ์ด ์ฒ์์ด๋ผ
- Git/GitHub ์ ์ํ๋๊ฒ
- ๊ณต๋ถ๊ฐ ํ์ํ ๊ฒ ๊ฐ๋ค
- ๊ธฐ๋ฅ์ด ๊ฒน์ณ์ ์ถฉ๋์ด ๋๋ฌด ์ฆ์๋ค
- ๊ธฐ๋ฅ์ด ์ผ๋ง ์๋๋ฐ ์ฌ๋๋ง ๋ง์์
์์ฌ์ ๋ค.
- ์ฝ๋ฉ์ปจ๋ฒค์
, ํ
์คํธ, ์ฝ๋๋ฆฌ๋ทฐ, Git Flow
- ์๊ฐ์ด ์์ด์ ํ , ์ผ Free
- ๋ค์ ํ์ 2๊ฐ => 1์ฃผ
์ฝ๋๋ฆฌ๋ทฐ ๋ฐ์ ๋ค ์ฐ๋ฆฌ๋ผ๋ฆฌ ๋ฆฌํฉํ ๋ง ํด๋ณด์
- ์๋น์ค ๋ก์ง ์ ๋ ์ง๋ณด๋ฉด ์ข์ ๋ฏ
'์ฝ์์์
'์ธ๋ฐ ๋งค์ฐ ๋ํญ์ด ๋ง์๋ค.
๋ค์ ํ์ ์ SpringBoot, DB, REST API์ธ๋ฐ ๊ธฐ๊ฐ ๋๊ฐ์๋ฐ, ๊ด์ฐฎ์๊น?
1. ์ด๋๋ก ๊ด์ฐฎ๋ค. ๊ทธ๋๋ก ๊ฐ์
- ์ด๋ฒ ํ๋ก์ ํธ๊ฐ ํน์ํ ์ํฉ์ด์๋ค. ๋ค์์ ๊ด์ฐฎ์ ๊ฑฐ๋ค. (์ค๊ณ์ ๋๋ฌด ๋ง์ ์๊ฐ์ ์์, ์ฒ์์ธ ํ์
)
- ์คํ๋ ค ์ค๊ณ๋ฅผ ์ฒ์์ ์ ํด๋๊ธฐ ๋๋ฌธ์ ์ดํ๋ง์ ์์ฑํ ์ ์์๋ ๊ฑฐ๋ผ ์๊ฐํ๋ค.
2. ๋ญ๊ฐ ์ฐ๋ฆฌ๋ผ๋ฆฌ ์ฐ์ต์ ํด๋ณด์
- ํ ์ดํ๋ก์ ํธ ์ฝ๋๋ฆฌ๋ทฐ ํผ๋๋ฐฑ์ ๋ํ ๋ฆฌํฉํ ๋ง
- ํ
์คํธ ๊ณต๋ถ๋ ํ์ํ ๊ฒ ๊ฐ๋ค. (์ถํ์ JUnit์ ์จ์ผ๋ง ํจ)
- ๋ฏธ๋ฆฌ ๊ณต๋ถํด์ผ ํ๋ ๊ฒ๋ค์ ์ ๋ฆฌํด๋๋ฉด ์ข์ ๊ฒ ๊ฐ๋ค
์ข ๋ ๊ณต๋ถ ํด๋ณผ ๊ฒ
์ฝ๋ฉ ์ปจ๋ฒค์
, ํ
์คํธ ์ปจ๋ฒค์
Git Flow(์ฝ๋๋ฆฌ๋ทฐ)
์ฐฌ์๋ ์ง์ธ ์ถ์ฒ ์ฑ
- ๋จ์ํ
์คํธ
- ๋ ๊ฑฐ์ ์ฝ๋ ํ์ฉ ์ ๋ต (์ค๋๋จ)
๋ค์ ํ๋ก์ ํธ ์ ๊น์ง ํด๋ณผ ๊ฒ
(ํ์) 1. ๊ธฐ์กด ์ฝ๋์ ๋ํด => ๋ฆฌํฉํ ๋ง & ํ
์คํธ ์ฝ๋ ์ถ๊ฐ ๊ฐ์ PR
(๊ถ์ฅ) 2. ํ๋ก์ ํธ1๋ฅผ ๊ธฐ๋ฐ์ผ๋ก SpringBoot, DB, REST API ์ฑ ๋ง๋ค๊ธฐ (JPA ์ด์ฉํด์ ๋ฐ์์จ DB ์ ๋ณด๋ฅผ ํ ๋๋ก json ์๋ตํ๋ ๋ฉ์๋ 1๊ฐ
ํด๋์ค ์ค๊ณ๊น์ง ์๋ฒฝํ๊ฒ ํ๊ณ , ์ต๋ํ ๊ฐ์ฒด์งํฅ์ ์ผ๋ก SOLID ์ง์ผ๊ฐ๋ฉฐ ํ๋ก์ ํธ์ ์ํ๋ ค๊ณ ํ๋๊น ์ค๊ณํ๋ ๋ถ๋ถ์ ๋ง์ ์๊ฐ์ ์์ํ๋ค. ํนํ๋ MVC๋ ๊ฐ์ฒด ์งํฅ์ ์ธ ๋ถ๋ถ์์ ๋ฐฐ์ด์ ์ด ๋ง์๋ค.
๊ฐ์ฒด๋ฅผ ๋ฐ๋ผ๋ณผ ๋ ํญ์ DB์ ์ฐ๋ํ๋ ์ข ์ ๊ด๊ณ๋ฅผ ์๊ฐํ์ ๋ ์ฌํ์ด ์ฌ์ ์ ๊ฐ์ ธ์ผ ํ๋ค๊ณ ์๊ฐํ๋ค. ๊ทผ๋ฐ ์ด๊ฑด ORM์ ๊ด์ ์ด์ง ๊ฐ์ฒด์ ์ฐ๊ด๊ด๊ณ์์ ํ๋ฆฐ ๊ฒ์ด๋ค.
๋ชจ๋ ํ๋ก์ ํธ๋ ์์ ๋ฌผ์ DB์ ์ฐ๋์์ผ์ ํ๋ ์ด๋ฐ ๊ฐ์ฒด ๊ฐ์ ์ฐ๊ด ๊ด๊ณ๋ ๊ด์ฑ์ ์ผ๋ก ํ ์ด๋ธ์ ์ฐ๊ด๊ด๊ณ๋ก ์๊ฐํ๋ ๋ฒ๋ฆ์ด ์์๋ค.
์๋ฅผ ๋ค์ด ์๋ ์ฌ์ง์ฒ๋ผ ๋ฉค๋ฒ์ ํ์ด ์์ ๋ ๋, ํ ์์ ๋ฉค๋ฒ๊ฐ ์์ด์ผํ๋ค๊ณ ์๊ฐํ๋ค. ํ์ค ๊ฐ์ฒด์ ์ถ์ํ๋ก์ ๊ทธ๊ฒ ์์ฐ์ค๋ฝ๊ณ ํญ์ ๊ทธ๋์๋ค. ์๊ฐํ์ง๋ง, ๊ทธ๊ฑด ORM์ ๊ด์ ์ด์๋ค.
๊ทธ๋ฆฌ๊ณ JUNIT5๋ฅผ ์ฌ์ฉํ ํ ์คํธ ์ฝ๋๋ฅผ ์ด๋ฒ์ ์ ๊ทน ํ์ฉํ์ง ๋ชปํ ์ ์ด ์์ฌ์ ๋ค. ์ฐจํ 1๋ฌ ๋ค์ ๋ค์ ํ ์ด ํ๋ก์ ํธ 2 ์ด๋ ๊ทธ๋ ๊ผญ ํ ์คํธ ์ฝ๋๊น์ง ์๋ฒฝํ๊ฒ ์ํํด์ผ๊ฒ ๋ค.
์ข์๋ ์ ์ Git Hub Actions๋ฅผ ์ฌ์ฉํ์ฌ ์ค์ ํ์ ์ฒ๋ผ ํ์์ ๋ฆฌ๋ทฐ๋ฅผ ๋ฐ์ Approve๋ฅผ ๋ฐ์์ผ์ง๋ง Mergeํ ์ ์๋ ๊ฒ๊ณผ ๋ค์ํ ๋ฆฌ๋ทฐ ๋ฐ ํผ๋๋ฐฑ์ ๋๋ ์ ์๋ ์ ์ด ์ข์๋ค. ๋ํ ํจํค์ง ๋ฐ ํด๋์ค ์ค๊ณ ๋ถ๋ถ์์ ๋ง์ ์ ์ ๋ฐฐ์ ๊ณ , ์ญ์ ๊ณต๋ถ์ ๋์ด ์๋ค๋ ์๊ฐ๋ ๋ค์๋ค.
ํ ์คํธ ์ฝ๋ ๊ณต๋ถํ๋ฌ ๊ฐ์ผ๊ฒ ๋ค,,,,,
๋๊ธ