์๋๋๋ก๋ผ๋ฉด ์น์ 4-2๋ฅผ ์์ฑํด์ผํ์ง๋ง... 4-1์ ์ ๋ฆฌํ๊ณ velog์ ์๋ ๊ธ๋ค Tistory๋ก ๋ค์ ์ฎ๊ธฐ๋ฉด์ ๊ฐ์ ๋ด์ฉ์ด ์ ๋๋ก ๊ธฐ์ต๋์ง ์๊ฒ ๋์๋ค. ๊ทธ๋๋ keep going~ 4-2๋ 8์ ์ค์์ ๋ค์ ๋ค์ผ๋ฉด์ ์ ๋ฆฌํ๊ธฐ๋ก ํ๊ณ ์น์ 5 ๊ฐ์ ๋ถํฐ ์ ๋ฆฌํด๋ณผ๊น ํ๋ค. ํํ. ์ทจ์ ์ด ์์ ์ ์๋๋ ๊ฒ ๊ฐ์ ์ฝ๊ฐ์ ๋๋ ค์์ด ์์ง๋ง ๊ทธ๋๋ ๋ชจ๋๋ค ํ์ดํ !
๐งธ
๐งธ ๊ตฌ์กฐํ์ ๋ ์ธ ๊ผฌ์ฐ- ๐งธ
- singleton
ใด class : SingletonService, SingletonTest, StatefulService, StatefulServiceTest, ConfigurationSingletonTest - AppConfig
Q. ์คํ๋ง์ ์ฌ์ฉํ๋ ์ด์ ๋?
A. ์ฑ๊ธํค์ด ๋ณด์ฅ๋๊ธฐ ๋๋ฌธ์ด๋ค.
โ๏ธ SingletonTest
โบ pureContainer
์์ ์๋ฐ์ฝ๋๋ก ์์ฑ์๋ฅผ ์ง์ ํธ์ถํ๋ค.
MemberService memberService1 = appConfig.memberService();
MemberService memberService2 = appConfig.memberService();
AppConfig๋ฅผ ๋ณด๋ฉด MemberServiceํ์ ์ bean ์ด๋ฆ์ด memberService ๋ผ๋ ๊ฒ์ ๋ง๋ ๊ฑธ ํ์ธํ ์ ์๋ค.
appConfig.memberService๋ MemberService ํ์ ์ ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ณ ๋ฐ๋ณตํ๋ค๋ ๋ป์ด๋ค.
memberService1์ memberService๋ฅผ ๊ฐ๋ฆฌํค๋ ๊ฐ์ฒด๊ฐ ๋๋ค. (์ฐ๋ฆฌ๊ฐ ์๊ธฐ์ฝ๊ฒ ์ด๋ฆ๋ง ๋์ฌํด์ฃผ๋ ๋๋์ธ ๊ฒ ๊ฐ๋ค...(?))
๊ฒฐ๋ก ์ ์ผ๋ก memberService1์ ํตํด MemberServiced ๊ฐ์ฒด์ ์ ๊ทผํ๊ณ ์ฌ์ฉํ๋ค. ์ผ๋จ ์ด๋ ๊ฒ ์ดํดํ๊ธดํจ๐ง
ํ์ฌ ๋ง๋ AppConfig๋ ํธ์ถํ ๋ ๋ง๋ค ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ค.
๋ง์ฝ ์ฌ์ฉ์๊ฐ ๋ง์ ๊ฒฝ์ฐ, ๋ง์ ๊ฐ์ฒด ์์ฑ•์๋ฉธ๋ก ์ธํด ๋ฉ๋ชจ๋ฆฌ ๋ญ๋น๊ฐ ์ฌํด์ง๋ค.
โธ ๊ฒฐ๊ณผ
๊ฐ ๊ฐ์ด 6a472554์ 7ff2a664๋ก ๋ค๋ฅธ ๊ฒ์ ํ์ธํ ์ ์๋ค. ๊ฐ์ฒด๊ฐ ๋ค๋ฅด๊ฒ ์์ฑ๋์๋ค๋ ๊ฒ์ ์๋ฏธํ๋ค.
••• ์ด์ด์ ๋ค๋ฅธ ์ฝ๋ ๋ถ๋ถ •••
Assertions.assertThat(memberService1).isNotSameAs(memberService2);
assertThat(A).isNotSameAs(B)
: ๋์ A์ ๋์ B์ ์ฃผ์๊ฐ์ด ๋ค๋ฅธ์ง ํ์ธํ๋ ๋ฉ์๋
Q. assertThat(A).isEqualTo(B)์ assertThat(A).isSameAs(B)์ ์ฐจ์ด์ ์ ๋ฌด์์ธ๊ฐ?
A. isEqualTo๋ ๋์์ ๋ด์ฉ์ ๋น๊ตํ๊ณ isSameAs๋ ๋์์ ์ฃผ์๊ฐ์ ๋น๊ตํ๋ค.
์์) isEqualTo
String A = "Hi"; String B = "Hi"; assertThat(A).isEqualTo(B);โ
์์) isSameAs (==)String A = "Hi"; String B = A; assertThat(A).isSameAs(B);
โ๏ธ SingletonService
์ฑ๊ธํค ๋์์ธ ํจํด์ ๊ตฌํํ๋ค.
private static final SingletonService instance = new SingletonService();
private
: ๋ณ์๋ฅผ ์ธ๋ถ์์ ์ ๊ทผํ ์ ์๊ฒ ํ๋ค.
static
: instance ๋ณ์๊ฐ ํด๋์ค ์์ค์์ ๊ด๋ฆฌ๋๊ฒ ํ๋ฉฐ, ํด๋์ค๊ฐ ๋ฉ๋ชจ๋ฆฌ์ ๋ก๋๋ ๋ ์ธ์คํด์ค๊ฐ ์์ฑ๋๊ณ ํ๋ก๊ทธ๋จ ์ข ๋ฃ๋ ๋๊น์ง ์ ์ง๋๋ค.
final
: ์ธ์คํด์ค๊ฐ ํ ๋ฒ ์์ฑ๋๋ฉด ๋ณ๊ฒฝํ ์ ์๋ค.
Q. ์ฑ๊ธํค ํจํด์ static์ ์ ์ฐ๋๊ฑธ๊น?
์ ์ ์๋ฐ์์ ์ ๋ณต์์ static์ ๋ํ ๊ฐ๋ ์ ์ฐพ์๋ดค๋ ๊ฒ์ด ๊ธฐ์ต๋๋ค. ๊ทธ๋๋ main ๋ฉ์๋์ ๋ค์ด๊ฐ ์๋ ๊ฒ ๊ฐ์๋๋ฐ, ํ์ฌํผ ๊ธฐ์ต์ e๋์ง์ด๋ณด์๋ฉด static์ ์ฌ์ฉํด์ผ ๊ฐ์ฒด์ ์์ฑ ์์ด๋ ํธ์ถ์ด ๋์ด ๋ฉ๋ชจ๋ฆฌ์ ์ฌ๋ผ๊ฐ ์๋ํ ์ ์์ด์์๋ ๊ฒ ๊ฐ๋ค.(์ ํํ์ง ์์์ ๋ณต์ต์ด ํ์ํ๋ค) ๊ทธ๋ฐ๋ฐ ์ฑ๊ธํค ํจํด์๋ ์ ์ฌ์ฉํ๋์ง ์ ์ดํด๊ฐ ๊ฐ์ง ์๋๋ค.
A. static์ ์ธ์คํด์ค(๋ฉ๋ชจ๋ฆฌ ์์ ์ฌ๋ผ๊ฐ ๊ฐ์ฒด)๋ฅผ ์๋ก ์์ฑํ์ง ์์๋ ์ ๊ทผ ๊ฐ๋ฅํ๊ฒ ํ๊ธฐ์ํด ์ฌ์ฉํ๋ค. ์ฑ๊ธํค ํจํด์ ๋จ์ํ ํ๋์ ์ธ์คํด์ค๋ง ์์ฑํ๋ ๊ฒ์ด ์๋๋ค. ํ๋์ ์ธ์คํฐ์ค๋ฅผ ์์ฑ ํ ๊ณต์ ํด ์ฌ์ฉํ๋๋ก ํ๋ค. ์ฌ๊ธฐ์ static์ ํ๋์ ์ธ์คํด์ค๋ฅผ ์์ฑ๋๋๋ก ํ๋ฉฐ, ์ ์ญ์ ์ผ๋ก ๊ณต์ (์ฌ์ฉ)ํ๋๋ก ํ๊ฒ ํด์ค๋ค. private์ final์ ์ญํ ์ ์ธ๋ถ์์ ๋ณ๊ฒฝํ ์ ์๋๋ก ํด์ค๋ค.
- ์ฑ๊ธํค ํจํด๊ณผ static์ ๊ด๋ จ ์ถ์ฒ
Q. ๊ฐ์ฒด์ ์ธ์คํด์ค์ ์ฐจ์ด
A. ๊ฐ์ฒด๋ ์ ์ธ, ์ธ์คํด์ค๋ ์ค์ฒดํ๋ฅผ ์๋ฏธํ๋ค. ๊ฐ์ฒด๋ ํด๋์ค์ ํ์ ์ผ๋ก ์ ์ธ๋์์ ๋, ์ธ์คํด์ค๋ ๊ทธ ๊ฐ์ฒด๊ฐ ๋ฉ๋ชจ๋ฆฌ ์์ ์ฌ๋ ค์ก์ ๋๋ฅผ ๋งํ๋ค. ๊ทธ๋ฌ๋๊น ํน๋ณํ ๊ฐ์ฒด๋ฅผ ์ธ์คํด์ค๋ผ๊ณ ํ๋ค. (์ฉ์ด์ ์๋ฏธ๊ฐ ์กฐ๊ธ ๋ค๋ฅผ ๋ฟ, ๊ฐ์ฒด์ ์ธ์คํด์ค๋ ๊ฐ๋ค๊ณ ๋ณด๋ฉด ๋๋ ๊ฒ ๊ฐ๋ค.)
Dog myDog = new Dog(); Dog anotherDog = new Dog();
์์ ๋ ์ฝ๋์์ myDog์ anotherDog๋ Dog ํด๋์ค์ ๊ฐ์ฒด์ด์ ์ธ์คํด์ค์์ ๋ํ๋ธ๋ค. ์ฆ, ๊ฐ์ฒด์ง๋ง ์ธ์คํด์ค๊ฐ ์๋ ๊ฒฝ์ฐ๋ ์๋ค๊ณ ํ๋ค.
- ๊ฐ์ฒด์ ์ธ์คํด์ค์ ์ฐจ์ด์ ์ถ์ฒ
•••๊ทธ ๋ค์ ์ฝ๋ •••
public static SingletonService getInstance() {
return instance;
}
SingletonService์ ์ธ์คํด์ค๋ฅผ ์๋ก ๋ง๋ค์ง ์๊ณ , getInstance( ) ๋ฉ์๋๋ฅผ ํตํด ์ธ์คํด์ค๋ฅผ ์ ๊ทผํ๋ค.
๊ทธ๋ฌ๋๊น static์ผ๋ก ์ ์ญ์ ์ผ๋ก ๊ณต์ ๋ ๊ฒ์ ์ฌ์ฉํ๊ฒ ํด์ฃผ๋ ๋ฉ์๋๊ฐ getInstance( )์ธ ๋ฏ ํ๋ค.
private SingletonService() {
}
์์ฑ์
: ์ธ์คํด์ค๋ฅผ ๋ง๋ค ๋ ํธ์ถ๋๋ ํน๋ณํ ๋ฉ์๋
Q. ์์ฑ์๊ฐ ์ ํํ๊ฒ ๋ฌด์์ธ๊ฐ?
A. ๊ฐ์ฒด๊ฐ ์์ฑ๋ ๋ ์๋์ผ๋ก ํธ์ถ๋๋ ํน์ ๋ชฉ์ ์ ๋ฉค๋ฒํจ์(๋ฉ์๋)๋ก ๊ฐ์ฒด์ ์ด๊ธฐํ๋ฅผ ์ํด ์ฌ์ฉํ๋ค. ๋ฌด์กฐ๊ฑด ํด๋์ค๋น ํ๋๊ฐ ์์ด์ผํ๋ฉฐ, ๊ฐ์ฒด๊ฐ ์์ฑ๋๋๋ฐ ๊ทธ์ ๋ง๋ ์์ฑ์๊ฐ ์์ ๊ฒฝ์ฐ ์ปดํ์ผ๋ฌ๊ฐ ์๋์ผ๋ก ๊ธฐ๋ณธ์์ฑ์๋ฅผ ์์ฑํ๊ฑฐ๋ ์ค๋ฅ๊ฐ ๋ฐ์ํ ์ ์๋ค.
public Book() { } // ๊ธฐ๋ณธ์์ฑ์ public Book(String title, int price) { // ๋งค๊ฐ๋ณ์๋ฅผ ๊ฐ์ง ์์ฑ์ this.title = title; this.price = price; }
Book b1 = new Book(); // ๊ฐ์ฒด์์ฑ - ๊ธฐ๋ณธ์์ฑ์ ํธ์ถ๋จ Book b2 = new Book("๊ตญ์ด์ฑ ", 3000); // ๊ฐ์ฒด์์ฑ - ๋งค๊ฐ๋ณ์๋ฅผ ๊ฐ์ง ์์ฑ์ ํธ์ถ๋จ
- ์์ฑ์์ ๋ํ ์ค๋ช ์ถ์ฒ
Q. ๊ทธ๋ ๋ค๋ฉด ์์ ์์ฑ์๋ ๊ธฐ๋ณธ ์์ฑ์์ธ๊ฐ? ์ ์ฐ๋๊ฑธ๊น?
A. ์์ ์์ฑ์๋ ๊ธฐ๋ณธ์์ฑ์์ ์ฐจ์ด๊ฐ ์๋ค. ์ผ๋จ ๊ธฐ๋ณธ ์์ฑ์๋ public์ ๊ธฐ๋ฐ์ผ๋ก ํ๋๋ฐ, ์์ ์ฝ๋๋ private๋ก ๊ฐ๋ฐ์๊ฐ ์ ์ํ ๋ช ์์ ์์ฑ์(๋งค๊ฐ๋ณ์๊ฐ ์๋)๋ค. private๋ฅผ ์ฌ์ฉํ ์ด์ ๋ ์ฑ๊ธํค ํจํด์ ๋ง๋ค๊ธฐ ์ํด ์ธ๋ถ์์ ์ธ์คํด์ค๋ฅผ ๋ง๋ค ์ ์๋๋ก ํ๊ธฐ ์ํจ์ด๋ค.
••• ์ฐ๊ฒฐ๋ ํ ์คํธ ์ฝ๋ ํ์ธํ๊ธฐ •••
โ๏ธ SingletonTest
โบ singletonServiceTest
SingletonService singletonService1 = SingletonService.getInstance();
SingletonService singletonService2 = SingletonService.getInstance();
SingletonService์ ์ฝ๋๋ฅผ ์๊ฐํด๋ณด๋ฉด ์ธ์คํด์ค๋ฅผ ์ธ๋ถ์์ ๋ง๋ค์ง ๋ชปํ๋๋ก private ์์ฑ์๋ฅผ ๋ง๋ค์๋ค. ๊ทธ๋ฆฌ๊ณ static, final, private๋ก ์ธ์คํด์ค ๋ณ๊ฒฝ์ ๋ถ๊ฐํ๊ฒ ๋ง๋ค์๋ค. ๊ทธ๋ฐ๋ฐ ์ ์ญ์ ์ผ๋ก ๊ณต์ ๋ฅผ ํ๊ธฐ ์ํด getInstance ๋ฉ์๋๋ฅผ ๋ง๋ค์๋ค.
getInstance( )๋ฅผ ํตํด ์ ๊ทผํ์ฌ singletonService1๊ณผ singletonService2์ ์ธ์คํด์ค๋ฅผ ๋ฐํ๋ฐ๋ ๊ฒ์ด๋ค. ์์ฑ์๋ฅผ ์ง์ ํธ์ถํ์ง ์๊ณ ํด๋์ค ๋ด์์ ๊ด๋ฆฌํ๋ ์ ์ผํ ์ธ์คํด์ค๋ฅผ ๋ฐํํ๋ ์ ์ ๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด๋ค.
โ๏ธ SingletonTest
โบ springContainer
์ฑ๊ธํค ํจํด์ ์ฌ์ฉํ๋ฉด DIP,OCP๋ฅผ ์๋ฐํ ์ ์๋ค. ๋๊ตฌ๋ private ์ฌ์ฉ์ผ๋ก ์ธํด ์ ์ฐ์ฑ๋ ๋จ์ด์ง๋ค.
๊ทธ๋ ๊ธฐ์ ์คํ๋ง ์ปจํ ์ด๋๋ฅผ ์ฌ์ฉํ์ฌ ์ธ์คํด์ค๋ฅผ ์ฑ๊ธํค์ผ๋ก ์ ์งํ๋ ๋ฐฉ์์ ์ฌ์ฉํ ๊ฒ์ด๋ค.
MemberService memberService1 = ac.getBean("memberService", MemberService.class);
MemberService memberService2 = ac.getBean("memberService", MemberService.class);
AppConfig์ ์ ์๋์ด์๋ memberService๋ผ๋ ์ด๋ฆ์ ๊ฐ์ง ๋น์ MemberService ํ์ ์ผ๋ก ๋ฐํํ๋ค. ์ด๋ ์คํ๋ง ์ปจํ ์ด๋์ ํน์ฑ์ ์ํด ๊ฐ์ ๋น ์ธ์คํด์ค๋ฅผ ํ ๋นํ๋ค.
๊ฐ์ ๊ฒฐ๊ณผ๊ฐ์ด ๋์จ ๊ฒ์ ํ์ธํ ์ ์๋ค.
โ๏ธ StatefulService
์คํ๋ง ์ปจํ ์ด๋๋ ๋ฌด์ํ๋ก ์ค๊ณํด์ผํ๋ค.
๐๏ธ๐จ๏ธ ๋ฌธ์ ์
์คํ๋ง์ปจํ ์ด๋ ํน์ ์ฑ๊ธํค ํจํด์ ํ๋์ ์ธ์คํด์ค๋ฅผ ๊ฐ์ ธ์ ๊ณต์ ํ๊ฒ ๋๋ค.
๋ง์ผ ์ํ๋ฅผ ๊ฐ์ง๋ ํ๋๊ฐ ์๋ค๋ฉด, ์ฒ๋ฆฌ์ ๋ฌธ์ ๊ฐ ์๊ธฐ๊ฒ ๋๋ค.
private int price;
public void order(String name, int price) {
...
this.price = price;
}
์ฒซ๋ฒ์งธ ์ฃผ๋ฌธ์๊ฐ 2๋ง์์ ์ฃผ๋ฌธํ๋๋ฐ ๊ทธ๊ฒ์ ์ฒ๋ฆฌํ๋ ๋์ ๋๋ฒ์งธ ์ฃผ๋ฌธ์ด 10๋ง์ ๋ค์ด์ค๊ฒ ๋๋ฉด,
์ฒซ๋ฒ์งธ ์ฃผ๋ฌธ์์ ์ฃผ๋ฌธ๊ฐ๊ฒฉ์ด 10๋ง์์ผ๋ก ๋ณ๊ฒฝ๋ ์ ์๋ค.
๐ซ ํด๊ฒฐํด๋ณด์
public int order(String name, int price) {
...
return price;
}
1. ๋ฌด์ํ๋ก ๋ง๋ค๊ธฐ ์ํด ์๋ ์๋ this.price = price;๋ฅผ ์ง์์ค๋ค.
2. ๋ฆฌํด๊ฐ์ ๋ค์ด์๋ ๊ฐ๊ฒฉ์ผ๋ก ๋๊ฐ๋๋ก return price;๋ก ์์ ํ๋ค.
โ๏ธ StatefulServiceTest
โบ TestConfig
@Bean
public StatefulService statefulService() {
return new StatefulService();
}
@Bean์ ์จ์ ๊ฐ๋จํ ์ค์ ํด๋์ค๋ฅผ ๋ง๋ค์๋ค.
StatefulService statefulService1 = ac.getBean(StatefulService.class);
StatefulService statefulService2 = ac.getBean(StatefulService.class);
statefulService1๊ณผ statefulService2์ ์ธ์คํด์ค๋ฅผ ์๊ตฌํ๋ค.
๊ทธ๋ฌ๋ฉด TestConfig์ ์๋ StatefulService๋ก ๊ฐ์ ์ธ์คํด์ค๋ฅผ ์์ฑํ๊ณ ๋ฐํํ๋ค.
int userAprice = statefulService1.order("A", 2000);
int userBprice = statefulService2.order("B", 1000);
StatefulService์ order ๋ฉ์๋๋ฅผ ํธ์ถํ๋ค.
์์๋๋ก ๋ด๋ถ์ํํ๋ price์ ๊ฐ ๊ฐ์ ์ ์ฅํ๊ณ ์ด ๊ฐ์ ๋ฐํํ๋ค.
๐ท
๊ฒฐ๋ก ์ ์ผ๋ก AppConfig์ ๋ถ์ด์๋ @Configuration๊ณผ @Bean์ ํตํด ๊ฐ ์ธ์คํด์ค์ ์ฑ๊ธํค์ ๋ณด์ฅํด์ค๋ค.
๋ง์ผ @Configuration์ด ์๋ค๋ฉด AppConfig์ memberRepository๋ ๋ค๋ฅธ ์ธ์คํด์ค๋ฅผ ๊ฐ์ ธ ํธ์ถ๋ ๊ฒ์ด๋ค.
๊ทธ๋ฆฌ๊ณ ์ฃผ์ํด์ผํ ๊ฒ์ ๋ฌด์(stateless)๋ฅผ ์ ์งํ๋ ๊ฒ์ด๋ค.