๐ ๊ธ๋ 6๊ธฐ ํฌ์คํ
1. ๋ฏธ์น๋๋ก ๋์ ๋ 7์์ ํ๊ณ
2. ์ฌ์ฉ์๊ฐ ๊ฒ์๋ฌผ์ ์์ฑํ ๋์ ํธ๋์ญ์ ์ฒ๋ฆฌ
3. Spring AOP - (1) ํ๋ก์ ํจํด, ๋ฐ์ฝ๋ ์ดํฐ ํจํด
4. [MySQL] - ํธ๋์ญ์ ์ ๊ฒฉ๋ฆฌ ์์ค(Isolation level)
5. Spring AOP - (2) AOP ๊ฐ๋ ๋ฐ ์ค์ต
6. ์ธํ ๋ฆฌ์ ์ด(IntelliJ) - ๋๋ฒ๊น (Debugging) ํ๊ธฐ
7. [Java, ๋์์ธํจํด] - ์ฑ๊ธํด ํจํด(Singleton Pattern)
8. ์๊ฐ ์ฝ๋๋ฆฌ๋ทฐ Ver_0.1: ์ปค๋ฆฌ์ด ์ฑ์ฅ CODE ์ธ๋ฏธ๋ ์ ๋ฆฌ
9. ํฌ์คํธ๋งจ(API ํ ์คํธ) ํ์ฉํ๊ธฐ
๐ Spring AOP(Aspect Oriented Programming)
ํฌ์คํ ์ ์์ฑํ ์์ ์ฝ๋๋ ๊นํ๋ธ์์ ํ์ธํ์ค ์ ์์ต๋๋ค :)
์๋ ํ์ธ์, ์ด๋ฒ ์๊ฐ์ ์ ๋ฆฌํ ๋ด์ฉ์ ์คํ๋ง AOP(Aspect Oriented Programming) ์ ๋๋ค.
์ต๊ทผ ๋ช๋ช ๋ฉด์ ์์ AOP์ ๋ํด ์ง๋ฌธ์ ๋ฐ์์ ์ด ์์๊ณ , ์ค์ ์ ์ฉ์ ํด๋ณด๊ฑฐ๋ ์ ํํ๊ฒ ์ดํด๋ฅผ ํ๊ณ ์๋ ์ํ๋ ์๋์๊ธฐ ๋๋ฌธ์ ์ด๋ฒ ๊ธฐํ์ ํ์คํ๊ฒ ์ดํด๋ฅผ ํ๊ธฐ ์ํด ํฌ์คํ ์ ์์ฑํ๊ฒ ๋์์ต๋๋ค. ๐
๋จผ์ ํฌ์คํ ์ ๋ชฉ์ ์ธ ์คํ๋ง AOP์ ๋ํด ์์๋ณด๊ธฐ ์ ์ ๋ถ๊ฐ ๊ธฐ๋ฅ์ ์์ํ๋ ์ ํต์ ์ธ ๋ฐฉ๋ฒ์ผ๋ก ํ๋ก์์ ๋ฐ์ฝ๋ ์ดํฐ์ ๋ํด
์ ๋ฆฌ๋ฅผ ํ ํ ์คํ๋ง AOP์ ๋ํด ์์๋ณด๊ฒ ์ต๋๋ค.
ํฌ์คํ ์ ๋ชฉ์ฐจ ์ ๋๋ค.
- ๋ถ๊ฐ ๊ธฐ๋ฅ์ ์์ํ๋ ์ ํต์ ์ธ ๋ฐฉ๋ฒ 1 - ํ๋ก์ ํจํด
- ๋ถ๊ฐ ๊ธฐ๋ฅ์ ์์ํ๋ ์ ํต์ ์ธ ๋ฐฉ๋ฒ 2 - ๋ฐ์ฝ๋ ์ดํฐ ํจํด
Spring AOP ๊ฐ๋ Spring AOP ํน์งSpring AOP ์ฉ์ดSpring AOP ์ค์ต 1Spring AOP ์ด๋ ธํ ์ด์ Spring AOP ์ค์ต 2๋ง๋ฌด๋ฆฌ
์ด๋ฒ ํฌ์คํ ์์๋ ๋ถ๊ฐ ๊ธฐ๋ฅ์ ์์ํ๋ ์ ํต์ ์ธ ๋ฐฉ๋ฒ - ํ๋ก์ ํจํด, ๋ฐ์ฝ๋ ์ดํฐ ํจํด์ ๋ํด ์์๋ณด๊ฒ ์ต๋๋ค :)
๐ฏ ๋ถ๊ฐ ๊ธฐ๋ฅ์ ์์ํ๋ ์ ํต์ ์ธ ๋ฐฉ๋ฒ 1 - ํ๋ก์ ํจํด
ํ๋ก์(Proxy)
- ์ปดํจํฐ ํ๋ก๊ทธ๋๋ฐ์์ ์ํํธ์จ์ด ๋์์ธ ํจํด์ ํ๋
- ๋ค๋ฅธ ๋ฌด์ธ๊ฐ์ ์ด์ด์ง๋ ์ธํฐํ์ด์ค ์ญํ ์ ํ๋ ํด๋์ค
- ์ด๋ค ๊ฐ์ฒด์ ๋ํ ์ ๊ทผ์ ์ ์ดํ๋ ์ฉ๋๋ก ๋๋ฆฌ์ธ์ด๋ ๋๋ณ์ธ์ ํด๋นํ๋ ๊ฐ์ฒด๋ฅผ ์ ๊ณตํ๋ ํจํด
- ํ๋ก์์ ๋ฆฌ์ผ ์๋ธ์ ํธ๊ฐ ๊ณต์ ํ๋ ์ธํฐํ์ด์ค(Subject)๊ฐ ์กด์ฌํ๊ณ , ํด๋ผ์ด์ธํธ๋ ์ธํฐํ์ด์ค ํ์ ์ผ๋ก ํ๋ก์๋ฅผ ์ฌ์ฉํฉ๋๋ค.
- ํด๋ผ์ด์ธํธ๋ ํ๋ก์๋ฅผ ๊ฑฐ์ณ ๋ฆฌ์ผ ์๋ธ์ ํธ๋ฅผ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ ํ๋ก์๋ ๋ฆฌ์ผ ์๋ธ์ ํธ์ ๋ํ ์ ๊ทผ ๊ด๋ฆฌ, ๋ถ๊ฐ๊ธฐ๋ฅ ์ ๊ณต, ๋ฆฌํด๊ฐ ๋ณ๊ฒฝ ๋ฑ์ ์ํํ ์ ์์ต๋๋ค.
- ๋ฆฌ์ผ ์๋ธ์ ํธ๋ ์์ ์ด ํด์ผ ํ ์ผ(ํต์ฌ ๊ธฐ๋ฅ)๋ง ์ํํ๋ฉด์ ํ๋ก์๋ฅผ ์ฌ์ฉํด ๋ถ๊ฐ๊ธฐ๋ฅ(๋ก๊น , ํธ๋์ญ์ ๋ฑ)์ ์ ๊ณตํ๊ณ ์ ํ ๋ ์ด์ ๊ฐ์ ํ๋ก์ ํจํด์ ์ฃผ๋ก ์ฌ์ฉํฉ๋๋ค.
- ํด๋ผ์ด์ธํธ๋ ํ๋ก์(๋๋ฆฌ์ธ, ๋น์)๋ฅผ ๊ฑฐ์ณ์ ๋ฆฌ์ผ ์๋ธ์ ํธ๋ฅผ ์ฌ์ฉํ๊ฒ ๋ฉ๋๋ค.
ํ๋ก์ ํจํด์ ์ดํด๋ฅผ ์ํด ๋ก๊ทธ์ธ์ ํ๋ ๊ธฐ๋ฅ์ ๋ํด ๊ณ ๋ คํด๋ณด๊ฒ ์ต๋๋ค.
์ ์ํฉ์์ login() ๋ฉ์๋์๋ ๋ก๊ทธ์ธ ๊ธฐ๋ฅ์ ๋ํ๋ด๋ ํต์ฌ ๊ธฐ๋ฅ๊ณผ ๋ก๊น , ํธ๋์ญ์ ๋ฑ๊ณผ ๊ฐ์ ๋ถ๊ฐ ๊ธฐ๋ฅ์ ๋ชจ๋ ์ํํ๊ฒ ๋ฉ๋๋ค.
ํ๋์ ๋ฉ์๋์์ ์ฌ๋ฌ ๊ฐ์ง ๊ธฐ๋ฅ์ ์ํํ๋ค๋ณด๋ ์์ง๋๋ ๋ฎ์์ง๊ฒ ๋๊ณ ํ ์คํธ ์ฝ๋๋ฅผ ์์ฑํ๋๋ผ๋ ํต์ฌ ๊ธฐ๋ฅ ๋ฟ๋ง ์๋๋ผ ๋ถ๊ฐ ๊ธฐ๋ฅ๋ ํ ์คํธ๋ฅผ ํด์ผ ํ๊ธฐ ๋๋ฌธ์ ์ข์ง ์์ ์ฝ๋๊ฐ ๋ ๊ฐ๋ฅ์ฑ์ด ๋์์ง๊ฒ ๋ฉ๋๋ค.
ํต์ฌ ๊ธฐ๋ฅ๊ณผ ๋๋ถ์ด ๋ถ๊ฐ ๊ธฐ๋ฅ๋ ํฌํจ๋๋ค๋ฉด ์ฌ๋ฌ ํจํค์ง์ ์์กดํ๊ณ ์์ ํ๋ฅ ์ด ๋๊ธฐ ๋๋ฌธ์ ์์กด์ฑ๋ํ ๋์์ง๊ฒ ๋๊ณ ,
์ด๋ฌํ ์์กด์ฑ์ด ๋์ ์ฝ๋๋ ๋ฆฌํฉํ ๋ง์ ํ๊ธฐ๊ฐ ์ด๋ ต๊ณ , ๋ณํ์ ๋ฏผ์ฒฉํ๊ฒ ๋์ํ๊ธฐ๊ฐ ์ด๋ ค์ธ ์ ์์ต๋๋ค.
๋ํ ๊ฐ์ฒด์งํฅ ์ค๊ณ์์น(SOLID) ์ค ํ๋์ธ ๋จ์ผ์ฑ ์์์น(Single Responsibility Principle)์๋ ์ด๊ธ๋๊ฒ ๋ฉ๋๋ค.
๋ฐ๋ผ์ ์์ ๊ฐ์ ์ํฉ์ ํ๋ก์ ํจํด์ ํตํด ๋ค์๊ณผ ๊ฐ์ด ๊ฐ์ ํ ์ ์์ต๋๋ค.
์์ ๊ตฌ์กฐ์์ ํด๋ผ์ด์ธํธ์ ์ ์ฅ์์๋ ๋ก๊ทธ์ธ ๊ธฐ๋ฅ์ ์ฌ์ฉํ๋ ๊ฒ๊ณผ ์๋ฌด๋ฐ ์ฐจ์ด์ ์ด ์กด์ฌํ์ง ์์ต๋๋ค.
ํด๋ผ์ด์ธํธ๊ฐ ๋ก๊ทธ์ธ ๊ธฐ๋ฅ์ ์ํํ๋ฉด ํ๋ก์ ํจํด์ ์ํด ๋ถ๊ฐ ๊ธฐ๋ฅ์ด ์ํ๋๊ณ , ํต์ฌ ๊ธฐ๋ฅ์ด ์ํ๋๊ธฐ ๋๋ฌธ์ ๊ฒฐ๊ณผ๋ ๋์ผํฉ๋๋ค.
ํ๋ก์ ํจํด ์์
@Getter
@Setter
public class Book {
private String title;
}
/* ์๋ธ์ ํธ ์ญํ */
public interface BookService {
void rent(Book book);
}
/* ํ๋ก์ */
public class BookServiceProxy implements BookService {
// ํ๋ก์๋ ๋ฆฌ์ผ ์๋ธ์ ํธ๋ฅผ ๊ฐ์ง๊ณ ์์ด์ผ ํจ(delegate ->)
private final RealBookService realBookService;
public BookServiceProxy(RealBookService realBookService) {
this.realBookService = realBookService;
}
// ํ๋ก์์์ ๋ถ๊ฐ๊ธฐ๋ฅ์ ์ถ๊ฐ
@Override
public void rent(Book book) {
System.out.println("ํธ๋์ญ์
์ฒ๋ฆฌ");
realBookService.rent(book); // ํ๋ก์ -> ๋ฆฌ์ผ ์๋ธ์ ํธ
System.out.println("๋ก๊น
");
}
}
/* ๋ฆฌ์ผ ์๋ธ์ ํธ ์ญํ */
@Service
public class RealBookService implements BookService {
/*
rent(): ์ฑ
์ ๋น๋ฆฌ๋(ํต์ฌ ๊ธฐ๋ฅ) ๋ฉ์๋
์ฑ
์ ๋น๋ฆฌ๊ธฐ ์ ํ ํธ๋์ญ์
& ๋ก๊น
(๋ถ๊ฐ ๊ธฐ๋ฅ) ์ถ๊ฐ
*/
public void rent(Book book) {
System.out.println("rent: " + book.getTitle());
}
}
/* ํด๋ผ์ด์ธํธ */
public class Client {
public static void main(String[] args) {
BookService bookService = new BookServiceProxy(new RealBookService());
bookService.rent(new Book());
}
}
ํธ๋์ญ์
์ฒ๋ฆฌ
rent: null
๋ก๊น
์ ์ฝ๋์ ์๋ ๊ทธ๋ฆผ์ ๋น๊ตํด๊ฐ๋ฉฐ ํ์ธํ์๋ฉด ์ดํดํ๊ธฐ๊ฐ ๋ ์์ํฉ๋๋ค :)
์ ์์ ์ฝ๋์์ ๊ฐ ํด๋์ค๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
- Client = Client
- BookService = Subject
- BookServiceProxy = Proxy
- RealBookService = RealSubject
๋ฐ๋ผ์ ํ๋ก์์ ์ญํ ์ ํ๋ BookServiceProxy๋ ๋ฆฌ์ผ ์๋ธ์ ํธ์ธ RealBookService ๊ฐ์ฒด๋ฅผ ๊ฐ์ง๊ณ ์์ต๋๋ค.
์ด๋ฅผ ํตํด ํ๋ก์๋ ๋ถ๊ฐ ๊ธฐ๋ฅ๋ ์ํํ๋ฉฐ ํต์ฌ ๊ธฐ๋ฅ์ธ ์ฑ ์ ๋น๋ฆฌ๋ ๊ธฐ๋ฅ๋ ์ํํ ์ ์์ต๋๋ค.
ํ๋ก์ ๋ถ๋ถ์ ์ฝ๋๋ง ๋ค์ ์ดํด๋ณด๋ฉด ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
/* ํ๋ก์ */
public class BookServiceProxy implements BookService {
// ํ๋ก์๋ ๋ฆฌ์ผ ์๋ธ์ ํธ๋ฅผ ๊ฐ์ง๊ณ ์์ด์ผ ํจ(delegate ->)
private final RealBookService realBookService;
public BookServiceProxy(RealBookService realBookService) {
this.realBookService = realBookService;
}
// ํ๋ก์์์ ๋ถ๊ฐ๊ธฐ๋ฅ์ ์ถ๊ฐ
@Override
public void rent(Book book) {
System.out.println("ํธ๋์ญ์
์ฒ๋ฆฌ");
realBookService.rent(book); // ํ๋ก์ -> ๋ฆฌ์ผ ์๋ธ์ ํธ
System.out.println("๋ก๊น
");
}
}
๐ฏ ๋ถ๊ฐ ๊ธฐ๋ฅ์ ์์ํ๋ ์ ํต์ ์ธ ๋ฐฉ๋ฒ 2 - ๋ฐ์ฝ๋ ์ดํฐ ํจํด
๋ฐ์ฝ๋ ์ดํฐ ํจํด์ ์ค๋ช ํ๊ธฐ ์ ์ ์ ํ์ํ์ง ์์์ ํตํ ํ์ฅ๊ณผ ํจ๊ป ์ดํด๋ณด๊ฒ ์ต๋๋ค.
๋ด๋น๊ฒ์ด์ SW์์ ๋๋ก๋ฅผ ํ์ํ๋ ๊ธฐ๋ฅ์ ๋ํด ์๊ฐํด๋ณด๊ฒ ์ต๋๋ค.
๊ธฐ๋ณธ์ ์ธ ๊ธฐ๋ฅ์ ๋๋ก๋ฅผ ๊ฐ๋จํ ์ ์ผ๋ก ํ์ํ๋ ๊ฒ์ด๊ณ , ๋ด๋น๊ฒ์ด์ ์ ๋ฐ๋ผ ๋๋ก์ ์ฐจ์ ์ ํ์ํ๋ ๊ธฐ๋ฅ์
(์ถ๊ฐ์ ์ผ๋ก) ์ ๊ณตํ ์ ์์ต๋๋ค.
์ด๋ฌํ ์ํฉ์์ ๋๋ก๋ฅผ ํ์ํ๋ ๊ธฐ๋ฅ์ ํด๋์ค๋ฅผ ๋ค์๊ณผ ๊ฐ์ด ๋ํ๋ด๋ณด๊ฒ ์ต๋๋ค.
- RoadDisplay ํด๋์ค: ๊ธฐ๋ณธ ๋๋ก ํ์ ๊ธฐ๋ฅ์ ์ ๊ณต
- RoadDisplayWithLane ํด๋์ค: ์ถ๊ฐ์ ์ผ๋ก ์ฐจ์ ์ ํ์ํ๋ ๊ธฐ๋ฅ์ ์ ๊ณต
public class RoadDisplay { // ๊ธฐ๋ณธ ๋๋ก ํ์ ๊ธฐ๋ฅ
public void draw() {
System.out.println("๊ธฐ๋ณธ ๋๋ก ํ์");
}
}
public class RoadDisplayWithLane extends RoadDisplay { // ๊ธฐ๋ณธ ๋๋ก ํ์ + ์ฐจ์ ํ์
@Override
public void draw() {
super.draw(); // ์์ ํด๋์ค(๊ธฐ๋ณธ ๋๋ก ํ์)
drawLine(); // ์ถ๊ฐ์ ์ผ๋ก ์ฐจ์ ํ์
}
private void drawLine() {
System.out.println("์ฐจ์ ํ์");
}
}
public class Client {
public static void main(String[] args) {
RoadDisplay road = new RoadDisplay();
road.draw(); // ๊ธฐ๋ณธ ๋๋ก๋ง ํ์
RoadDisplay roadWithLane = new RoadDisplayWithLane();
roadWithLane.draw(); // ๊ธฐ๋ณธ ๋๋ก + ์ฐจ์ ํ์
}
}
๊ธฐ๋ณธ ๋๋ก ํ์
๊ธฐ๋ณธ ๋๋ก ํ์
์ฐจ์ ํ์
RoadDisplay ํด๋์ค๋ ๊ธฐ๋ณธ ๋๋ก ํ์ ๊ธฐ๋ฅ์ ์ํ draw() ๋ฉ์๋๋ฅผ ๊ตฌํํฉ๋๋ค.
RoadDisplayWithLane ํด๋์ค๋ ๊ธฐ๋ณธ ๋๋ก + ์ฐจ์ ํ์๋ฅผ ์ํด ์์๋ฐ์ draw() ๋ฉ์๋๋ฅผ ์ค๋ฒ๋ผ์ด๋ ํฉ๋๋ค.
๋ฌธ์ ์
- ์ฐจ์ ํ์๊ฐ ์๋ ๋ ๋ค๋ฅธ ๊ธฐ๋ฅ์ ์ถ๊ฐ๋ก ๊ตฌํํ๊ณ ์ถ๋ค๋ฉด ์ด๋ป๊ฒ ํด์ผํ ๊น์? ex) ๊ธฐ๋ณธ ๋๋ก ํ์ + ๊ตํต๋ ํ์
- ๋ค์ํ ์ถ๊ฐ ๊ธฐ๋ฅ์ ์กฐํฉํด ์ ๊ณตํ๊ณ ์ถ๋ค๋ฉด ์ด๋ป๊ฒ ํด์ผ ํ ๊น์? ex) ๊ธฐ๋ณธ ๋๋ก ํ์ + ์ฐจ์ ํ์ + ๊ตํต๋ ํ์
์ ๋ฌธ์ ์ ์ ํด๊ฒฐํ๊ธฐ ์ํด RoadDisplay ํด๋์ค๋ฅผ ์์๋ฐ์ ๊ตํต๋์ ํ์ํ๋ RoadDisplayWithTraffic ํด๋์ค๋ฅผ ๋ง๋ค์ด๋ณด๊ฒ ์ต๋๋ค.
RoadDisplayWithTraffic ํด๋์ค๋ฅผ ์์ฑํ๊ณ ๋ ํ์ ํด๋์ค ๋ค์ด์ด๊ทธ๋จ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
// ๊ธฐ๋ณธ ๋๋ก ํ์ + ๊ตํต๋ ํ์
public class RoadDisplayWithTraffic extends RoadDisplay {
@Override
public void draw() {
super.draw(); // ์์ ํด๋์ค(๊ธฐ๋ณธ ๋๋ก ํ์)
drawTraffic(); // ๊ตํต๋ ํ์
}
private void drawTraffic() {
System.out.println("๊ตํต๋ ํ์");
}
}
RoadDisplay ํด๋์ค์ ํ์ ํด๋์ค๋ก ๋๋ก ํ์์ ์ถ๊ฐ์ ์ธ ๊ธฐ๋ฅ(์ฐจ์ ํ์, ๊ตํต๋ ํ์ ๋ฑ)์ ์ ๊ณตํ๋ ๊ฒ์ ์ ์ ํ ์ค๊ณ ๋ฐฉ๋ฒ์ด ๋ ์ ์์ต๋๋ค. ๊ทธ๋ฌ๋ ๋ค์ํ ๊ธฐ๋ฅ์ ์กฐํฉ์ ๊ณ ๋ คํด์ผ ํ๋ ๊ฒฝ์ฐ ์์์ ํตํ ํ์ฅ์ ๊ฐ ๊ธฐ๋ฅ๋ณ ํด๋์ค๋ฅผ ์ถ๊ฐํด์ผ ํ๋ค๋ ๋จ์ ์ด ์กด์ฌํฉ๋๋ค.
์๋ฅผ ๋ค์ด ๋๋ก ํ์๋ฅผ ํ๋ ๊ธฐ๋ณธ ๊ธฐ๋ฅ์ ์ถ๊ฐ๋ก ์ ๊ณตํ ์ ์๋ ๊ธฐ๋ฅ์ผ๋ก ์ฐจ์ ํ์, ๊ตํต๋ ํ์, ๊ต์ฐจ๋ก ํ์๋ฅผ 3๊ฐ์ง์ ์ถ๊ฐ ๊ธฐ๋ฅ์ด ์กด์ฌํ๋ค๊ณ ํ์๋, ์กฐํฉํ ์ ์๋ ๊ฒฝ์ฐ์ ์๋ ๋ค์๊ณผ ๊ฐ์ด ์ด 8๊ฐ์ง์ ์กฐํฉ์ด ๊ฐ๋ฅํฉ๋๋ค.
๊ฒฝ์ฐ | ๊ธฐ๋ณธ ๊ธฐ๋ฅ (๋๋ก ํ์) |
์ถ๊ฐ ๊ธฐ๋ฅ | ํด๋์ค ์ด๋ฆ | ||
์ฐจ์ ํ์ | ๊ตํต๋ ํ์ | ๊ต์ฐจ๋ก ํ์ | |||
1 | O | RoadDisplay | |||
2 | O | O | RoadDisplayWithLane | ||
3 | O | O | RoadDisplayWithTraffic | ||
4 | O | O | RoadDisplayWithCrossing | ||
5 | O | O | O | RoadDisplayWithLaneTraffic | |
6 | O | O | O | RoadDisplayWithLaneCrossing | |
7 | O | O | O | RoadDisplayWithTrafficCrossing | |
8 | O | O | O | O | RoadDisplayWithLaneTrafficCrossing |
์ ํ์ ๊ฐ์ด ๊ฐ ์กฐํฉ๋ณ๋ก RoadDisplay ํด๋์ค๋ฅผ ์์๋ฐ๋ 7๊ฐ์ ํ์ ํด๋์ค๋ฅผ ์ถ๊ฐํด์ผ ํฉ๋๋ค.
๋ ํ์ฅํด์ ์ถ๊ฐ ๊ธฐ๋ฅ์ด n๊ฐ๋ผ๋ฉด (2^n - 1)๊ฐ์ ํ์ ํด๋์ค๋ฅผ ์ถ๊ฐํด์ผ ํ๋ ์์ฒญ๋ ์์ ์ ํด์ผํฉ๋๋ค.
์ด์ ๊ฐ์ด ์์์ ์ด์ฉํ ๊ธฐ๋ฅ ์ถ๊ฐ ๋ฐฉ๋ฒ์ ํตํด ํด๊ฒฐํ ์ ์์ง๋ง, ์ถ๊ฐ๋๋ ๊ธฐ๋ฅ์ ์กฐํฉ๋ณ๋ก ํ์ ํด๋์ค๋ฅผ ๊ตฌํํด์ผ ํ๋ ๋ฌธ์ ์ ์ด ์์ต๋๋ค. ์ด๋ ๊ฒ ์กฐํฉ ์๊ฐ ๋์ด๋๋ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์๋ ์ค๊ณ๋ฅผ ํ๊ธฐ ์ํด์๋ ๊ฐ ์ถ๊ฐ ๊ธฐ๋ฅ๋ณ๋ก ๊ฐ๋ณ์ ์ธ ํด๋์ค๋ฅผ ์ค๊ณํ๊ณ , ๊ธฐ๋ฅ์ ์กฐํฉํ ๋ ๊ฐ ํด๋์ค์ ๊ฐ์ฒด ์กฐํฉ์ ์ด์ฉํจ์ผ๋ก์จ ํด๊ฒฐํ ์ ์์ต๋๋ค.
๋ฐ์ฝ๋ ์ดํฐ ํจํด์ ํตํด ์ ๋ฌธ์ ์ ์ ํด๊ฒฐํด๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค.
โป ์ถ๊ฐ ๊ธฐ๋ฅ์ ํ์ฅํ ์ผ์ด ์๋ค๋ ๊ฐ์ ํ์ ์์์ผ๋ก ์ค๊ณ๋ฅผ ํ๋๋ผ๋, ์ค์ ์ํํธ์จ์ด ๊ฐ๋ฐ์ ์ด๋ป๊ฒ ๋ ์ง ๋ชจ๋ฅด๋ ์ผ์ด๊ธฐ์ ์ฒ์๋ถํฐ ์ค๊ณ๋ฅผ ์ ๋๋ก ํ๋ค๋ฉด ์ด๋ฌํ ์์ ํ์ฅ์ ๋ฌธ์ ๋ฅผ ๋ ๊ฐ๋จํ๊ฒ ํด๊ฒฐํ ์ ์์ต๋๋ค.
์์ ๋ฐฉ์์ ์ถ๊ฐ ๊ธฐ๋ฅ ๋ฌธ์ ์ ํด๊ฒฐ(๋ฐ์ฝ๋ ์ดํฐ ํจํด)
๊ธฐ๋ณธ ๊ธฐ๋ฅ(๊ธฐ๋ณธ ๋๋ก ํ์)๋ง ์ด์ฉํ ๋๋ RoadDisplay ํด๋์ค์ ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ฉด ์ถฉ๋ถํฉ๋๋ค.
ํ์ง๋ง ์ฐจ์ ์ ํ์ํ๋ ๊ธฐ๋ฅ์ด ์ถ๊ฐ์ ์ผ๋ก ํ์ํ๋ค๋ฉด LaneDecorator ํด๋์ค์ ๊ฐ์ฒด๊ฐ ํ์ํฉ๋๋ค.
์ด ๋ LaneDecorator์์๋ ์ฐจ์ ํ์ ๊ธฐ๋ฅ๋ง ์ง์ ์ ์ผ๋ก ์ ๊ณตํ๊ณ , ๊ธฐ๋ณธ ๋๋ก ํ์ ๊ธฐ๋ฅ์ RoadDisplay ํด๋์ค์ draw() ๋ฉ์๋๋ฅผ ํธ์ถํ๋ ๋ฐฉ์์ผ๋ก ๊ตฌํํฉ๋๋ค.
์ด๋ฅผ ์ํด LaneDecorator ํด๋์ค๋ RoadDisplay ๊ฐ์ฒด์ ๋ํ ์ฐธ์กฐ๊ฐ ํ์ํ๋ฐ, ์ด๋ฅผ ์์ ํด๋์ค์ธ DisplayDecorator ํด๋์ค์์ Display ํด๋์ค๋ก์ ์ปดํฌ์ง์ (composition) ๊ด๊ณ๋ฅผ ํตํด ํํ๋๊ณ ์์ต๋๋ค.
์ ๋ฐฉ์์ผ๋ก ์ค๊ณ๋ ํด๋์ค์ ์ฝ๋๋ฅผ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
public abstract class Display {
public abstract void draw();
}
// ๊ธฐ๋ณธ ๋๋ก ํ์
public class RoadDisplay extends Display {
@Override
public void draw() {
System.out.println("๊ธฐ๋ณธ ๋๋ก ํ์");
}
}
// ๋ค์ํ ์ถ๊ฐ ๊ธฐ๋ฅ์ ๋ํ ๊ณตํต ํด๋์ค
public abstract class DisplayDecorator extends Display {
private final Display decoratedDisplay;
public DisplayDecorator(Display decoratedDisplay) {
this.decoratedDisplay = decoratedDisplay;
}
public void draw() {
decoratedDisplay.draw();
}
}
// ์ฐจ์ ํ์
public class LaneDecorator extends DisplayDecorator {
// ๊ธฐ์กด ํ์ ํด๋์ค ์ค์
public LaneDecorator(Display decoratedDisplay) {
super(decoratedDisplay);
}
public void draw() {
super.draw(); // ์ค์ ๋ ๊ธฐ์กด ํ์ ๊ธฐ๋ฅ ์ํ
drawLane(); // ์ถ๊ฐ์ ์ผ๋ก ์ฐจ์ ํ์
}
private void drawLane() {
System.out.println("\t์ฐจ์ ํ์");
}
}
// ๊ตํต๋ ํ์
public class TrafficDecorator extends DisplayDecorator {
// ๊ธฐ์กด ํ์ ํด๋์ค ์ค์
public TrafficDecorator(Display decoratedDisplay) {
super(decoratedDisplay);
}
public void draw() {
super.draw(); // ์ค์ ๋ ๊ธฐ์กด ํ์ ๊ธฐ๋ฅ ์ํ
drawTraffic();
}
private void drawTraffic() {
System.out.println("\t๊ตํต๋ ํ์");
}
}
// ํด๋ผ์ด์ธํธ, new -> ๊ฐ์ฒด์์ ์กฐํฉ
public class Client {
public static void main(String[] args) {
Display road = new RoadDisplay();
road.draw(); // ๊ธฐ๋ณธ ๋๋ก ํ์
Display roadWithLane = new LaneDecorator(new RoadDisplay());
roadWithLane.draw(); // ๊ธฐ๋ณธ ๋๋ก ํ์ + ์ฐจ์ ํ์
Display roadWithTraffic = new TrafficDecorator(new RoadDisplay());
roadWithTraffic.draw(); // ๊ธฐ๋ณธ ๋๋ก ํ์ + ๊ตํต๋ ํ์
Display roadWithLaneAndTraffic =
new TrafficDecorator(new LaneDecorator(new RoadDisplay()));
roadWithLaneAndTraffic.draw(); // ๊ธฐ๋ณธ ๋๋ก ํ์ + ์ฐจ์ ํ์ + ๊ตํต๋ ํ์
}
}
๊ธฐ๋ณธ ๋๋ก ํ์
๊ธฐ๋ณธ ๋๋ก ํ์
์ฐจ์ ํ์
๊ธฐ๋ณธ ๋๋ก ํ์
๊ตํต๋ ํ์
๊ธฐ๋ณธ ๋๋ก ํ์
์ฐจ์ ํ์
๊ตํต๋ ํ์
์ ์ฝ๋์์ ์ดํด๋ณผ ์ ์ road, roadWithLane, roadWithTraffic ๊ฐ์ฒด์ ์ ๊ทผ์ด ๋ชจ๋ Display ํด๋์ค๋ฅผ ํตํด ์ด๋ฃจ์ด์ง๋ค๋ ์ ์ ๋๋ค.
์ฆ ๋ค์๊ณผ ๊ฐ์ ๊ธฐ๋ฅ์ ๊ด๊ณ์์ด Client ํด๋์ค๋ ๋ชจ๋ Display ํด๋์ค๋ง์ ํตํด ์ผ๊ด์ฑ ์๋ ๋ฐฉ์์ผ๋ก ๋๋ก ์ ๋ณด๋ฅผ ํ์ํ ์ ์์ต๋๋ค.
- road: ๊ธฐ๋ณธ ๋๋ก ํ์
- roadWithLane: ๊ธฐ๋ณธ ๋๋ก ํ์ + ์ฐจ์ ํ์
- roadWithTraffic: ๊ธฐ๋ณธ ๋๋ก ํ์ + ๊ตํต๋ ํ์
- roadWithLaneAndTraffic: ๊ธฐ๋ณธ ๋๋ก ํ์ + ์ฐจ์ ํ์ + ๊ตํต๋ ํ์
์ด์ ์์์ ๋ฐฉ์์์๋ ์ถ๊ฐ ๊ธฐ๋ฅ ์กฐํฉ๋ณ๋ก ๋ณ๋์ ํด๋์ค๋ฅผ ๊ตฌํ์ ํด์ผํ์ง๋ง, ์์ ๊ฐ์ ๋ฐฉ์์ ์ค๊ณ๋ฅผ ์ด์ฉํ๋ฉด ์กฐํฉ๋ณ ๋ณ๋์ ํด๋์ค๋ฅผ ๊ตฌํํ๋ ๋์ ๊ฐ ์ถ๊ฐ ๊ธฐ๋ฅ์ ํด๋นํ๋ ํด๋์ค์ ๊ฐ์ฒด๋ฅผ ์กฐํฉํด ์ถ๊ฐ ๊ธฐ๋ฅ์ ์กฐํฉ์ ๊ตฌํํ ์ ์์ต๋๋ค.
์ด๋ฌํ ์ค๊ณ๋ ์ถ๊ฐ ๊ธฐ๋ฅ์ ์๊ฐ ๋ง์์๋ก ์กฐํฉ์ ๊ฒฝ์ฐ์ ์๋ ๋ง์์ง๋ฏ๋ก ํจ๊ณผ๊ฐ ํฝ๋๋ค.
์๋ฅผ ๋ค์ด ์ฐจ์ ํ์ + ๊ตํต๋ ํ์์ ์ถ๊ฐ ๊ธฐ๋ฅ์ ๊ต์ฐจ๋ก๋ฅผ ํ์ํ๋ ์ถ๊ฐ ๊ธฐ๋ฅ์ ์ง์ํ๋ ๊ฒฝ์ฐ ์๋ UML๊ณผ ๊ฐ์ด ๋จ์ํ CrossingDecorator ํด๋์ค๋ง ์ถ๊ฐํ ํ ๊ฐ์ฒด์์ ์กฐํฉ์ ํตํด ์ ์ฉ์ ํ ์ ์์ต๋๋ค.
// ๊ต์ฐจ๋ก ํ์
public class CrossingDecorator extends DisplayDecorator {
// ๊ธฐ์กด ํ์ ํด๋์ค ์ค์
public CrossingDecorator(Display decoratedDisplay) {
super(decoratedDisplay);
}
public void draw() {
super.draw(); // ์ค์ ๋ ๊ธฐ์กด์ ํ์ ๊ธฐ๋ฅ ์ํ
drawCrossing(); // ์ถ๊ฐ์ ์ผ๋ก ๊ต์ฐจ๋ก ํ์
}
private void drawCrossing() {
System.out.println("\t๊ต์ฐจ๋ก ํ์");
}
}
// ํด๋ผ์ด์ธํธ
public class Client {
...
// new ...(new ...(new ...( -> ๊ฐ์ฒด ์กฐํฉ
Display roadWithCrossingAndLandAndTraffic
= new LaneDecorator(new TrafficDecorator(new CrossingDecorator(new RoadDisplay())));
roadWithCrossingAndLandAndTraffic.draw(); // ๊ธฐ๋ณธ ๋๋ก ํ์ + ์ฐจ์ ํ์ + ๊ตํต๋ ํ์ + ๊ต์ฐจ๋ก ํ์
}
๊ธฐ๋ณธ ๋๋ก ํ์
๊ต์ฐจ๋ก ํ์
๊ตํต๋ ํ์
์ฐจ์ ํ์
๋ฐ์ฝ๋ ์ดํฐ(Decorator) ํจํด
- ๊ธฐ๋ณธ ๊ธฐ๋ฅ์ ์ถ๊ฐํ ์ ์๋ ๊ธฐ๋ฅ์ ์ข ๋ฅ๊ฐ ๋ง์ ๊ฒฝ์ฐ ๊ฐ ์ถ๊ฐ ๊ธฐ๋ฅ์ Decorator ํด๋์ค๋ก ์ ์ํ ํ ํ์ํ Decorator ๊ฐ์ฒด๋ฅผ ์กฐํฉํจ์ผ๋ก์จ ์ถ๊ฐ ๊ธฐ๋ฅ์ ์กฐํฉ์ ์ค๊ณ
- ์ฃผ์ด์ง ์ํฉ ๋ฐ ์ฉ๋์ ๋ฐ๋ผ ์ด๋ค ๊ฐ์ฒด์ ์ฑ ์์ ๋ง๋ถ์ด๋ ํจํด
- ๊ธฐ๋ฅ ํ์ฅ์ด ํ์ํ ๋ ์๋ธํด๋์ค ๋์ ์ฌ์ฉํ ์ ์๋ ์ ์ฐํ ๋์์ด ๋ ์ ์์
- ์์ผ๋ก์ ๋ณ๊ฒฝ์ด ์ผ๋ง๋ ๋ ์ง ๋ชจ๋ฅด๋ ์ํฉ์์ ์์์ ์ฌ์ฉํ ํ๋ก๊ทธ๋๋ฐ์ ๋ณ๊ฒฝ์ ์ ์ฐํ์ง ๋ชปํจ
๋ฐ์ฝ๋ ์ดํฐ ํจํด์ UML์ ๋๋ค.
- Component: ๊ธฐ๋ณธ ๊ธฐ๋ฅ์ ๋ปํ๋ ConcreteComponent์ ์ถ๊ฐ ๊ธฐ๋ฅ์ ๋ปํ๋ Decorator์ ๊ณตํต ๊ธฐ๋ฅ์ ์ ์, ์ฆ ํด๋ผ์ด์ธํธ๋ Component๋ฅผ ํตํด ์ค์ ๊ฐ์ฒด๋ฅผ ์ฌ์ฉ
- ConcreteComponent: ๊ธฐ๋ณธ ๊ธฐ๋ฅ์ ๊ตฌํํ๋ ํด๋์ค
- Decorator: ๋ง์ ์๊ฐ ์กด์ฌํ๋ ๊ตฌ์ฒด์ ์ธ Decorator์ ๊ณตํต ๊ธฐ๋ฅ์ ์ ๊ณต
- ConcreteDecoratorA, ConcreteDecoratorB: Decorator์ ํ์ ํด๋์ค๋ก ๊ธฐ๋ณธ ๊ธฐ๋ฅ์ ์ถ๊ฐ๋๋ ๊ฐ๋ณ์ ์ธ ๊ธฐ๋ฅ
๋ฐ์ฝ๋ ์ดํฐ ํจํด์ ์ํ์ค ๋ค์ด์ด๊ทธ๋จ์ ๋๋ค.
ConcreteComponent๊ฐ c๋ก ์ ์๋์ด ์๊ณ , ConcreteDecoratorA์ ๊ฐ์ฒด a์ ์ด์ ๋ํ ๋ฐ์ฝ๋ ์ดํฐ๋ก ConcreteDecoratorB์ ๊ฐ์ฒด b๊ฐ ์๋ค๊ณ ๊ฐ์ ํด๋ณด๊ณ์ต๋๋ค.
์ฆ, ๋ค์๊ณผ ๊ฐ์ด ๊ฐ์ฒด๊ฐ ์์ฑ๋ ๊ฒฝ์ฐ์ ๋๋ค.
Component c = new ConcreteComponent();
Component a = new ConcreteDecoratorA(c);
Component b = new ConcreteDecoratorB(a);
์ ์ฝ๋์์ Client๊ฐ ๊ฐ์ฒด b์ operation ๋ฉ์๋๋ฅผ ํธ์ถํ๋ฉด ๊ฐ์ฒด b๊ฐ ๊ฐ๋ฆฌํค๋ Component, ์ฆ ConcreteDecoratorA ๊ฐ์ฒด a์ operation ๋ฉ์๋๋ฅผ ํธ์ถํฉ๋๋ค.
๊ฐ์ฒด a ์ญ์ ์์ ์ด ๊ฐ๋ฆฌํค๋ Component, ์ฆ ConcreteComponent ๊ฐ์ฒด c์ operation ๋ฉ์๋๋ฅผ ํธ์ถํ ํ ์์ ์ addedBehavior ๋ฉ์๋๋ฅผ ํธ์ถํฉ๋๋ค.
๊ฐ์ฒด b ์ญ์ ๊ฐ์ฒด a์ operation ๋ฉ์๋๋ฅผ ํธ์ถํ ํ ์์ ์ addedBehavior ๋ฉ์๋๋ฅผ ํธ์ถํฉ๋๋ค.
AOP์ ๋ํ ์ ๋ฆฌ๋ฅผ ํ๋ ค๊ณ ํ์ง๋ง ..... ์ด๋ฒ ํฌ์คํ ์์๋ ๋ถ๊ฐ ๊ธฐ๋ฅ์ ์์ํ๋ ์ ํต์ ์ธ ๋ฐฉ๋ฒ์ธ ํ๋ก์์ ๋ฐ์ฝ๋ ์ดํฐ ํจํด์ ๋ํด ์ ๋ฆฌ๋ฅผ ํด๋ณด์์ต๋๋ค. ํ์ ์๋ฐ๋ฅผ ์ฌ์ฉํ๋ฉด์ ์ ๋ ฅ์ ๋ฐ์ ๋, ๊ฐ๋ BufferedReader ํด๋์ค๋ฅผ ์ฌ์ฉํ ์ ์ด ์์๋๋ฐ ์ด ํด๋์ค๋ฅผ ์ฌ์ฉํด์ ๊ฐ์ฒด๋ฅผ ์์ฑํ ๋ ๋ค์๊ณผ ๊ฐ์ด ์์ฑ์ ํ์๋๋ฐ, ์ด๊ฒ์ด ๋ฐ์ฝ๋ ์ดํฐ ํจํด์ ์ฌ์ฉํ๋ ์์ ์ธ ๊ฒ ๊ฐ์ต๋๋ค.
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
๊ฐ์ธ์ ์ผ๋ก ๋ฐ์ฝ๋ ์ดํฐ ํจํด์ ๊ฒฝ์ฐ ์ดํดํ๊ธฐ๊น์ง ๋ช ๋ฒ์ ๊ณ์ํด์ ๋ณด์๋๋ฐ, ์์ ํ ์ดํด๋ฅผ ํ๋ค๊ณ ๋ ๋ณด๊ธฐ ํ๋ค๊ฒ ์ง๋ง ๊ณ์ ๋ณด๋ค๋ณด๋ ๋๋ต์ ์ผ๋ก๋๋ง ์ดํด๊ฐ ๋๋ ๊ฒ ๊ฐ์ต๋๋ค.
์ฌ์ค ์ด๋ ๊ฒ ์ ๋ฆฌ๋ฅผ ํ๋ ๊ฒ๋ ์ข์ง๋ง, ๊ฐ์ฅ ์ข์ ๋ฐฉ๋ฒ์ ์ค์ ์ ์ฉ์ ํด ๋ณด๋ ๋ฐฉ์์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค. ๋ค์์ ์ค๋ฌด์์ ์ด๋ฌํ ํจํด์ ์ ์ฉํด๋ณด๊ณ , ๊ฒฝํ์ ํตํด ์ ๊ฒ์ผ๋ก ๋ง๋ค๊ณ ์ถ์ต๋๋ค :)
๊ทธ ๋ ๊ธฐํ๊ฐ ๋๋ค๋ฉด, ๋ค์ ์ ๋ฆฌ๋ฅผ ํด๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค.
AOP๊น์ง ์ ๋ฆฌ๋ฅผ ํ๊ธฐ์ ๋ด์ฉ์ด ๋๋ฌด ๋ฐฉ๋ํด์ง ๊ฒ ๊ฐ์ AOP์ ๋ํ ์ ๋ฆฌ๋ ๋ค์ ํฌ์คํ ์์ ํ๋๋ก ํ๊ฒ ์ต๋๋ค. ๐คฃ
References
- https://fastcampus.co.kr/
- https://ko.wikipedia.org/wiki/%ED%94%84%EB%A1%9D%EC%8B%9C
- https://milkye.tistory.com/202
- https://www.inflearn.com/course/the-java-code-manipulation/dashboard
- http://www.yes24.com/Product/Goods/12501269
'Spring' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
Spring Boot + MockMvc ํ ์คํธ(feat. Kotlin) (0) | 2021.09.07 |
---|---|
[Spring] - @JsonProperty, @JsonNaming (2) | 2021.09.02 |
Spring Boot Maven profile ์ด์ & ๊ฐ๋ฐ DB ๋ถ๋ฆฌ(AWS EC2) (6) | 2021.06.18 |
JUnit - @ParameterizedTest, @ValueSource, @CsvSource, @MethodSource ์ด๋ ธํ ์ด์ (4) | 2021.06.08 |
[Spring] ๊ฐ์ฒด๋ณต์ฌ BeanUtils.copyProperties() & ์๋ ์๋ฆฌ (0) | 2021.02.20 |
๋๊ธ