Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Step3 #384

Open
wants to merge 10 commits into
base: henry174
Choose a base branch
from
4 changes: 4 additions & 0 deletions src/main/java/nextstep/courses/domain/Course.java
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,8 @@ public String toString() {
", updatedAt=" + updatedAt +
'}';
}

public Long getId() {
return this.id;
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package nextstep.courses.domain;

public interface CourseRepository {
int save(Course course);
long save(Course course);

Course findById(Long id);
}
11 changes: 10 additions & 1 deletion src/main/java/nextstep/courses/domain/RegisteredUsers.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Stream;

/**
* 수강신청한 사용자들 목록
Expand All @@ -24,4 +25,12 @@ public void add(NsUser user) {
public int theNumberOfUsers() {
return this.users.size();
}
}

public Stream<NsUser> stream() {
return this.users.stream();
}

public List<NsUser> toList() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DB에 매핑을 하다보면 Session과 NsUser가 m:n 관계를 가지게 된다.
즉 sessionId와 nsUserId를 가지는 매핑 테이블이 필요하고, 이 매핑 정보를 담고 있는 Student와 객체로 바뀌지 않을까?

return List.copyOf(this.users);
}
}
76 changes: 53 additions & 23 deletions src/main/java/nextstep/courses/domain/Session.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package nextstep.courses.domain;

import nextstep.courses.type.InfinitablePositiveInteger;
import nextstep.courses.type.MaxRegister;
import nextstep.courses.type.SessionDuration;
import nextstep.courses.type.SessionState;
import nextstep.payments.domain.Payment;
Expand All @@ -24,48 +24,49 @@ public class Session {
private SessionImage coverImage;
private SessionDuration duration;

private InfinitablePositiveInteger maxUserCount;
private MaxRegister maxUserCount;
private int fee;


private Session() {

}

public static Session createFreeSession(Long id, Course course, SessionImage coverImage, SessionDuration duration) {
public static Session create(Long id, Course course, SessionState state, RegisteredUsers registeredUsers, SessionImage coverImage, SessionDuration duration, MaxRegister maxUserCount, int fee) {
Session session = new Session();

session.id = id;
session.course = course;
session.state = READY;
session.registeredUsers = new RegisteredUsers();
session.state = state;
session.registeredUsers = registeredUsers;
session.coverImage = coverImage;
session.duration = duration;
session.maxUserCount = InfinitablePositiveInteger.infinite();
session.fee = 0;
session.maxUserCount = maxUserCount;
session.fee = fee;

validateSession(session);
return session;
}

public static Session createPaidSession(Long id, Course course, SessionImage coverImage, SessionDuration duration, InfinitablePositiveInteger maxUserCount, int fee) {
Session session = new Session();

session.id = id;
session.course = course;
session.state = READY;
session.registeredUsers = new RegisteredUsers();
session.coverImage = coverImage;
session.duration = duration;
session.maxUserCount = maxUserCount;
session.fee = fee;
public static Session createFreeSession(Long id, Course course, SessionImage coverImage, SessionDuration duration) {
return Session.create(id, course, READY, new RegisteredUsers(), coverImage, duration, MaxRegister.infinite(), 0);
}

validateSession(session);
return session;
public static Session createPaidSession(Long id, Course course, SessionImage coverImage, SessionDuration duration, MaxRegister maxUserCount, int fee) {
return Session.create(id, course, READY, new RegisteredUsers(), coverImage, duration, maxUserCount, fee);
}

private static void validateSession(Session session) {
validateFee(session.fee);
validateMaxUserCount(session.maxUserCount, session.fee);
}

private static void validateMaxUserCount(MaxRegister maxUserCount, int fee) {
if (fee == 0 && maxUserCount.isFinite()) {
throw new IllegalArgumentException("무료 강의는 수강 제한 인원을 둘 수 없습니다.");
}
}

private static void validateFee(int fee) {
if (fee < 0) {
throw new IllegalArgumentException("강의료가 음수일 수 없습니다.");
Expand All @@ -88,15 +89,15 @@ public void registerUser(NsUser user) {
}

public void registerUser(NsUser user, Payment payment) {
if (payment.isSameUser(user) == false) {
if (!payment.isSameUser(user)) {
throw new IllegalArgumentException("지불 정보와 등록하는 유저가 일치하지 않습니다.");
}

if (payment.isSameAmountWith(this.fee) == false) {
if (!payment.isSameAmountWith(this.fee)) {
throw new IllegalArgumentException("수강료와 지불 금액이 동일하지 않습니다.");
}

if (this.maxUserCount.isLargerThan(this.registeredUsers.theNumberOfUsers()) == false) {
if (!this.maxUserCount.isLargerThan(this.registeredUsers.theNumberOfUsers())) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Enrollment와 같은 객체를 추가해 maxUserCount와 수강생 목록을 가지고 수강 신청 가능 여부를 Enrollment가 담당하도록 구현하는 것은 어떨까?

throw new IllegalStateException("이 강의의 최대 등록 가능 인원에 도달했습니다. 더 이상 사용자를 추가할 수 없습니다.");
}

Expand All @@ -116,6 +117,31 @@ public Long getId() {
return this.id;
}


public Course getCourse() {
return course;
}

public SessionState getState() {
return state;
}

public SessionImage getCoverImage() {
return coverImage;
}

public SessionDuration getDuration() {
return duration;
}

public MaxRegister getMaxUserCount() {
return maxUserCount;
}

public int getFee() {
return fee;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
Expand All @@ -141,4 +167,8 @@ public String toString() {
", fee=" + fee +
'}';
}

public RegisteredUsers getRegisteredUsers() {
return this.registeredUsers;
}
}
41 changes: 34 additions & 7 deletions src/main/java/nextstep/courses/domain/SessionImage.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@
import nextstep.courses.type.*;

public class SessionImage {
private static final Capacity MAX_CAPACITY = new Capacity(1024, CapacityUnit.KB);
private static final Rectangle MIN_SIZE = new Rectangle(300, 200, LengthUnit.PIXEL);
private static final Capacity MAX_CAPACITY = new Capacity(1024);
private static final Rectangle MIN_SIZE = new Rectangle(300, 200);
private static final int WIDTH_RATIO = 3;
private static final int HEIGHT_RATIO = 2;

private String filePath;

/**
* 이미지 용량
*/
Expand All @@ -18,22 +20,32 @@ public class SessionImage {
*/
private Rectangle size;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍



private ImageExtension type;

public SessionImage(Capacity capacity, Rectangle size, ImageExtension type) {
public SessionImage(String filePath, Capacity capacity, Rectangle size, ImageExtension type) {
validateCapacity(capacity);
validateSize(size);

this.filePath = filePath;
this.capacity = capacity;
this.size = size;
this.type = type;
}

public SessionImage(String filePath, int capacity, int width, int height, ImageExtension type) {
this(
filePath,
new Capacity(capacity),
new Rectangle(width, height),
type
);
}

public SessionImage(int capacity, int width, int height, ImageExtension type) {
this(
new Capacity(capacity, CapacityUnit.KB),
new Rectangle(width, height, LengthUnit.PIXEL),
"",
new Capacity(capacity),
new Rectangle(width, height),
type
);
}
Expand All @@ -47,4 +59,19 @@ private static void validateSize(Rectangle size) {
size.throwIfRatioIsNotTheSameWith(WIDTH_RATIO, HEIGHT_RATIO);
}

}
public String getFilePath() {
return filePath;
}

public Capacity getCapacity() {
return capacity;
}

public Rectangle getSize() {
return size;
}

public ImageExtension getType() {
return type;
}
}
7 changes: 7 additions & 0 deletions src/main/java/nextstep/courses/domain/SessionRepository.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package nextstep.courses.domain;

public interface SessionRepository {
long save(Session session);

Session findById(Long id);
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,16 @@

import nextstep.courses.domain.Course;
import nextstep.courses.domain.CourseRepository;
import nextstep.courses.infrastructure.exception.DbInsertFailException;
import nextstep.qna.CannotDeleteException;
import org.springframework.jdbc.core.JdbcOperations;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;
import org.springframework.stereotype.Repository;

import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.time.LocalDateTime;

Expand All @@ -18,9 +24,22 @@ public JdbcCourseRepository(JdbcOperations jdbcTemplate) {
}

@Override
public int save(Course course) {
public long save(Course course) {
String sql = "insert into course (title, creator_id, created_at) values(?, ?, ?)";
return jdbcTemplate.update(sql, course.getTitle(), course.getCreatorId(), course.getCreatedAt());
KeyHolder keyHolder = new GeneratedKeyHolder();

jdbcTemplate.update(connection -> {
PreparedStatement ps = connection.prepareStatement(sql, new String[]{"id"});
ps.setString(1, course.getTitle());
ps.setLong(2, course.getCreatorId());
ps.setTimestamp(3, Timestamp.valueOf(course.getCreatedAt()));
return ps;
}, keyHolder);

if (keyHolder.getKey() == null) {
throw new DbInsertFailException("Course");
}
return keyHolder.getKey().longValue();
}

@Override
Expand Down
Loading