ํด๋ฆฐ ์ํคํ ์ฒ ์ดํดํ๊ธฐ
๊ฐ์
์ง๊ธ๊น์ง ์ฌ๋ฌ ํ๋ก์ ํธ๋ฅผ ์งํํ๋ฉด์ ๋ ์ด์ด๋ ์ํคํ ์ฒ๋ฅผ ์ฌ์ฉํด ์์ต๋๋ค. ๊ฐ์ฅ ์ฒ์ ์ ํ ์ํคํ ์ฒ์๊ณ , ์ต์ํ๊ธฐ ๋๋ฌธ์ ์์ฐ์ค๋ฝ๊ฒ ์ ํํด ์์ต๋๋ค. ํ์ง๋ง ์๊ฐ์ด ์ง๋ ์๋ก ๋ ์ด์ด๋ ์ํคํ ์ฒ์ ๋ํ ์๋ฌธ์ด ์๊ฒผ์ต๋๋ค.
ํจํค์ง ๊ตฌ์กฐ๊ฐ ํ๋์ ๋ค์ด์ค์ง ์์๊ณ , ์๋ก์ด ํด๋์ค๋ฅผ ์์ฑํ ๋๋ง๋ค ์ด๋์ ์์น์์ผ์ผ ํ ์ง ๊ณ ๋ฏผํ๋ ์๊ฐ๋ ๋ง์์ก์ต๋๋ค. ๊ธฐ๋ฅ์ ์ถ๊ฐํ๊ฑฐ๋ ์์ ํ ๋๋ ๊ฐ์ ๋ฌธ์ ๊ฐ ๋ฐ๋ณต๋์์ต๋๋ค.
์ด๋ฐ ๊ฒฝํ์ด ์์ด๋ฉด์ ์์ฐ์ค๋ฝ๊ฒ ๋ค๋ฅธ ์ํคํ
์ฒ์ ๊ด์ฌ์ด ์๊ฒผ์ต๋๋ค. ํด๋ฆฐ ์ํคํ
์ฒ์ ํฅ์ฌ๊ณ ๋ ์ํคํ
์ฒ, ์ด์ ๋ถํฐ ๋ง์ด ๋ค์ด๋ดค์ง๋ง, ๋น์์๋ ํฌ๊ฒ ์๋ฟ์ง ์์๊ณ , ์ดํด ์์ด ์ ์ฉํ๋ ค ํ๋ ์ด๋ ต๊ฒ๋ง ๋๊ปด์ ธ ๋ฏธ๋ค๋์์ต๋๋ค.
ํ์ง๋ง ์์ ์ธ๊ธํ ๋ฌธ์ ๋ค์ด ๊ณ์๋๋ฉด์ ์ด์ ๋ ์ ๋๋ก ์ดํดํ๊ณ ์ ์ฉํด ๋ด์ผ๊ฒ ๋ค๋ ์๊ฐ์ด ๋ค์์ต๋๋ค. ๊ทธ๋ฌ๋ค ์ฐ์ฐํ ๋ง๋ค๋ฉด์ ๋ฐฐ์ฐ๋ ํด๋ฆฐ ์ํคํ ์ฒ๋ผ๋ ์ฑ ์ ์๊ฒ ๋์๊ณ , ์ด ์ฑ ์ ์ฝ์ผ๋ฉฐ ํด๋ฆฐ ์ํคํ ์ฒ์ ๊ดํ ๋ด์ฉ๊ณผ ์ ์ ์๊ฐ์ ์ ๋ฆฌํด ๋ณด๋ ค ํฉ๋๋ค.
๋ ์ด์ด๋ ์ํคํ ์ฒ์ ๋ฌธ์ ์
์ฑ ์์๋ ๋ ์ด์ด๋ ์ํคํ ์ฒ๊ฐ ๊ฐ์ง๋ ๋ช ๊ฐ์ง ๋ฌธ์ ์ ์ ์ง์ ํฉ๋๋ค. ๊ทธ์ค ๊ฐ์ฅ ์๋ฟ๋ ๋ถ๋ถ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฃผ๋ ์ค๊ณ๋ก ํ๋ฅด๊ธฐ ์ฝ๋ค๋ ์ ์ด์์ต๋๋ค. ์๋ฅผ ๋ค์ด, ํํ๋ค ์ฌ์ฉํ๋ ORM ํ๋ ์์ํฌ์ @Entity, @JoinColumn ๋ฑ์ ์ด๋ ธํ ์ด์ ์ด ์ ์ฉ๋ ์ํฐํฐ ํด๋์ค๊ฐ ๋ํ์ ์ ๋๋ค.
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Entity
public class HouseWork {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@ManyToOne
@JoinColumn(name = "place_id")
private Place place;
@ManyToOne
@JoinColumn(name = "house_work_group_id")
private Group group;
...
}
์ด์ฒ๋ผ ์ํฐํฐ๊ฐ JPA ์ด๋ ธํ ์ด์ ์ ๋ฌถ์ฌ ์๋ค ๋ณด๋ ์๋น์ค ๊ณ์ธต์ด ์์์ฑ ๋ชจ๋ธ์ ๊ณง ๋น์ฆ๋์ค ๋ชจ๋ธ์ฒ๋ผ ์ฌ์ฉํ๋ ๋ฌธ์ ๊ฐ ์๊ธฐ๊ณ , ๊ฒฐ๊ตญ ์์์ฑ ๊ณ์ธต๊ณผ ๋๋ฉ์ธ ๊ณ์ธต ์ฌ์ด์ ๊ฐํ ๊ฒฐํฉ์ด ํ์ฑ๋ฉ๋๋ค. ๋ํ JPA ์คํ์ private๊ฐ ์๋ ๊ธฐ๋ณธ ์์ฑ์๊ฐ ๋ฐ๋์ ํ์ํ๋ค๋ ์ ๋ ํ๋ ์์ํฌ์ ๋ํ ์์กด์ฑ์ ๋๋ฌ๋ด๋ ์์๋ผ ํ ์ ์์ต๋๋ค.
์ด๋ฐ ์์ผ๋ก ๋๋ฉ์ธ์ด ์์์ฑ์ ์์กดํ๊ฒ ๋๋ค๋ฉด, ์๋น์ค๊ฐ JPA ์ํฐํฐ๋ฅผ ์ง์ ๋ค๋ฃจ๊ธฐ ๋๋ฌธ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ๊ตฌ์กฐ๊ฐ ๋ฐ๋์์ ๋ ๊ทธ ๋ณํ๊ฐ ๊ณง๋ฐ๋ก ๋๋ฉ์ธ๊ณผ ๋น์ฆ๋์ค ๋ก์ง์ ์ํฅ์ ๋ฏธ์น๊ฒ ๋ฉ๋๋ค. ์ฆ, ์์กด์ฑ์ ๋ฐฉํฅ์ด ์์ชฝ(๋๋ฉ์ธ)์ผ๋ก ํฅํ์ง ์๊ณ ๋ฐ๊นฅ์ชฝ์ผ๋ก ํฅํ๋ ์ํ์ ๋๋ค.
๋ ๋ค๋ฅธ ๋ฌธ์ ๋ ๋ ์ด์ด๋ ์ํคํ ์ฒ์ ๋จ์ํ ๊ท์น์ฑ์ ๋๋ค. "ํน์ ๊ณ์ธต์ ๊ฐ์ ๊ณ์ธต์ด๋ ํ์ ๊ณ์ธต์๋ง ์ ๊ทผํ ์ ์๋ค."๋ ์ ๋์ ๊ท์น๋ง ์กด์ฌํ๋ค ๋ณด๋, ๊ตฌ์กฐ์ ์ ์ฝ์ด ์ฝํ๊ณ ํธ์ ์์ฃผ์ ๋ฐฉํฅ์ผ๋ก ํ๋ฌ๊ฐ ์ ์์ต๋๋ค. ์ด๋ ๊ฒฐ๊ตญ ์ฝ๋๋ฅผ ์ง์ ๋ถํ๊ฒ ๋ง๋ค์ด ์ ์ง๋ณด์์ฑ์ ๋จ์ด๋จ๋ฆฌ๊ฒ ๋๋๋ฐ, ๋ํ์ ์ธ ์๊ฐ ๋ค์๊ณผ ๊ฐ์ด ๋น๋ํด์ง ์๋น์ค ํด๋์ค์ ๋๋ค.
@RequiredArgsConstructor
@Transactional(readOnly = true)
@Service
public class HouseWorkService {
private final HouseWorkRepository houseWorkRepository;
private final HouseWorkTagRepository houseWorkTagRepository;
private final HouseWorkMemberRepository houseWorkMemberRepository;
private final EmotionCardRepository emotionCardRepository;
private final MemberService memberService;
private final GroupService groupService;
public List<HouseWorkStatusByPeriodResponse> getHouseWorkStatusByPeriod(
Long groupId,
LocalDate from,
LocalDate to
) {
List<HouseWorkStatusByPeriodResponse> responses = new ArrayList<>();
List<LocalDate> result = houseWorkRepository.findTaskDatesBetween(groupId, from, to);
for (LocalDate date = from; !date.isAfter(to); date = date.plusDays(1)) {
responses.add(new HouseWorkStatusByPeriodResponse(date, result.contains(date)));
}
return responses;
}
@Transactional
public void completeHouseWork(Long memberId, Long houseWorkId) {
if (!houseWorkMemberRepository.existsByHouseWorkIdAndMemberId(houseWorkId, memberId)) {
throw new IllegalStateException("Not authorized");
}
HouseWork houseWork = findById(houseWorkId);
houseWork.markCompleted();
}
...
}
(์ค์ ์ฝ๋ ์ ์ฒด๋ ์ฝ 500์ค์ ๋ฌํ๋ ์๋นํ ๋ฑ๋ฑํ ์๋น์ค ํด๋์ค์ ๋๋ค.)
์ด์ฒ๋ผ ๋น๋ํด์ง ์๋น์ค๋ ์ฌ๋ฌ ์์์ฑ ๊ณ์ธต์ ์์กดํ๊ฒ ๋๊ณ , ๋ง์ ์น ๊ณ์ธต ๋ํ ์ด ์๋น์ค์ ์์กดํ๊ฒ ๋ฉ๋๋ค. ๊ทธ ๊ฒฐ๊ณผ, ๊ฐ ๊ธฐ๋ฅ(์ ์ค์ผ์ด์ค)์ ์ฑ ์์ด ์ด๋์ ์๋์ง ์ฐพ๊ธฐ ํ๋ค์ด์ง๊ณ , ์๋ก์ด ๊ธฐ๋ฅ์ ์ถ๊ฐํ๊ฑฐ๋ ๊ธฐ์กด ๋ก์ง์ ์์ ํ ๋ ์ํฅ๋ฐ๋ ๋ฒ์๋ฅผ ์์ธกํ๊ธฐ ํ๋ค์ด์ง๋๋ค.
์ ์ญ์ ํ๋ก์ ํธ๋ฅผ ์งํํ๋ฉฐ ๋น๋ํด์ง ์๋น์ค๋ก ์ธํด ์ง์ ๊ฒช์ ๋ฌธ์ ์ ์ด ์์ต๋๋ค. ํ ๋จ์๋ก ๊ฐ๋ฐํ ๊ฒฝ์ฐ, ์๋ก ๋ค๋ฅธ ๊ธฐ๋ฅ์ ๊ตฌํํ๋๋ผ๋ ๊ฐ์ ์๋น์ค ํด๋์ค ๋ด์์ ์์ ํ๋ค ๋ณด๋ ์ฝ๋ ์ถฉ๋์ด ๋น๋ฒํ๊ฒ ๋ฐ์ํ์ต๋๋ค. ๊ทธ๋ก ์ธํด ๋ณํฉ ์ ์ถฉ๋์ ํด๊ฒฐํด์ผ ํ๋ ๋ฒ๊ฑฐ๋ก์ด ์ํฉ์ ์์ฃผ ๋ง๋ฌ๋ ๊ฒฝํ์ด ์์ต๋๋ค.
์ด ์ธ์๋ ์ฌ๋ฌ ๋ฌธ์ ์ ์ด ์กด์ฌํ๋๋ฐ, ๊ฒฐ๊ตญ ๊ณตํต๋ ๋ฌธ์ ๋ ์ฝ๋์ ์ดํด์ ํ ์คํธ๋ฅผ ์ด๋ ต๊ฒ ๋ง๋ค๊ณ , ๊ทธ๋ก ์ธํด ์ ์ง๋ณด์๊ฐ ์ด๋ ค์์ง๋ค๋ ์ ์ ๋๋ค.
ํด๋ฆฐ ์ํคํ ์ฒ๋
ํด๋ฆฐ ์ํคํ ์ฒ๋ ์์ ์ธ๊ธํ ๋ ์ด์ด๋ ์ํคํ ์ฒ์ ๋ฌธ์ ์ ๋ค์ ํด๊ฒฐํ ์ ์๋ ๋ฐฉํฅ์ ์ ์ํฉ๋๋ค.

๊ฐ์ฅ ํต์ฌ์ ์ธ ์์น์ ์์กด์ฑ์ ๋ํ ๊ฒ์ผ๋ก, ๋๋ฉ์ธ ๊ณ์ธต์ ์ค์ฌ์ผ๋ก ๊ณ์ธต ๊ฐ์ ๋ชจ๋ ์์กด์ฑ์ด ์์ชฝ์ผ๋ก๋ง ํฅํด์ผ ํ๋ค๋ ๊ฒ์
๋๋ค. ๋๋ฉ์ธ์ ๋น์ฆ๋์ค์ ๋ณธ์ง์ ํํํ๋ ์์ญ์ผ๋ก, ๋ค๋ฅธ ๊ณ์ธต์ ๋นํด ๋ณ๊ฒฝ ๊ฐ๋ฅ์ฑ์ด ๊ฐ์ฅ ๋ฎ์ ์์ ์ ์ธ ์์ญ์
๋๋ค. ๋ฐ๋ฉด ์ธ๋ถ ์์(UI๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ฑ)๋ ๊ธฐ์ ๋ณํ๋ ์๊ตฌ์ฌํญ์ ๋ฐ๋ผ ์์ฃผ ๋ฐ๋๋ ์์ญ์
๋๋ค.
๋ฐ๋ผ์ ์์กด์ฑ์ ์์ชฝ์ผ๋ก ํฅํ๊ฒ ํจ์ผ๋ก์จ ์ธ๋ถ ๊ณ์ธต์ ๋ณ๊ฒฝ์ด ๋๋ฉ์ธ์ ์ํฅ์ ๋ฏธ์น์ง ์๋๋ก ํด์ผ ํฉ๋๋ค. ์๋ฅผ ๋ค์ด, ์ด๋ค ๋ฐ์ดํฐ๋ฒ ์ด์ค๊ฐ ์ฌ์ฉ๋๋์ง, UI์ ๋ํ ์๊ตฌ์ฌํญ์ด ์ด๋ป๊ฒ ๋ฐ๋๋์ง ๋ฑ, ๋๋ฉ์ธ์์๋ ์ด๋ฐ ๊ฒ๋ค์ ์ ํ ์ ํ์๊ฐ ์์ต๋๋ค.
๋ํ ํด๋ฆฐ ์ํคํ ์ฒ์์๋ ์ ์ค์ผ์ด์ค(์๋น์ค)๋ฅผ ๊ธฐ์กด๋ณด๋ค ์ธ๋ถํํฉ๋๋ค. ์ด๋ฅผ ํตํด ๋จ์ผ ์ฑ ์ ์์น(SRP)์ ์ค์ํ ์ ์๊ณ , ๊ฐ ๊ธฐ๋ฅ์ด ๋ช ํํ ๋ถ๋ฆฌ๋์ด ํ ์คํธ๊ฐ ์ฌ์์ง๋๋ค.
์ด์ ์ฒ๋ผ ํ๋์ ๊ฑฐ๋ํ ์๋น์ค ํด๋์ค์์ ์ฌ๋ฌ ๊ธฐ๋ฅ์ ํจ๊ป ๋ค๋ฃฐ ๋ ๊ฒช๋ ๋ถํธํจ๋ ์ค์ด๋ญ๋๋ค. ๊ทธ ๊ฒฐ๊ณผ, ์ฝ๋์ ๊ตฌ์กฐ๊ฐ ๋ช ํํด์ง๊ณ , ๊ธฐ๋ฅ ์ถ๊ฐ๋ ๋ณ๊ฒฝ์ด ์ฌ์์ง๋ฉฐ, ํ ๋จ์ ํ์ ์์๋ ๋์ ์์ ์ด ํจ์ฌ ์์ํด์ง๋๋ค.
๋ฌผ๋ก ํด๋ฆฐ ์ํคํ ์ฒ์๋ ๋จ์ ์ ์กด์ฌํฉ๋๋ค. ์์กด์ฑ ๋ฐฉํฅ์ ์งํค๊ณ ๊ฐ ๊ณ์ธต์ ์ฑ ์์ ๋ช ํํ ํ๋ค ๋ณด๋ฉด ๊ตฌ์กฐ๊ฐ ๋ค์ ๋ณต์กํด์ง๊ณ , ๊ตฌํ ๊ณผ์ ์ด ๋ฒ๊ฑฐ๋ก์์ง ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, JPA ์ํฐํฐ๋ ์์์ฑ ๊ณ์ธต์์ ๊ด๋ฆฌํด์ผ ํ๋ฏ๋ก ๋๋ฉ์ธ ๊ณ์ธต์๋ ๋ณ๋์ ์ํฐํฐ ํด๋์ค๋ฅผ ๋ฐ๋ก ๊ด๋ฆฌํด์ผ ํ๋ ๋ฒ๊ฑฐ๋ก์์ด ์์ต๋๋ค. ๋ํ ํ๋ก์ ํธ์ ๊ท๋ชจ๊ฐ ํฌ์ง ์๊ฑฐ๋ ์ฃผ์ด์ง ๊ฐ๋ฐ ๊ธฐ๊ฐ์ด ์งง์ ๊ฒฝ์ฐ, ์ด๋ฌํ ๊ตฌ์กฐ์ ๋ณต์กํจ์ด ์คํ๋ ค ๊ฐ๋ฐ ํจ์จ์ ๋จ์ด๋จ๋ฆฌ๋ ์์ธ์ด ๋ ์๋ ์์ต๋๋ค.
๋ง๋ฌด๋ฆฌ
๊ฒฐ๊ตญ ํด๋ฆฐ ์ํคํ ์ฒ๋ฅผ ์งํฅํ๋, ๋งน์ ํ์ง๋ ๋ง์์ผ ํ๋ค๊ณ ์๊ฐํฉ๋๋ค. ํด๋ฆฐ ์ํคํ ์ฒ๊ฐ ์ ์ํ๋ ์์น๋ค์ ๋ชจ๋ ๊นจ๋ํ ๊ตฌ์กฐ๋ฅผ ์ ์งํ๋ ๋ฐ ํฐ ๋์์ด ๋์ง๋ง, ์ํฉ์ ๋ฐ๋ผ์๋ ์คํ๋ ค ๋นํจ์จ์ ์ด๋ํ ์๋ ์์ต๋๋ค.
์ ์ ๊ฒฝํ์ ์๋ก ๋ค๋ฉด 8์ฃผ๊ฐ์ IT ๋์๋ฆฌ ํ๋ ์ค ์ค์ ๊ฐ๋ฐ ๊ธฐ๊ฐ์ด ์ฝ 3์ฃผ ์ ๋๋ฐ์ ๋์ง ์์์ต๋๋ค. ๋ง์ฝ ๊ทธ ์ํฉ์์ ํด๋ฆฐ ์ํคํ ์ฒ๋ฅผ ๊ผผ๊ผผํ ์ ์ฉํ๋ ค ํ๋ค๋ฉด ์๋ง ๋ง๊ฐ ๊ธฐํ์ ๋ง์ถ๊ธฐ ์ด๋ ค์ ์ ๊ฒ์ ๋๋ค.
์ด์ฒ๋ผ ์๊ฐ์ด ์ด๋ฐํ ์ํฉ์์๋ ๋จ์ํ ๊ตฌ์กฐ๋ก ๋น ๋ฅด๊ฒ ๊ตฌํํ๋ ๊ฒ๋ ์ถฉ๋ถํ ์ข์ ์ ํ์ง๋ผ๊ณ ์๊ฐํฉ๋๋ค. ์๋ฅผ ๋ค์ด, ์น ๊ณ์ธต๊ณผ ์๋น์ค ๊ณ์ธต ๊ฐ์ ์์กด์ฑ์ ์ด๋ฏธ ๋๋ฉ์ธ ๋ฐฉํฅ์ผ๋ก ํฅํด์๊ธฐ ๋๋ฌธ์ ๊ตณ์ด ํฌํธ๋ฅผ ๋์ง ์๋ ๋ฐฉ์์ผ๋ก ๋จ์ํํ ์ ์์ต๋๋ค.
์ดํ ํ๋ก์ ํธ๊ฐ ์ข ๋ ๋ณต์กํด์ง๊ฑฐ๋ ์ ์ง๋ณด์์ ์ฌ์ ๊ฐ ์๊ธด ์์ ์ ํด๋ฆฐ ์ํคํ ์ฒ๋ฅผ ์ ์ง์ ์ผ๋ก ์ ์ฉํ๋ ์ ๊ทผ์ด ๋ ํ์ค์ ์ธ ๋ฐฉ์์ด ๋ ์ ์๋ค๊ณ ์๊ฐํฉ๋๋ค.
ํ์ง๋ง ์ ์ง๋ณด์์ ์ฉ์ดํ ์ฝ๋๊ฐ ์ข์ ์ฝ๋๋ผ๋ ์๊ฐ์๋ ๋ณํจ์ด ์์ต๋๋ค. ์ฑ ์์๋ "๊นจ์ง ์ ๋ฆฌ์ฐฝ ์ด๋ก "์ ์ธ๊ธํ๋๋ฐ, ์ด๋ ๊นจ์ง ์ ๋ฆฌ์ฐฝ ํ๋๋ฅผ ๋ฐฉ์นํ๋ฉด ๊ทธ ์ฃผ๋ณ์ผ๋ก ๋ฒ์ฃ๊ฐ ํ์ฐ๋๋ค๋ ์ด๋ก ์ ๋๋ค. ์ฝ๋ ์ญ์ ๋ง์ฐฌ๊ฐ์ง์ ๋๋ค. ์ฌ์ํด ๋ณด์ด๋ ๊ท์น ์๋ฐ์ ๋ฐฉ์นํ๋ค ๋ณด๋ฉด ๊ทธ ๋์ ์ด ์์ฌ ์ฝ๋ ํ์ง์ด ์ ์ ๋จ์ด์ง๊ณ , ๊ฒฐ๊ตญ ๋ ๊ฑฐ์ ์ฝ๋๋ก ๋ณํ๊ฒ ๋ ๊ฒ์ ๋๋ค. ์ ๋ํ ํ๋ก์ ํธ๋ฅผ ์งํํ๋ฉด์ ์ด๋ฐ ๊ณผ์ ์ ์ง์ ๊ฒฝํํ๊ธฐ์ ์ด ๋ถ๋ถ์ ํนํ ๊ณต๊ฐ์ด ๋์ต๋๋ค.
์์ผ๋ก ์งํํ ํ๋ก์ ํธ์์๋ ๋ ์ด์ด๋ ์ํคํ ์ฒ์์ ๋ฒ์ด๋, ํด๋ฆฐ ์ํคํ ์ฒ์ ํต์ฌ ์์น์ ๋ฐํ์ผ๋ก ์๊ฐ์ด ์ง๋๋ ๊ฒฌ๊ณ ํ๊ณ ์ ์ง๋ณด์ํ๊ธฐ ์ฌ์ด ๊ตฌ์กฐ๋ฅผ ๋ง๋ค์ด๊ฐ๊ณ ์ ํฉ๋๋ค.