Skip to content

Commit ccd918f

Browse files
authored
๐Ÿš€ 2๋‹จ๊ณ„ - ์ˆ˜๊ฐ•์‹ ์ฒญ(๋„๋ฉ”์ธ ๋ชจ๋ธ) (#796)
* ๐Ÿš€ 2๋‹จ๊ณ„ - ์ˆ˜๊ฐ•์‹ ์ฒญ(๋„๋ฉ”์ธ ๋ชจ๋ธ) : TDD 1์ฐจ ๊ตฌํ˜„ * ๐Ÿš€ 2๋‹จ๊ณ„ - ์ˆ˜๊ฐ•์‹ ์ฒญ(๋„๋ฉ”์ธ ๋ชจ๋ธ) : id, enroll ๋ถ„๋ฆฌ * ํŒจํ‚ค์ง€ ๋ถ„๋ฆฌ, SessionType ๋ถ„๋ฆฌ * ๋ฉ”์„œ๋“œ๋ช… ๋ณ€๊ฒฝ ๋ฐ Registration ์ถ”๊ฐ€ * Enrollment ๋ถ„๋ฆฌ, ๊ฐ€๋ณ€ ๊ฐ์ฒดํ™” * payAmount long ํƒ€์ž…์œผ๋กœ ๋ณ€๊ฒฝ
1 parent 9284c57 commit ccd918f

34 files changed

+955
-58
lines changed
File renamed without changes.

โ€Ždocs/Step02.mdโ€Ž

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
## ์ˆ˜๊ฐ• ์‹ ์ฒญ ๊ธฐ๋Šฅ ์š”๊ตฌ์‚ฌํ•ญ
2+
- ๊ณผ์ •(Course)์€ ๊ธฐ์ˆ˜ ๋‹จ์œ„๋กœ ์šด์˜ํ•˜๋ฉฐ, ์—ฌ๋Ÿฌ ๊ฐœ์˜ ๊ฐ•์˜(Session)๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋‹ค.
3+
- ๊ฐ•์˜๋Š” ์‹œ์ž‘์ผ๊ณผ ์ข…๋ฃŒ์ผ์„ ๊ฐ€์ง„๋‹ค.
4+
- ๊ฐ•์˜๋Š” ๊ฐ•์˜ ์ปค๋ฒ„ ์ด๋ฏธ์ง€ ์ •๋ณด๋ฅผ ๊ฐ€์ง„๋‹ค.
5+
- ์ด๋ฏธ์ง€ ํฌ๊ธฐ๋Š” 1MB ์ดํ•˜์—ฌ์•ผ ํ•œ๋‹ค.
6+
- ์ด๋ฏธ์ง€ ํƒ€์ž…์€ gif, jpg(jpeg ํฌํ•จ),, png, svg๋งŒ ํ—ˆ์šฉํ•œ๋‹ค.
7+
- ์ด๋ฏธ์ง€์˜ width๋Š” 300ํ”ฝ์…€, height๋Š” 200ํ”ฝ์…€ ์ด์ƒ์ด์–ด์•ผ ํ•˜๋ฉฐ, width์™€ height์˜ ๋น„์œจ์€ 3:2์—ฌ์•ผ ํ•œ๋‹ค.
8+
- ๊ฐ•์˜๋Š” ๋ฌด๋ฃŒ ๊ฐ•์˜์™€ ์œ ๋ฃŒ ๊ฐ•์˜๋กœ ๋‚˜๋‰œ๋‹ค.
9+
- ๋ฌด๋ฃŒ ๊ฐ•์˜๋Š” ์ตœ๋Œ€ ์ˆ˜๊ฐ• ์ธ์› ์ œํ•œ์ด ์—†๋‹ค.
10+
- ์œ ๋ฃŒ ๊ฐ•์˜๋Š” ๊ฐ•์˜ ์ตœ๋Œ€ ์ˆ˜๊ฐ• ์ธ์›์„ ์ดˆ๊ณผํ•  ์ˆ˜ ์—†๋‹ค.
11+
- ์œ ๋ฃŒ ๊ฐ•์˜๋Š” ์ˆ˜๊ฐ•์ƒ์ด ๊ฒฐ์ œํ•œ ๊ธˆ์•ก๊ณผ ์ˆ˜๊ฐ•๋ฃŒ๊ฐ€ ์ผ์น˜ํ•  ๋•Œ ์ˆ˜๊ฐ• ์‹ ์ฒญ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.
12+
- ๊ฐ•์˜ ์ƒํƒœ๋Š” ์ค€๋น„์ค‘, ๋ชจ์ง‘์ค‘, ์ข…๋ฃŒ 3๊ฐ€์ง€ ์ƒํƒœ๋ฅผ ๊ฐ€์ง„๋‹ค.
13+
- ๊ฐ•์˜ ์ˆ˜๊ฐ•์‹ ์ฒญ์€ ๊ฐ•์˜ ์ƒํƒœ๊ฐ€ ๋ชจ์ง‘์ค‘์ผ ๋•Œ๋งŒ ๊ฐ€๋Šฅํ•˜๋‹ค.
14+
- ์œ ๋ฃŒ ๊ฐ•์˜์˜ ๊ฒฝ์šฐ ๊ฒฐ์ œ๋Š” ์ด๋ฏธ ์™„๋ฃŒํ•œ ๊ฒƒ์œผ๋กœ ๊ฐ€์ •ํ•˜๊ณ  ์ดํ›„ ๊ณผ์ •์„ ๊ตฌํ˜„ํ•œ๋‹ค.
15+
- ๊ฒฐ์ œ๋ฅผ ์™„๋ฃŒํ•œ ๊ฒฐ์ œ ์ •๋ณด๋Š” payments ๋ชจ๋“ˆ์„ ํ†ตํ•ด ๊ด€๋ฆฌ๋˜๋ฉฐ, ๊ฒฐ์ œ ์ •๋ณด๋Š” Payment ๊ฐ์ฒด์— ๋‹ด๊ฒจ ๋ฐ˜ํ•œ๋œ๋‹ค.
16+
17+
18+
## ํด๋ž˜์Šค
19+
- `๊ณผ์ •(Course)` : 1
20+
- ๊ธฐ์ˆ˜
21+
22+
- `๊ฐ•์˜(Session)` : N
23+
- ๊ธˆ์•ก : ์œ ๋ฃŒ / ๋ฌด๋ฃŒ
24+
- ์œ ๋ฃŒ ๊ฐ•์˜
25+
- ๊ฐ•์˜ ์ตœ๋Œ€ `์ˆ˜๊ฐ• ์ธ์›` ์ œํ•œ
26+
- `๊ฒฐ์žฌ ๊ธˆ์•ก` = ์ˆ˜๊ฐ•๋ฃŒ]
27+
- ๋ฌด๋ฃŒ ๊ฐ•์˜
28+
- ์ตœ๋Œ€ ์ˆ˜๊ฐ•์ธ์› ์ œํ•œ ์—†์Œ
29+
- ์ƒํƒœ : ์ค€๋น„์ค‘, ๋ชจ์ง‘์ค‘, ์ข…๋ฃŒ
30+
- ์‹œ์ž‘์ผ, ์ข…๋ฃŒ์ผ
31+
- ๊ฐ•์˜ ์ปค๋ฒ„ ์ด๋ฏธ์ง€
32+
33+
- `๊ฐ•์˜ ์ปค๋ฒ„ ์ด๋ฏธ์ง€ (SessionCoverImage)`
34+
- ํฌ๊ธฐ : 1MB
35+
- ํƒ€์ž… : gif, jpg(jpeg), png, svg
36+
- dimension
37+
- width >= 300, height >= 200
38+
- width : height = 3 : 2
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package nextstep.courses.domain;
2+
3+
import java.time.LocalDateTime;
4+
5+
public abstract class BaseEntity {
6+
private Long id;
7+
private LocalDateTime createdAt;
8+
private LocalDateTime updatedAt;
9+
10+
protected BaseEntity() {
11+
this.createdAt = LocalDateTime.now();
12+
}
13+
14+
protected BaseEntity(Long id) {
15+
this.id = id;
16+
this.createdAt = LocalDateTime.now();
17+
}
18+
19+
protected BaseEntity(Long id, LocalDateTime createdAt, LocalDateTime updatedAt) {
20+
this.id = id;
21+
this.createdAt = createdAt;
22+
this.updatedAt = updatedAt;
23+
}
24+
25+
public Long getId() {
26+
return id;
27+
}
28+
29+
public LocalDateTime getCreatedAt() {
30+
return createdAt;
31+
}
32+
33+
public LocalDateTime getUpdatedAt() {
34+
return updatedAt;
35+
}
36+
}

โ€Žsrc/main/java/nextstep/courses/domain/Course.javaโ€Ž

Lines changed: 0 additions & 53 deletions
This file was deleted.
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
package nextstep.courses.domain.course;
2+
3+
import java.time.LocalDateTime;
4+
import java.util.Objects;
5+
import nextstep.courses.domain.BaseEntity;
6+
7+
public class Course extends BaseEntity {
8+
private String title;
9+
private Long creatorId;
10+
11+
public Course() {
12+
}
13+
14+
public Course(String title, Long creatorId) {
15+
this(null, title, creatorId);
16+
}
17+
18+
public Course(Long id, String title, Long creatorId) {
19+
super(id);
20+
this.title = title;
21+
this.creatorId = creatorId;
22+
}
23+
24+
public Course(Long id, String title, Long creatorId, LocalDateTime createdAt, LocalDateTime updatedAt) {
25+
super(id, createdAt, updatedAt);
26+
this.title = title;
27+
this.creatorId = creatorId;
28+
}
29+
30+
public String getTitle() {
31+
return title;
32+
}
33+
34+
public Long getCreatorId() {
35+
return creatorId;
36+
}
37+
38+
@Override
39+
public String toString() {
40+
return "Course{" +
41+
"id=" + getId() +
42+
", title='" + title + '\'' +
43+
", creatorId=" + creatorId +
44+
", createdAt=" + getCreatedAt() +
45+
'}';
46+
}
47+
48+
@Override
49+
public boolean equals(Object o) {
50+
if (o == null || getClass() != o.getClass()) {
51+
return false;
52+
}
53+
Course course = (Course) o;
54+
return Objects.equals(getId(), course.getId());
55+
}
56+
57+
@Override
58+
public int hashCode() {
59+
return Objects.hashCode(getId());
60+
}
61+
}

src/main/java/nextstep/courses/domain/CourseRepository.java renamed to src/main/java/nextstep/courses/domain/course/CourseRepository.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package nextstep.courses.domain;
1+
package nextstep.courses.domain.course;
22

33
public interface CourseRepository {
44
int save(Course course);
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package nextstep.courses.domain.image;
2+
3+
public class SessionCoverImage {
4+
private final SessionImageDimension dimension;
5+
private final SessionImageExtension extension;
6+
private final SessionImageCapacity capacity;
7+
8+
public SessionCoverImage(int width, int height, String extension, long bytes) {
9+
this(new SessionImageDimension(width, height), SessionImageExtension.from(extension), new SessionImageCapacity(bytes));
10+
}
11+
12+
public SessionCoverImage(SessionImageDimension dimension, SessionImageExtension extension, SessionImageCapacity capacity) {
13+
this.dimension = dimension;
14+
this.extension = extension;
15+
this.capacity = capacity;
16+
}
17+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package nextstep.courses.domain.image;
2+
3+
public class SessionImageCapacity {
4+
private static final long MAX_CAPACITY_BYTES = 1024 * 1024; // 1MB
5+
private final long bytes;
6+
7+
public SessionImageCapacity(long bytes) {
8+
validate(bytes);
9+
this.bytes = bytes;
10+
}
11+
12+
public static SessionImageCapacity ofKB(long kb) {
13+
return new SessionImageCapacity(kb * 1024);
14+
}
15+
16+
public static SessionImageCapacity ofMB(long mb) {
17+
return new SessionImageCapacity(mb * 1024 * 1024);
18+
}
19+
20+
private void validate(long bytes) {
21+
if (bytes <= 0) {
22+
throw new IllegalArgumentException("์ด๋ฏธ์ง€ ํฌ๊ธฐ๋Š” 0๋ณด๋‹ค ์ปค์•ผ ํ•ฉ๋‹ˆ๋‹ค.");
23+
}
24+
if (bytes > MAX_CAPACITY_BYTES) {
25+
throw new IllegalArgumentException("์ด๋ฏธ์ง€ ํฌ๊ธฐ๋Š” 1MB ์ดํ•˜์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.");
26+
}
27+
}
28+
29+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package nextstep.courses.domain.image;
2+
3+
public class SessionImageDimension {
4+
private static final int MIN_WIDTH = 300;
5+
private static final int MIN_HEIGHT = 200;
6+
private static final int RATIO_W = 3;
7+
private static final int RATIO_H = 2;
8+
9+
private int width;
10+
private int height;
11+
12+
public SessionImageDimension(int width, int height) {
13+
validateMinLength(width, height);
14+
validateRatio(width, height);
15+
this.width = width;
16+
this.height = height;
17+
}
18+
private void validateMinLength(int width, int height){
19+
if(!(width >= MIN_WIDTH && height >= MIN_HEIGHT)) {
20+
throw new IllegalArgumentException("์ด๋ฏธ์ง€๋Š” ๊ฐ€๋กœ 300์ด์ƒ, ์„ธ๋กœ 200 ์ด์ƒ์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.");
21+
}
22+
}
23+
24+
private void validateRatio(int width, int height){
25+
int gcd = gcd(width, height);
26+
int ratioW = width / gcd;
27+
int ratioH = height / gcd;
28+
if(!(ratioW == RATIO_W && ratioH == RATIO_H)){
29+
throw new IllegalArgumentException("์ด๋ฏธ์ง€๋Š” ๊ฐ€๋กœ x ์„ธ๋กœ 3๋Œ€ 2์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.");
30+
}
31+
}
32+
33+
private int gcd(int a, int b) {
34+
return b == 0 ? a : gcd(b, a % b);
35+
}
36+
37+
38+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package nextstep.courses.domain.image;
2+
3+
import java.util.ArrayList;
4+
import java.util.List;
5+
6+
public enum SessionImageExtension {
7+
GIF("gif"),
8+
JPG("jpg", "jpeg"),
9+
PNG("png"),
10+
SVG("svg");
11+
12+
private List<String> names;
13+
14+
SessionImageExtension(String... names){
15+
this.names = new ArrayList<>(List.of(names));
16+
}
17+
18+
public static SessionImageExtension from(String extension) {
19+
String lowerExt = extension.toLowerCase();
20+
for (SessionImageExtension type : values()) {
21+
if (type.names.contains(lowerExt)) {
22+
return type;
23+
}
24+
}
25+
throw new IllegalArgumentException("์ง€์›ํ•˜์ง€ ์•Š๋Š” ์ด๋ฏธ์ง€ ํ™•์žฅ์ž์ž…๋‹ˆ๋‹ค: " + extension);
26+
}
27+
}

0 commit comments

Comments
ย (0)