A가 B를 의존한다
➡️의존 대상 B가 변하면 그것이 A에 영향을 미친다.
- B의 기능이 추가 또는 변겨되거나 형식이 바뀌게 되면 그 영향이 A에 미치게 되는 것을 말한다.
💡의존성 주입은 필요한 객체를 직접 생성하거나 찾지 않고, 외부에서 필요한 객체를 받아 사용하는 것이다.
이를 통해 객체간의 결합도
를 줄이고 코드의 재활용성
을 높여준다.
이 개발 블로그에 글을 쓰는 상황에 대해 생각해 보았다.
개발 공부 기록 목적의 블로그를 만들고, 여기에 안드로이드 앱 개발 관련 포스트를 작성해 보자.
"개발 공부 글을 올려야지!"
블로그에 올리는 포스트에 따라 다른 메소드들을 필요로 하지 않기 때문에, AndroidPost()라는 객체를 만들어준 후 Blog()가 이를 의존
하게 하면 된다.
// Blog 객체 생성
Blog blog = new Blog();
// 새로운 글 작성하기
blog.getNewPost();
class Blog {
private AndroidPost androidPost;
public Blog() {
// 블로그가 AndroidPost()에 의존한다
this.androidPost = new AndroidPost()
}
// 새로운 글을 작성할 때 사용할 함수
public getNewPost() {
// AndroidPost에 있는 메소드를 사용한다
// Blog가 AndroidPost에 의존하고 있다
androidPost.writePost();
}
}
class AndroidPost {
public Post writePost() {
return workbook;
}
}
"올리는 주제에 따라 기능을 다르게 하고 싶어!"
블로그에 글이 많아질수록, 포스트의 주제
에 따라 글 구성과 설정을 다르게
하고 싶어진다. 이를 관리하기 위해서, 블로그에 카테고리를 만들어 설정을 다르게 할 수 있도록 해보자.
Blog blog = new Blog();
blog.getNewPost();
// Category 인터페이스 -주제- 를 만들어 준다
interface Category{
// 카테고리마다 있어야 할 메소드들
Post writePost()
// 비공개 설정, 양식 설정 등등...
}
class Blog {
private Category category;
public Blog() {
this.category = new AndroidPost()
// 백엔드 관련 코딩 기록을 남기고 싶다면, 위 코드 대신 아래 코드를 활성화
// this.category = new ServerCoding()
}
public getNewPost() {
category.writePost();
}
}
class AndroidStudy implements Category {
public Post writePost() {
return workbook;
}
}
class ServerCoding implements Category {
public Post writePost() {
return code; // 주제에 따라 다른 Post 내용 구성을 업로드한다
}
}
코드를 계속 수정하는 것이 불편하다!
인터페이스를 통해서 기존 Blog-AndroidPost 클래스 간의 결합도를 낮추고 더 다양한 의존 관계를 맺을 수 있었지만, 아직 Blog 클래스 안에서 내부적
으로 어떤 카테고리의 글을 작성할지에 대해 직접 지정
해주고 있다. 더욱 객체 지향적으로 코드를 작성해야 하기 때문에, Blog 안의 클래스를 건드리는 것은 좋은 방법이 아니다.
Blog 객체가 생성되는 외부의 코드에서 카테고리를 지정해 주는 방법
에 대해 생각해 보자.
// 의존성 주입
// 안드로이드 스터디 내용을 작성할 것이라고 외부에서 지정해 주었다
Blog blog = new Blog(new AndroidStudy());
blog.getNewPost();
interface Category{
Post writePost()
}
class Blog {
private Category category;
// 블로그 클래스가 생성될 때, 카테고리가 지정된다
public Blog (Category category) {
this.category = category;
}
public getNewPost() {
uploadPost.writePost();
}
}
class AndroidStudy implements Category {
public Post writePost() {
return workbook();
}
}
class ServerCoding implements Category {
public Post writePost() {
return code;
}
}
DI(의존성 주입)을 진행한 모습이다. 이는 생성자를 이용하여 DI를 구현한 예시인데, Blog 클래스의 생성자에서 변수를 통해 카테고리를 지정하며 클래스 내부 코드를 굳이 이해할 필요 없이 외부에서 포스트 내용을 결정하고 주입하였다.
DI는 Spring에서 많이 사용된다. 지금까지는 단순히 DI에 대한 이해를 해 보았다면, 아래에서는 Spring을 통한 DI 예시를 살펴보며 실전 사용에 대한 파악을 해 보겠다.
@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;
}
}
@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;
}
}
Setter
라고 하는 필드의 값을 변경하는 메소드를 이용하여 의존관계를 주입한다.
잘 봤습니다. 좋은 글 감사합니다.