-
Notifications
You must be signed in to change notification settings - Fork 164
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
2단계 - 리팩터링(메뉴) #169
base: chr0m3
Are you sure you want to change the base?
2단계 - 리팩터링(메뉴) #169
Changes from 16 commits
bde7ea3
86b5760
4022276
8382a9b
a1644b4
b84cfe6
eb121a6
4e44a8f
2c52931
0146904
a968bc6
7ff9973
3621adb
5aab011
58bd527
0701e17
bf9bfb1
44adb96
2d16e74
218f580
c346395
26aa5e7
ac684f6
748ee71
96fe49a
f795b5c
2c7035e
a662282
a753755
86dc9e6
81afbbc
bd08ccb
71f200a
139c6f8
1c460a0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
package kitchenpos.menu.tobe.domain.entity; | ||
|
||
import java.util.Collections; | ||
import java.util.List; | ||
import java.util.UUID; | ||
import kitchenpos.common.name.Name; | ||
import kitchenpos.common.price.Price; | ||
import kitchenpos.menu.tobe.domain.service.MenuDisplayPolicy; | ||
import kitchenpos.menu.tobe.domain.vo.MenuGroup; | ||
import kitchenpos.menu.tobe.domain.vo.MenuProduct; | ||
|
||
public class Menu { | ||
|
||
public final UUID id; | ||
|
||
public final Name name; | ||
|
||
public final MenuGroup menuGroup; | ||
|
||
private final List<MenuProduct> menuProducts; | ||
|
||
private Boolean displayed; | ||
|
||
private Price price; | ||
|
||
public Menu( | ||
final UUID id, | ||
final Name name, | ||
final Boolean displayed, | ||
final Price price, | ||
final MenuGroup menuGroup, | ||
final List<MenuProduct> menuProducts | ||
) { | ||
this.id = id; | ||
this.name = name; | ||
this.displayed = displayed; | ||
this.price = price; | ||
this.menuGroup = menuGroup; | ||
this.menuProducts = menuProducts; | ||
} | ||
|
||
public boolean displayed() { | ||
return this.displayed; | ||
} | ||
|
||
public Price price() { | ||
return this.price; | ||
} | ||
|
||
public List<MenuProduct> menuProducts() { | ||
return Collections.unmodifiableList(this.menuProducts); | ||
} | ||
|
||
public void display() { | ||
if (!MenuDisplayPolicy.isDisplayable(this)) { | ||
throw new IllegalStateException("메뉴 노출 정책에 따라 이 메뉴를 노출할 수 없습니다"); | ||
} | ||
this.displayed = true; | ||
} | ||
|
||
public void hide() { | ||
this.displayed = false; | ||
} | ||
|
||
public void setPrice(final Price price) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. setter 네이밍을 사용하기 보다는 의미있는 네이밍을 고민해보세요 😄 |
||
if (!MenuDisplayPolicy.isDisplayable(this)) { | ||
this.hide(); | ||
} | ||
this.price = price; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package kitchenpos.menu.tobe.domain.entity; | ||
|
||
import java.util.UUID; | ||
import kitchenpos.common.name.Name; | ||
|
||
public class MenuGroup { | ||
|
||
public final UUID id; | ||
|
||
public final Name name; | ||
|
||
public MenuGroup(final UUID id, final Name name) { | ||
this.id = id; | ||
this.name = name; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package kitchenpos.menu.tobe.domain.repository; | ||
|
||
import java.util.List; | ||
import java.util.Optional; | ||
import java.util.UUID; | ||
import kitchenpos.menu.tobe.domain.entity.MenuGroup; | ||
|
||
public interface MenuGroupRepository { | ||
|
||
MenuGroup save(MenuGroup menuGroup); | ||
|
||
Optional<MenuGroup> findById(UUID id); | ||
|
||
List<MenuGroup> findAll(); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package kitchenpos.menu.tobe.domain.repository; | ||
|
||
import java.util.List; | ||
import java.util.Optional; | ||
import java.util.UUID; | ||
import kitchenpos.menu.tobe.domain.entity.Menu; | ||
|
||
public interface MenuRepository { | ||
|
||
Menu save(final Menu menu); | ||
|
||
Optional<Menu> findById(final UUID id); | ||
|
||
List<Menu> findAll(); | ||
|
||
List<Menu> findAllByIdIn(final List<UUID> ids); | ||
|
||
List<Menu> findAllByProductId(final UUID productId); | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package kitchenpos.menu.tobe.domain.service; | ||
|
||
|
||
import kitchenpos.common.price.Price; | ||
import kitchenpos.menu.tobe.domain.entity.Menu; | ||
import kitchenpos.menu.tobe.domain.vo.MenuProduct; | ||
import org.springframework.stereotype.Service; | ||
|
||
@Service | ||
public class MenuDisplayPolicy { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이 때는 별도의 클래스로 분리했지만 실제로 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 현재 구현해주신 코드는 Menu Aggregate만을 사용하게 되지만, 가격 변경시 |
||
|
||
private MenuDisplayPolicy() { | ||
} | ||
|
||
public static boolean isDisplayable(final Menu menu) { | ||
final Price total = menu.menuProducts() | ||
.stream() | ||
.map(MenuProduct::subtotal) | ||
.reduce(new Price(0), Price::add); | ||
return menu.price().compareTo(total) <= 0; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package kitchenpos.menu.tobe.domain.vo; | ||
|
||
import kitchenpos.common.name.Name; | ||
|
||
public class MenuGroup { | ||
|
||
public final Name name; | ||
|
||
public MenuGroup(final Name name) { | ||
this.name = name; | ||
} | ||
|
||
@Override | ||
public boolean equals(final Object o) { | ||
if (this == o) { | ||
return true; | ||
} | ||
if (o == null || getClass() != o.getClass()) { | ||
return false; | ||
} | ||
|
||
MenuGroup menuGroup = (MenuGroup) o; | ||
|
||
return name.equals(menuGroup.name); | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return name.hashCode(); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
package kitchenpos.menu.tobe.domain.vo; | ||
|
||
import java.util.UUID; | ||
import kitchenpos.common.price.Price; | ||
|
||
public class MenuProduct { | ||
|
||
public final UUID productId; | ||
|
||
public final Price pricePerUnit; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 단순히 |
||
|
||
public final MenuProductQuantity quantity; | ||
|
||
public MenuProduct( | ||
final UUID productId, | ||
final Price pricePerUnit, | ||
final MenuProductQuantity quantity | ||
) { | ||
this.productId = productId; | ||
this.pricePerUnit = pricePerUnit; | ||
this.quantity = quantity; | ||
} | ||
|
||
public Price subtotal() { | ||
return this.pricePerUnit.multiply(this.quantity.value); | ||
} | ||
|
||
@Override | ||
public boolean equals(final Object o) { | ||
if (this == o) { | ||
return true; | ||
} | ||
if (o == null || getClass() != o.getClass()) { | ||
return false; | ||
} | ||
|
||
MenuProduct that = (MenuProduct) o; | ||
|
||
if (!productId.equals(that.productId)) { | ||
return false; | ||
} | ||
if (!pricePerUnit.equals(that.pricePerUnit)) { | ||
return false; | ||
} | ||
return quantity.equals(that.quantity); | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
int result = productId.hashCode(); | ||
result = 31 * result + pricePerUnit.hashCode(); | ||
result = 31 * result + quantity.hashCode(); | ||
return result; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
package kitchenpos.menu.tobe.domain.vo; | ||
|
||
/** | ||
* <h1>메뉴 상품 수량</h1> | ||
* <ul> | ||
* <li>메뉴 상품별 수량은 1 이상이다.</li> | ||
* </ul> | ||
*/ | ||
public class MenuProductQuantity { | ||
|
||
final long value; | ||
|
||
public MenuProductQuantity(final long value) { | ||
if (value < 1) { | ||
throw new IllegalArgumentException("MenuProductQuantity는 1보다 작을 수 없습니다"); | ||
} | ||
this.value = value; | ||
} | ||
|
||
@Override | ||
public boolean equals(final Object o) { | ||
if (this == o) { | ||
return true; | ||
} | ||
if (o == null || getClass() != o.getClass()) { | ||
return false; | ||
} | ||
|
||
MenuProductQuantity that = (MenuProductQuantity) o; | ||
|
||
return value == that.value; | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return (int) (value ^ (value >>> 32)); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package kitchenpos.menu.tobe.infra.jpa; | ||
|
||
import java.util.UUID; | ||
import org.springframework.data.jpa.repository.JpaRepository; | ||
import org.springframework.stereotype.Repository; | ||
|
||
@Repository | ||
public interface JpaMenuGroupDao extends JpaRepository<MenuGroupEntity, UUID> { | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
package kitchenpos.menu.tobe.infra.jpa; | ||
|
||
import java.util.List; | ||
import java.util.Optional; | ||
import java.util.UUID; | ||
import java.util.stream.Collectors; | ||
import kitchenpos.menu.tobe.domain.entity.MenuGroup; | ||
import kitchenpos.menu.tobe.domain.repository.MenuGroupRepository; | ||
import kitchenpos.menu.tobe.infra.jpa.MenuGroupEntityConverter.MenuGroupEntityToMenuGroupConverter; | ||
import kitchenpos.menu.tobe.infra.jpa.MenuGroupEntityConverter.MenuGroupToMenuGroupEntityConverter; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.stereotype.Repository; | ||
|
||
@Repository | ||
public class JpaMenuGroupRepository implements MenuGroupRepository { | ||
|
||
private final JpaMenuGroupDao jpaMenuGroupDao; | ||
|
||
private final MenuGroupToMenuGroupEntityConverter menuGroupToMenuGroupEntityConverter; | ||
|
||
private final MenuGroupEntityToMenuGroupConverter menuGroupEntityToMenuGroupConverter; | ||
|
||
@Autowired | ||
public JpaMenuGroupRepository( | ||
JpaMenuGroupDao jpaMenuGroupDao, | ||
MenuGroupToMenuGroupEntityConverter menuGroupToMenuGroupEntityConverter, | ||
MenuGroupEntityToMenuGroupConverter menuGroupEntityToMenuGroupConverter | ||
) { | ||
this.jpaMenuGroupDao = jpaMenuGroupDao; | ||
this.menuGroupToMenuGroupEntityConverter = menuGroupToMenuGroupEntityConverter; | ||
this.menuGroupEntityToMenuGroupConverter = menuGroupEntityToMenuGroupConverter; | ||
} | ||
|
||
@Override | ||
public MenuGroup save(MenuGroup menuGroup) { | ||
final MenuGroupEntity menuGroupEntity = this.menuGroupToMenuGroupEntityConverter.convert(menuGroup); | ||
final MenuGroupEntity result = this.jpaMenuGroupDao.save(menuGroupEntity); | ||
return this.menuGroupEntityToMenuGroupConverter.convert(result); | ||
} | ||
|
||
@Override | ||
public Optional<MenuGroup> findById(UUID id) { | ||
final Optional<MenuGroupEntity> result = this.jpaMenuGroupDao.findById(id); | ||
if (result.isEmpty()) { | ||
return Optional.empty(); | ||
} | ||
return Optional.of(this.menuGroupEntityToMenuGroupConverter.convert(result.get())); | ||
} | ||
|
||
@Override | ||
public List<MenuGroup> findAll() { | ||
return this.jpaMenuGroupDao.findAll() | ||
.stream() | ||
.map(this.menuGroupEntityToMenuGroupConverter::convert) | ||
.collect(Collectors.toUnmodifiableList()); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package kitchenpos.menu.tobe.infra.jpa; | ||
|
||
import java.util.UUID; | ||
import javax.persistence.Column; | ||
import javax.persistence.Entity; | ||
import javax.persistence.Id; | ||
|
||
@Entity | ||
public class MenuGroupEntity { | ||
|
||
@Column(name = "id", columnDefinition = "binary(16)") | ||
@Id | ||
public UUID id; | ||
|
||
@Column(name = "name", nullable = false) | ||
public String name; | ||
|
||
public MenuGroupEntity() { | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
굳이
isVisible
로 바꿔야만 하는 이유가 없어서 불필요한 데이터베이스 변경을 만들지 않기 위해displayed
를 그대로 사용하기로 했습니다.