<aside> ❗
<aside> ❗
[특징]
package hello.core.order;
import hello.core.discount.DiscountPolicy;
import hello.core.member.Member;
import hello.core.member.MemberRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class OrderServiceImpl implements OrderService{
private final MemberRepository memberRepository;
private final DiscountPolicy discountPolicy;
@Autowired
public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy discountPolicy) {
this.memberRepository = memberRepository;
this.discountPolicy = discountPolicy;
}
@Override
public Order createOrder(Long memberId, String itemName, int itemPrice) {
Member member = memberRepository.findById(memberId);
// 주문 서비스 입장에서 할인에 대한 것 모르겠다. discountPolicy 니가 알아서 해줘 - 단일 책임 원칙을 잘 지킨 것
// 즉, 할인 변경을 수행할 때, 할인 쪽만 고치면 됨
// member 전체를 넘겨도 되고, 등급만 넘겨도 된다. - 상황에 맞게 구현하면 됨
int discountPrice = discountPolicy.discount(member, itemPrice);
return new Order(memberId, itemName, itemPrice, discountPrice);
}
public MemberRepository getMemberRepository() {
return memberRepository;
}
}
[기타 팁]
좋은 개발은 한계점이랑 제약이 있어야 한다. 가급적 생성자에 값을 넣고 Setter 메서드를 안 만드는게 좋다. → 버그가 줄어든다.
관례상 생성자의 인자는 웬만하면 값을 다 넣어야 한다.
</aside>
<aside> ❗
[특징]
package hello.core.order;
import hello.core.discount.DiscountPolicy;
import hello.core.member.Member;
import hello.core.member.MemberRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class OrderServiceImpl implements OrderService{
private MemberRepository memberRepository;
private DiscountPolicy discountPolicy;
@Autowired
public void setMemberRepository(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
@Autowired
public void setDiscountPolicy(DiscountPolicy discountPolicy) {
this.discountPolicy = discountPolicy;
}
@Autowired
public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy discountPolicy) {
this.memberRepository = memberRepository;
this.discountPolicy = discountPolicy;
}
@Override
public Order createOrder(Long memberId, String itemName, int itemPrice) {
Member member = memberRepository.findById(memberId);
// 주문 서비스 입장에서 할인에 대한 것 모르겠다. discountPolicy 니가 알아서 해줘 - 단일 책임 원칙을 잘 지킨 것
// 즉, 할인 변경을 수행할 때, 할인 쪽만 고치면 됨
// member 전체를 넘겨도 되고, 등급만 넘겨도 된다. - 상황에 맞게 구현하면 됨
int discountPrice = discountPolicy.discount(member, itemPrice);
return new Order(memberId, itemName, itemPrice, discountPrice);
}
public MemberRepository getMemberRepository() {
return memberRepository;
}
}
[참고]
<aside> ❗
[특징]
package hello.core.order;
import hello.core.discount.DiscountPolicy;
import hello.core.member.Member;
import hello.core.member.MemberRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class OrderServiceImpl implements OrderService{
// 필드에 바로 주입
@Autowired
private MemberRepository memberRepository;
@Autowired
private DiscountPolicy discountPolicy;
@Override
public Order createOrder(Long memberId, String itemName, int itemPrice) {
Member member = memberRepository.findById(memberId);
// 주문 서비스 입장에서 할인에 대한 것 모르겠다. discountPolicy 니가 알아서 해줘 - 단일 책임 원칙을 잘 지킨 것
// 즉, 할인 변경을 수행할 때, 할인 쪽만 고치면 됨
// member 전체를 넘겨도 되고, 등급만 넘겨도 된다. - 상황에 맞게 구현하면 됨
int discountPrice = discountPolicy.discount(member, itemPrice);
return new Order(memberId, itemName, itemPrice, discountPrice);
}
public MemberRepository getMemberRepository() {
return memberRepository;
}
}
@Bean
OrderService orderService(MemberRepository memberRepoisitory, DiscountPolicy
discountPolicy) {
return null;
}
[참조]
OrderServiceImpl orderService = new OrderServiceImpl();
또한 테스트할 때, 구현객체 교체가 불가능
Ex) 스프링을 사용하지 않고 테스트할 때
더미 데이터를 갖고 있는 메모리 저장소를 사용하여 테스트 하고 싶은데
필드에 주입해줄 방법이 없음 (의존관계 필드들이 모두 NullPointerException)<aside> ❗
[특징]
@Component
public class OrderServiceImpl implements OrderService {
private MemberRepository memberRepository;
private DiscountPolicy discountPolicy;
@Autowired
public void init(MemberRepository memberRepository, DiscountPolicy discountPolicy) {
this.memberRepository = memberRepository;
this.discountPolicy = discountPolicy;
}
}
<aside> ❗
<aside> ❗
[자동 주입 대상을 옵션으로 처리하는 방법]
** 여기서 Member는 스프링 빈이 아닌 자바 순수 객체 **
// 의존관계가 없으면 해당 메서드 자체를 호출하지 않음
@Autowired(required = false)
public void setNoBean1(Member noBean1) {
System.out.println("noBean1 = " + noBean1);
}
@Autowired
public void setNoBean2(@Nullable Member noBean2) {
System.out.println("noBean2 = " + noBean2);
}
@Autowired
public void setNoBean3(Optional<Member> noBean3) {
System.out.println("noBean3 = " + noBean3);
}
noBean2 = null
noBean3 = Optional.empty
[참고]
<aside> ❗
[참고]
<aside> ❗
<aside> ❗
<aside> ❗