본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성하였습니다.
공부 시작 시각 인증
도메인과 클린 아키텍쳐
소프트웨어 아키텍트
- 소프트웨어가 언제, 어떻게 구성돼야 할 지를 결정하는 사람, 비즈니스 목표에 부합되도록 만드는 사람
클린 아키텍쳐
- 소프트웨어 시스템의 구조를 설계할 때, 지켜야 할 원칙과 방법
- 선택지를 넓힘으로써 유연하게 대응하게 되면서 비용이 줄어 든다.
- 컴포넌트 - 시스템의 구성 요소로, 배포할 수 있는 가장 작은 단위(예: JAVA - .jar)
- 저수준 컴포넌트: 비즈니스 로직보다는 유저와 외부에 가까움.
- 고수준 컴포넌트: 비즈니스 로직에 포함됨.
- 고수준 컴포넌트는 저수준 컴포넌트에 의존해서는 안 됨! 왜냐하면, 저수준 컴포넌트는 수시로 변경되기 때문이다.
수강 인증 사진
Course.java
package org.fastcampus.student_management.domain;
import org.fastcampus.student_management.application.course.dto.*;
public class Course {
private final Student student;
private final String courseName;
private CourseFee fee;
private final DayOfWeek dayOfWeek;
private final Long courseTime;
public Course(Student student, CourseInfoDto courseInfo) {
if (student == null) {
throw new IllegalArgumentException("학생은 필수 입력값입니다.");
}
this.student = student;
this.courseName = courseInfo.getCourseName();
this.fee = new CourseFee(courseInfo.getFee());
this.dayOfWeek = courseInfo.getDayOfWeek();
this.courseTime = courseInfo.getCourseTime();
}
public void changeFee(int fee) {
this.fee.changeFee(fee);
}
public String getCourseName() {
return courseName;
}
public boolean isSameDay(DayOfWeek dayOfWeek) {
return this.dayOfWeek.equals(dayOfWeek);
}
public boolean isActivateUser() {
return student.isActivate();
}
public String getStudentName() {
return student.getName();
}
public int getFee() {
return this.fee.getFee();
}
public DayOfWeek getDayOfWeek() {
return dayOfWeek;
}
public Long getCourseTime() {
return courseTime;
}
}
CourseCommandRepositoryImpl.java
package org.fastcampus.student_management.repo;
import java.util.HashMap;
import java.util.Map;
import org.fastcampus.student_management.application.course.Interface.*;
import org.fastcampus.student_management.domain.Course;
public class CourseCommandRepositoryImpl implements CourseCommandRepository {
private final Map<String, Course> courseMap = new HashMap<>();
public void save(Course course) {
courseMap.put(course.getCourseName(), course);
}
}
CourseCommandRepository.java
package org.fastcampus.student_management.application.course.Interface;
import org.fastcampus.student_management.domain.Course;
public interface CourseCommandRepository {
void save(Course course);
}
※ 기존 CourseRepository.java 파일은 삭제됨!
CourseJdbcRepository.java
package org.fastcampus.student_management.repo;
import java.util.List;
import org.fastcampus.student_management.application.course.Interface.*;
import org.fastcampus.student_management.domain.Course;
import org.fastcampus.student_management.domain.DayOfWeek;
public class CourseJdbcRepository implements CourseQueryRepository {
@Override
public List<Course> getCourseDayOfWeek(DayOfWeek dayOfWeek) {
return List.of();
}
@Override
public List<Course> getCourseListByStudent(String studentName) {
return List.of();
}
}
CourseQueryRepository.java
package org.fastcampus.student_management.application.course.Interface;
import java.util.List;
import org.fastcampus.student_management.domain.Course;
import org.fastcampus.student_management.domain.DayOfWeek;
public interface CourseQueryRepository {
List<Course> getCourseDayOfWeek(DayOfWeek dayOfWeek);
List<Course> getCourseListByStudent(String studentName);
}
StudentRepository.java
package org.fastcampus.student_management.repo;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import org.fastcampus.student_management.domain.Student;
public class StudentRepository {
private final Map<String, Student> studentMap = new HashMap<>();
public void save(Student student) {
studentMap.put(student.getName(), student);
}
public Optional<Student> findByName(String name) {
return Optional.ofNullable(studentMap.get(name));
}
public Student getStudent(String name) {
return findByName(name).orElseThrow(IllegalAccessError::new);
}
}
CourseService.java
package org.fastcampus.student_management.application.course;
import java.util.List;
import org.fastcampus.student_management.application.course.Interface.*;
import org.fastcampus.student_management.application.course.dto.*;
import org.fastcampus.student_management.domain.Course;
import org.fastcampus.student_management.domain.CourseList;
import org.fastcampus.student_management.domain.DayOfWeek;
import org.fastcampus.student_management.domain.Student;
import org.fastcampus.student_management.repo.StudentRepository;
public class CourseService {
private final CourseCommandRepository courseCommandRepository;
private final CourseQueryRepository courseQueryRepository;
private final StudentRepository studentRepository;
public CourseService(CourseCommandRepository courseCommandRepository, CourseQueryRepository courseQueryRepository, StudentRepository studentRepository) {
this.courseCommandRepository = courseCommandRepository;
this.courseQueryRepository = courseQueryRepository;
this.studentRepository = studentRepository;
}
public void registerCourse(CourseInfoDto courseInfoDto) {
Student student = studentRepository.getStudent(courseInfoDto.getStudentName());
Course course = new Course(student, courseInfoDto);
courseCommandRepository.save(course);
}
public List<CourseInfoDto> getCourseDayOfWeek(DayOfWeek dayOfWeek) {
// TODO: 과제 구현 부분
List<Course> courses = courseQueryRepository.getCourseDayOfWeek(dayOfWeek);
return courses.stream().map(CourseInfoDto::new).toList();
}
public void changeFee(String studentName, int fee) {
// TODO: 과제 구현 부분
List<Course> courses = courseQueryRepository.getCourseListByStudent(studentName);
CourseList courseList = new CourseList(courses);
courseList.changeAllCoursesFee(fee);
}
}
Main.java
package org.fastcampus.student_management;
import org.fastcampus.student_management.application.course.CourseService;
import org.fastcampus.student_management.application.student.StudentService;
import org.fastcampus.student_management.repo.CourseCommandRepositoryImpl;
import org.fastcampus.student_management.repo.CourseJdbcRepository;
import org.fastcampus.student_management.repo.StudentRepository;
import org.fastcampus.student_management.ui.course.CourseController;
import org.fastcampus.student_management.ui.course.CoursePresenter;
import org.fastcampus.student_management.ui.student.StudentController;
import org.fastcampus.student_management.ui.student.StudentPresenter;
import org.fastcampus.student_management.ui.UserInputType;
public class Main {
public static void main(String[] args) {
StudentRepository studentRepository = new StudentRepository();
CourseCommandRepositoryImpl courseCommandRepository = new CourseCommandRepositoryImpl();
CourseJdbcRepository courseJdbcRepository = new CourseJdbcRepository();
StudentService studentService = new StudentService(studentRepository);
CourseService courseService = new CourseService(courseCommandRepository, courseJdbcRepository, studentRepository);
CoursePresenter coursePresenter = new CoursePresenter();
StudentPresenter studentPresenter = new StudentPresenter();
CourseController courseController = new CourseController(coursePresenter, courseService, studentPresenter);
StudentController studentController = new StudentController(studentPresenter, studentService);
studentPresenter.showMenu();
UserInputType userInputType = studentController.getUserInput();
while (userInputType != UserInputType.EXIT) {
switch (userInputType) {
case NEW_STUDENT:
studentController.registerStudent();
break;
case NEW_COURSE:
courseController.registerCourse();
break;
case SHOW_COURSE_DAY_OF_WEEK:
courseController.showCourseDayOfWeek();
break;
case ACTIVATE_STUDENT:
studentController.activateStudent();
break;
case DEACTIVATE_STUDENT:
studentController.deactivateStudent();
break;
case CHANGE_FEE:
courseController.changeFee();
break;
default:
studentPresenter.showErrorMessage();
break;
}
studentPresenter.showMenu();
userInputType = studentController.getUserInput();
}
}
}