FastCampus X Yanolja TechSchool

ํŒจ์ŠคํŠธ์บ ํผ์ŠคX์•ผ๋†€์ž: ๋ฐฑ์—”๋“œ ๊ฐœ๋ฐœ ๋ถ€ํŠธ ์บ ํ”„ - ๐ŸŽ Java ๊ธฐ๋ฐ˜ ํ† ์ด ํ”„๋กœ์ ํŠธ

ํ”„๋กœ๊ทธ๋ž˜๋จธ ์˜ค์›” 2023. 9. 13.

๐ŸŽ ํ† ์ด ํ”„๋กœ์ ํŠธ - 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

 

์—ฌํ–‰ ๊ธฐ๋ก ์‹คํ–‰ํ™”๋ฉด_2

 

์—ฌ์ • ๊ธฐ๋ก ์‹คํ–‰ํ™”๋ฉด

 

์—ฌํ–‰ ์กฐํšŒ ์‹คํ–‰ ํ™”๋ฉด

 

 

์—ฌ์ • ์กฐํšŒ ์‹คํ–‰ ํ™”๋ฉด

 

๋ฐ์ดํ„ฐ๋ฅผ ์ž…๋ ฅํ•œ ํ›„ ํŒŒ์ผ ์ €์žฅ ์ƒํƒœ ํ™”๋ฉด

 

 

๐Ÿค”ํŒ€ ํšŒ๊ณ 

ํ† ์ดํ”„๋กœ์ ํŠธ๊ฐ€ ๋๋‚˜๊ณ  ๊ทธ ์ฐจ์ฃผ ํ™”์š”์ผ์— ๋‹ค ๊ฐ™์ด ์คŒ์—์„œ ๋งŒ๋‚˜์„œ 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ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ๊ณผ ๋‹ค์–‘ํ•œ ๋ฆฌ๋ทฐ ๋ฐ ํ”ผ๋“œ๋ฐฑ์„ ๋‚˜๋ˆŒ ์ˆ˜ ์žˆ๋Š” ์ ์ด ์ข‹์•˜๋‹ค. ๋˜ํ•œ ํŒจํ‚ค์ง€ ๋ฐ ํด๋ž˜์Šค ์„ค๊ณ„ ๋ถ€๋ถ„์—์„œ ๋งŽ์€ ์ ์„ ๋ฐฐ์› ๊ณ , ์—ญ์‹œ ๊ณต๋ถ€์—” ๋์ด ์—†๋‹ค๋Š” ์ƒ๊ฐ๋„ ๋“ค์—ˆ๋‹ค.

ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ๊ณต๋ถ€ํ•˜๋Ÿฌ ๊ฐ€์•ผ๊ฒ ๋‹ค,,,,,

๋Œ“๊ธ€