Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
File renamed without changes.
38 changes: 38 additions & 0 deletions docs/Step02.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
## ์ˆ˜๊ฐ• ์‹ ์ฒญ ๊ธฐ๋Šฅ ์š”๊ตฌ์‚ฌํ•ญ
- ๊ณผ์ •(Course)์€ ๊ธฐ์ˆ˜ ๋‹จ์œ„๋กœ ์šด์˜ํ•˜๋ฉฐ, ์—ฌ๋Ÿฌ ๊ฐœ์˜ ๊ฐ•์˜(Session)๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋‹ค.
- ๊ฐ•์˜๋Š” ์‹œ์ž‘์ผ๊ณผ ์ข…๋ฃŒ์ผ์„ ๊ฐ€์ง„๋‹ค.
- ๊ฐ•์˜๋Š” ๊ฐ•์˜ ์ปค๋ฒ„ ์ด๋ฏธ์ง€ ์ •๋ณด๋ฅผ ๊ฐ€์ง„๋‹ค.
- ์ด๋ฏธ์ง€ ํฌ๊ธฐ๋Š” 1MB ์ดํ•˜์—ฌ์•ผ ํ•œ๋‹ค.
- ์ด๋ฏธ์ง€ ํƒ€์ž…์€ gif, jpg(jpeg ํฌํ•จ),, png, svg๋งŒ ํ—ˆ์šฉํ•œ๋‹ค.
- ์ด๋ฏธ์ง€์˜ width๋Š” 300ํ”ฝ์…€, height๋Š” 200ํ”ฝ์…€ ์ด์ƒ์ด์–ด์•ผ ํ•˜๋ฉฐ, width์™€ height์˜ ๋น„์œจ์€ 3:2์—ฌ์•ผ ํ•œ๋‹ค.
- ๊ฐ•์˜๋Š” ๋ฌด๋ฃŒ ๊ฐ•์˜์™€ ์œ ๋ฃŒ ๊ฐ•์˜๋กœ ๋‚˜๋‰œ๋‹ค.
- ๋ฌด๋ฃŒ ๊ฐ•์˜๋Š” ์ตœ๋Œ€ ์ˆ˜๊ฐ• ์ธ์› ์ œํ•œ์ด ์—†๋‹ค.
- ์œ ๋ฃŒ ๊ฐ•์˜๋Š” ๊ฐ•์˜ ์ตœ๋Œ€ ์ˆ˜๊ฐ• ์ธ์›์„ ์ดˆ๊ณผํ•  ์ˆ˜ ์—†๋‹ค.
- ์œ ๋ฃŒ ๊ฐ•์˜๋Š” ์ˆ˜๊ฐ•์ƒ์ด ๊ฒฐ์ œํ•œ ๊ธˆ์•ก๊ณผ ์ˆ˜๊ฐ•๋ฃŒ๊ฐ€ ์ผ์น˜ํ•  ๋•Œ ์ˆ˜๊ฐ• ์‹ ์ฒญ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.
- ๊ฐ•์˜ ์ƒํƒœ๋Š” ์ค€๋น„์ค‘, ๋ชจ์ง‘์ค‘, ์ข…๋ฃŒ 3๊ฐ€์ง€ ์ƒํƒœ๋ฅผ ๊ฐ€์ง„๋‹ค.
- ๊ฐ•์˜ ์ˆ˜๊ฐ•์‹ ์ฒญ์€ ๊ฐ•์˜ ์ƒํƒœ๊ฐ€ ๋ชจ์ง‘์ค‘์ผ ๋•Œ๋งŒ ๊ฐ€๋Šฅํ•˜๋‹ค.
- ์œ ๋ฃŒ ๊ฐ•์˜์˜ ๊ฒฝ์šฐ ๊ฒฐ์ œ๋Š” ์ด๋ฏธ ์™„๋ฃŒํ•œ ๊ฒƒ์œผ๋กœ ๊ฐ€์ •ํ•˜๊ณ  ์ดํ›„ ๊ณผ์ •์„ ๊ตฌํ˜„ํ•œ๋‹ค.
- ๊ฒฐ์ œ๋ฅผ ์™„๋ฃŒํ•œ ๊ฒฐ์ œ ์ •๋ณด๋Š” payments ๋ชจ๋“ˆ์„ ํ†ตํ•ด ๊ด€๋ฆฌ๋˜๋ฉฐ, ๊ฒฐ์ œ ์ •๋ณด๋Š” Payment ๊ฐ์ฒด์— ๋‹ด๊ฒจ ๋ฐ˜ํ•œ๋œ๋‹ค.


## ํด๋ž˜์Šค
- `๊ณผ์ •(Course)` : 1
- ๊ธฐ์ˆ˜

- `๊ฐ•์˜(Session)` : N
- ๊ธˆ์•ก : ์œ ๋ฃŒ / ๋ฌด๋ฃŒ
- ์œ ๋ฃŒ ๊ฐ•์˜
- ๊ฐ•์˜ ์ตœ๋Œ€ `์ˆ˜๊ฐ• ์ธ์›` ์ œํ•œ
- `๊ฒฐ์žฌ ๊ธˆ์•ก` = ์ˆ˜๊ฐ•๋ฃŒ]
- ๋ฌด๋ฃŒ ๊ฐ•์˜
- ์ตœ๋Œ€ ์ˆ˜๊ฐ•์ธ์› ์ œํ•œ ์—†์Œ
- ์ƒํƒœ : ์ค€๋น„์ค‘, ๋ชจ์ง‘์ค‘, ์ข…๋ฃŒ
- ์‹œ์ž‘์ผ, ์ข…๋ฃŒ์ผ
- ๊ฐ•์˜ ์ปค๋ฒ„ ์ด๋ฏธ์ง€

- `๊ฐ•์˜ ์ปค๋ฒ„ ์ด๋ฏธ์ง€ (SessionCoverImage)`
- ํฌ๊ธฐ : 1MB
- ํƒ€์ž… : gif, jpg(jpeg), png, svg
- dimension
- width >= 300, height >= 200
- width : height = 3 : 2
36 changes: 36 additions & 0 deletions src/main/java/nextstep/courses/domain/BaseEntity.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package nextstep.courses.domain;

import java.time.LocalDateTime;

public abstract class BaseEntity {
private Long id;
private LocalDateTime createdAt;
private LocalDateTime updatedAt;

protected BaseEntity() {
this.createdAt = LocalDateTime.now();
}

protected BaseEntity(Long id) {
this.id = id;
this.createdAt = LocalDateTime.now();
}

protected BaseEntity(Long id, LocalDateTime createdAt, LocalDateTime updatedAt) {
this.id = id;
this.createdAt = createdAt;
this.updatedAt = updatedAt;
}

public Long getId() {
return id;
}

public LocalDateTime getCreatedAt() {
return createdAt;
}

public LocalDateTime getUpdatedAt() {
return updatedAt;
}
}
53 changes: 0 additions & 53 deletions src/main/java/nextstep/courses/domain/Course.java

This file was deleted.

61 changes: 61 additions & 0 deletions src/main/java/nextstep/courses/domain/course/Course.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package nextstep.courses.domain.course;

import java.time.LocalDateTime;
import java.util.Objects;
import nextstep.courses.domain.BaseEntity;

public class Course extends BaseEntity {
private String title;
private Long creatorId;

public Course() {
}

public Course(String title, Long creatorId) {
this(null, title, creatorId);
}

public Course(Long id, String title, Long creatorId) {
super(id);
this.title = title;
this.creatorId = creatorId;
}

public Course(Long id, String title, Long creatorId, LocalDateTime createdAt, LocalDateTime updatedAt) {
super(id, createdAt, updatedAt);
this.title = title;
this.creatorId = creatorId;
}

public String getTitle() {
return title;
}

public Long getCreatorId() {
return creatorId;
}

@Override
public String toString() {
return "Course{" +
"id=" + getId() +
", title='" + title + '\'' +
", creatorId=" + creatorId +
", createdAt=" + getCreatedAt() +
'}';
}

@Override
public boolean equals(Object o) {
if (o == null || getClass() != o.getClass()) {
return false;
}
Course course = (Course) o;
return Objects.equals(getId(), course.getId());
}

@Override
public int hashCode() {
return Objects.hashCode(getId());
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package nextstep.courses.domain;
package nextstep.courses.domain.course;

public interface CourseRepository {
int save(Course course);
Expand Down
17 changes: 17 additions & 0 deletions src/main/java/nextstep/courses/domain/image/SessionCoverImage.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package nextstep.courses.domain.image;

public class SessionCoverImage {
private final SessionImageDimension dimension;
private final SessionImageExtension extension;
private final SessionImageCapacity capacity;

public SessionCoverImage(int width, int height, String extension, long bytes) {
this(new SessionImageDimension(width, height), SessionImageExtension.from(extension), new SessionImageCapacity(bytes));
}

public SessionCoverImage(SessionImageDimension dimension, SessionImageExtension extension, SessionImageCapacity capacity) {
this.dimension = dimension;
this.extension = extension;
this.capacity = capacity;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package nextstep.courses.domain.image;

public class SessionImageCapacity {
private static final long MAX_CAPACITY_BYTES = 1024 * 1024; // 1MB
private final long bytes;

public SessionImageCapacity(long bytes) {
validate(bytes);
this.bytes = bytes;
}

public static SessionImageCapacity ofKB(long kb) {
return new SessionImageCapacity(kb * 1024);
}

public static SessionImageCapacity ofMB(long mb) {
return new SessionImageCapacity(mb * 1024 * 1024);
}

private void validate(long bytes) {
if (bytes <= 0) {
throw new IllegalArgumentException("์ด๋ฏธ์ง€ ํฌ๊ธฐ๋Š” 0๋ณด๋‹ค ์ปค์•ผ ํ•ฉ๋‹ˆ๋‹ค.");
}
if (bytes > MAX_CAPACITY_BYTES) {
throw new IllegalArgumentException("์ด๋ฏธ์ง€ ํฌ๊ธฐ๋Š” 1MB ์ดํ•˜์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.");
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package nextstep.courses.domain.image;

public class SessionImageDimension {
private static final int MIN_WIDTH = 300;
private static final int MIN_HEIGHT = 200;
private static final int RATIO_W = 3;
private static final int RATIO_H = 2;

private int width;
private int height;

public SessionImageDimension(int width, int height) {
validateMinLength(width, height);
validateRatio(width, height);
this.width = width;
this.height = height;
}
private void validateMinLength(int width, int height){
if(!(width >= MIN_WIDTH && height >= MIN_HEIGHT)) {
throw new IllegalArgumentException("์ด๋ฏธ์ง€๋Š” ๊ฐ€๋กœ 300์ด์ƒ, ์„ธ๋กœ 200 ์ด์ƒ์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.");
}
}

private void validateRatio(int width, int height){
int gcd = gcd(width, height);
int ratioW = width / gcd;
int ratioH = height / gcd;
if(!(ratioW == RATIO_W && ratioH == RATIO_H)){
throw new IllegalArgumentException("์ด๋ฏธ์ง€๋Š” ๊ฐ€๋กœ x ์„ธ๋กœ 3๋Œ€ 2์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.");
}
}

private int gcd(int a, int b) {
return b == 0 ? a : gcd(b, a % b);
}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package nextstep.courses.domain.image;

import java.util.ArrayList;
import java.util.List;

public enum SessionImageExtension {
GIF("gif"),
JPG("jpg", "jpeg"),
PNG("png"),
SVG("svg");

private List<String> names;

SessionImageExtension(String... names){
this.names = new ArrayList<>(List.of(names));
}

public static SessionImageExtension from(String extension) {
String lowerExt = extension.toLowerCase();
for (SessionImageExtension type : values()) {
if (type.names.contains(lowerExt)) {
return type;
}
}
throw new IllegalArgumentException("์ง€์›ํ•˜์ง€ ์•Š๋Š” ์ด๋ฏธ์ง€ ํ™•์žฅ์ž์ž…๋‹ˆ๋‹ค: " + extension);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package nextstep.courses.domain.registration;

import java.time.LocalDateTime;

public class Registration {
private final Long sessionId;
private final Long studentId;
private final LocalDateTime enrolledAt;

public Registration(Long sessionId, Long studentId) {
this(sessionId, studentId, LocalDateTime.now());
}

public Registration(Long sessionId, Long studentId, LocalDateTime enrolledAt) {
this.sessionId = sessionId;
this.studentId = studentId;
this.enrolledAt = enrolledAt;
}
public boolean contains(Long studentId) {
return this.studentId == studentId;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package nextstep.courses.domain.registration;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class Registrations {
private final List<Registration> registrations;

public Registrations() {
this(new ArrayList<>());
}

public Registrations(List<Registration> registrations) {
this.registrations = registrations;
}

public Registrations add(Registration registration) {
List<Registration> newList = new ArrayList<>(registrations);
newList.add(registration);
return new Registrations(newList);
}

public int count() {
return registrations.size();
}

public boolean contains(Long studentId) {
return registrations.stream()
.anyMatch(r -> r.contains(studentId));
}

}
Loading