Skip to content

Commit cb8f94f

Browse files
authored
Merge pull request #728 from heewonham/step2
2단계 - 수강신청(도메인 모델)
2 parents 74636dc + 03942b2 commit cb8f94f

File tree

18 files changed

+551
-3
lines changed

18 files changed

+551
-3
lines changed
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package nextstep.courses.domain;
2+
3+
public class Capacity {
4+
private final int value;
5+
6+
public Capacity(int value) {
7+
if (value <= 0) {
8+
throw new IllegalArgumentException("수강 정원은 0이거나 음수일 수 없습니다.");
9+
}
10+
this.value = value;
11+
}
12+
13+
public int getValue() {
14+
return value;
15+
}
16+
17+
public boolean isFull(int registeredCount) {
18+
return registeredCount >= value;
19+
}
20+
}

src/main/java/nextstep/courses/domain/Course.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package nextstep.courses.domain;
22

33
import java.time.LocalDateTime;
4+
import java.util.ArrayList;
45

56
public class Course {
67
private Long id;
@@ -12,6 +13,8 @@ public class Course {
1213
private LocalDateTime createdAt;
1314

1415
private LocalDateTime updatedAt;
16+
private int generation;
17+
private Sessions sessions;
1518

1619
public Course() {
1720
}
@@ -40,6 +43,20 @@ public LocalDateTime getCreatedAt() {
4043
return createdAt;
4144
}
4245

46+
public void addSession(Session session) {
47+
if (sessions == null) {
48+
sessions = new Sessions(new ArrayList<>());
49+
}
50+
sessions.add(session);
51+
}
52+
53+
public void removeSession(Session session) {
54+
if (sessions == null) {
55+
return;
56+
}
57+
sessions.remove(session);
58+
}
59+
4360
@Override
4461
public String toString() {
4562
return "Course{" +
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package nextstep.courses.domain;
2+
3+
import nextstep.payments.domain.Payment;
4+
5+
public class FreeSession extends Session {
6+
7+
public FreeSession(Long id, String name, Period period, Image coverImage, SessionStatus status) {
8+
super(id, name, period, coverImage, status);
9+
}
10+
11+
@Override
12+
protected void validateRegistration(Long studentId, Payment payment) {
13+
}
14+
15+
@Override
16+
public SessionType getType() {
17+
return SessionType.FREE;
18+
}
19+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package nextstep.courses.domain;
2+
3+
public class Image {
4+
private String fileName;
5+
private String contentType;
6+
private long sizeInBytes;
7+
private int width;
8+
private int height;
9+
private static final int IMAGE_SIZE_1MB = 1024 * 1024;
10+
private static final int WIDTH_LIMIT = 300;
11+
private static final int HEIGHT_LIMIT = 200;
12+
private static final double REQUIRED_ASPECT_RATIO = 1.5;
13+
private static final double ASPECT_RATIO_TOLERANCE = 0.01;
14+
15+
public Image(String fileName, String contentType, long sizeInBytes, int width, int height) {
16+
validate(contentType, sizeInBytes, width, height);
17+
this.fileName = fileName;
18+
this.contentType = contentType;
19+
this.sizeInBytes = sizeInBytes;
20+
this.width = width;
21+
this.height = height;
22+
}
23+
24+
private void validate(String contentType, long sizeInBytes, int width, int height) {
25+
if (sizeInBytes > IMAGE_SIZE_1MB) {
26+
throw new IllegalArgumentException("이미지 크기는 1MB 이하여야 합니다.");
27+
}
28+
29+
if (!contentType.matches("(gif|jpeg|jpg|png|svg)")) {
30+
throw new IllegalArgumentException("허용되지 않는 이미지 형식입니다.");
31+
}
32+
33+
if (width < WIDTH_LIMIT || height < HEIGHT_LIMIT) {
34+
throw new IllegalArgumentException("이미지 크기가 너무 작습니다.");
35+
}
36+
37+
double ratio = (double) width / height;
38+
if (Math.abs(ratio - REQUIRED_ASPECT_RATIO) > ASPECT_RATIO_TOLERANCE) {
39+
throw new IllegalArgumentException("이미지 비율은 3:2여야 합니다.");
40+
}
41+
}
42+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package nextstep.courses.domain;
2+
3+
import nextstep.payments.domain.Payment;
4+
5+
public class PaidSession extends Session {
6+
private Capacity maxCapacity;
7+
private TuitionFee tuitionFee;
8+
9+
public PaidSession(Long id, String name, Period period, Image coverImage,
10+
SessionStatus status, int maxCapacity, int tuitionFee) {
11+
super(id, name, period, coverImage, status);
12+
this.maxCapacity = new Capacity(maxCapacity);
13+
this.tuitionFee = new TuitionFee(tuitionFee);
14+
}
15+
16+
@Override
17+
protected void validateRegistration(Long studentId, Payment payment) {
18+
if (registeredStudents.size() >= maxCapacity.getValue()) {
19+
throw new IllegalStateException("수강 인원을 초과하였습니다.");
20+
}
21+
if (payment == null) {
22+
throw new IllegalArgumentException("결제 정보가 없습니다.");
23+
}
24+
if (!this.id.equals(payment.getSessionId())) {
25+
throw new IllegalArgumentException("결제한 강의와 일치하지 않습니다.");
26+
}
27+
if (!studentId.equals(payment.getNsUserId())) {
28+
throw new IllegalArgumentException("결제한 사용자와 일치하지 않습니다.");
29+
}
30+
if (this.tuitionFee.getAmount() != payment.getAmount()) {
31+
throw new IllegalArgumentException("결제 금액과 일치하지 않습니다.");
32+
}
33+
}
34+
35+
@Override
36+
public SessionType getType() {
37+
return SessionType.PAID;
38+
}
39+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package nextstep.courses.domain;
2+
3+
import java.time.LocalDate;
4+
5+
public class Period {
6+
private final LocalDate startDate;
7+
private final LocalDate endDate;
8+
9+
public Period(LocalDate startDate, LocalDate endDate) {
10+
if (endDate.isBefore(startDate) || endDate.isEqual(startDate)) {
11+
throw new IllegalArgumentException("종료일은 시작일보다 이후여야 합니다.");
12+
}
13+
this.startDate = startDate;
14+
this.endDate = endDate;
15+
}
16+
17+
public LocalDate getStartDate() {
18+
return startDate;
19+
}
20+
21+
public LocalDate getEndDate() {
22+
return endDate;
23+
}
24+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package nextstep.courses.domain;
2+
3+
import nextstep.payments.domain.Payment;
4+
5+
import java.util.HashSet;
6+
import java.util.Set;
7+
public abstract class Session {
8+
protected Long id;
9+
protected String name;
10+
protected Period period;
11+
protected Image coverImage;
12+
protected SessionStatus status;
13+
protected Set<Long> registeredStudents = new HashSet<>();
14+
15+
public Session(Long id, String name, Period period, Image coverImage, SessionStatus status) {
16+
this.id = id;
17+
this.name = name;
18+
this.period = period;
19+
this.coverImage = coverImage;
20+
this.status = status;
21+
}
22+
23+
public void register(Long studentId, Payment payment) {
24+
if (status != SessionStatus.RECRUITING) {
25+
throw new IllegalStateException("수강 신청은 모집중일 때만 가능합니다.");
26+
}
27+
28+
validateRegistration(studentId, payment);
29+
registeredStudents.add(studentId);
30+
}
31+
32+
public boolean isRegistered(Long studentId) {
33+
return registeredStudents.contains(studentId);
34+
}
35+
36+
protected abstract void validateRegistration(Long studentId, Payment payment);
37+
38+
public abstract SessionType getType();
39+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package nextstep.courses.domain;
2+
3+
public enum SessionStatus {
4+
PREPARING,
5+
RECRUITING,
6+
CLOSED,
7+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package nextstep.courses.domain;
2+
3+
public enum SessionType {
4+
FREE,
5+
PAID,
6+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package nextstep.courses.domain;
2+
3+
import java.util.List;
4+
5+
public class Sessions {
6+
private final List<Session> sessions;
7+
8+
public Sessions(List<Session> sessions) {
9+
this.sessions = sessions;
10+
}
11+
12+
public void add(Session session) {
13+
sessions.add(session);
14+
}
15+
16+
public void remove(Session session) {
17+
sessions.remove(session);
18+
}
19+
}

0 commit comments

Comments
 (0)