๋์์ธ ํจํด. GoF 23๊ฐ๋ฅผ ๋ค ์ธ์ธ ํ์๋ ์๋ค. ์ฑ๊ธํค·์ ๋ต·ํ ํ๋ฆฟ ๋ฉ์๋·ํฉํ ๋ฆฌ·์ต์ ๋ฒ·๋ฐ์ฝ๋ ์ดํฐ — ์ค๋ฌด์์ ์์ฃผ ์ฐ๋ ์ฌ์ฏ ๊ฐ์ง ํจํด์, ์คํ๋ง ์ฝ๋์ ์ด๋ฏธ ์ด๋ป๊ฒ ๋ น์ ์๋์ง์ ํจ๊ป ์ ๋ฆฌํ๋ค.
๋ค์ด๊ฐ๋ฉฐ
๋์์ธ ํจํด์ ์ฒ์ ๊ณต๋ถํ๋ฉด GoF 23๊ฐ๋ฅผ ์ธ์ฐ๋ ค๋ค ์ง์น๋ค. ๊ทธ๋ฐ๋ฐ ์ ์ ์ค๋ฌด์์๋ ๊ทธ์ค ์์ ๊ผฝ๋ ๋ช ๊ฐ๋ฅผ ๋ฐ๋ณตํด์ ์ด๋ค. ๊ฒ๋ค๊ฐ ์ฐ๋ฆฌ๊ฐ ๋งค์ผ ์ฐ๋ ์คํ๋ง ํ๋ ์์ํฌ ์์ฒด๊ฐ ๋์์ธ ํจํด ๋ฉ์ด๋ฆฌ๋ค. ๋น(Bean), JdbcTemplate, @EventListener ๊ฐ์ ๊ฒ๋ค์ด ์ ๋ถ ํจํด์ ๊ตฌํ์ฒด๋ค.
๋์์ธ ํจํด์ ์ธ์ฐ๋ ๊ฒ ์๋๋ผ, ์ด๋ฏธ ์ฐ๊ณ ์๋ ๊ฒ์ ์ด๋ฆ์ ๋ถ์ด๋ ์ผ์ ๊ฐ๊น๋ค.
์ด ๊ธ์์๋ ์ค๋ฌด์์ ์์ฃผ ๋ง๋๋ ์ฌ์ฏ ๊ฐ์ง ํจํด์ ๊ณจ๋ผ, ์ด๋ค ๋ฌธ์ ๋ฅผ ํธ๋์ง์ ์คํ๋ง์ด ์ด๊ฑธ ์ด๋์ ์ฐ๋์ง๋ฅผ ์ฝ๋์ ํจ๊ป ์ ๋ฆฌํ๋ค. ์์๋ Java/Spring ๊ธฐ์ค์ด๋ค.
1. ์ฑ๊ธํค (Singleton) — ์ธ์คํด์ค๋ ํ๋๋ฉด ์ถฉ๋ถํ๋ค
ํด๋์ค์ ์ธ์คํด์ค๋ฅผ ๋ฑ ํ๋๋ง ๋ง๋ค์ด ๊ณต์ ํ๋ ํจํด์ด๋ค. ์ค์ ๊ฐ์ฒด, ์ปค๋ฅ์ ํ, ์บ์์ฒ๋ผ "์ฌ๋ฌ ๊ฐ ์์ ์ด์ ๊ฐ ์๋" ๊ฒ์ ์ด๋ค.
์ง์ ๊ตฌํํ๋ฉด ๋ณดํต ์ด๋ ๊ฒ ํ๋ค.
public class AppConfig {
private static final AppConfig INSTANCE = new AppConfig();
private AppConfig() {} // ์์ฑ์๋ฅผ ๋ง์ ์ธ๋ถ ์์ฑ ์ฐจ๋จ
public static AppConfig getInstance() {
return INSTANCE;
}
}
์์ฑ์๋ฅผ private์ผ๋ก ๋ง๊ณ , ์ ์ ์ธ์คํด์ค ํ๋๋ง ๋ ธ์ถํ๋ค. ์ด๋์ getInstance()๋ฅผ ๋ถ๋ฅด๋ ๊ฐ์ ๊ฐ์ฒด๊ฐ ๋์์จ๋ค.
ํ์ง๋ง ์ค๋ฌด์์ ์ด๋ ๊ฒ ์ง์ ์ง๋ ๊ฒฝ์ฐ๋ ๋๋ฌผ๋ค. ๋ฉํฐ์ค๋ ๋ ํ๊ฒฝ์์์ ์ด๊ธฐํ ๋ฌธ์ , ํ ์คํธ์ ์ด๋ ค์ ๋๋ฌธ์ด๋ค. ์ง์ ๋ง๋ ์ฑ๊ธํค์ ์ํ๋ฅผ ๊ณต์ ํ๊ธฐ ๋๋ฌธ์ ํ ์คํธ ๊ฐ ๊ฒฉ๋ฆฌ๊ฐ ๊นจ์ง๊ธฐ ์ฝ๊ณ , ๋ชฉ(mock)์ผ๋ก ๋ฐ๊ฟ์น๊ธฐ๋ ์ด๋ ต๋ค.
์คํ๋ง ์ด๋์ ์๋: ์ฌ์ค ์ฐ๋ฆฌ๋ ์ด๋ฏธ ์ฑ๊ธํค์ ๋งค์ผ ์ฐ๊ณ ์๋ค. ์คํ๋ง ๋น์ ๊ธฐ๋ณธ ์ค์ฝํ๊ฐ ์ฑ๊ธํค์ด๋ค. @Service, @Repository, @Component๋ก ๋ฑ๋ก๋ ๋น์ ์ปจํ ์ด๋๋น ํ๋๋ง ์์ฑ๋ผ ๊ณต์ ๋๋ค. ์ง์ getInstance()๋ฅผ ์ง์ง ์์๋, ์คํ๋ง์ด ์ฑ๊ธํค ๊ด๋ฆฌ๋ฅผ ๋์ ํด์ฃผ๋ ๊ฒ์ด๋ค.
๊ทธ๋์ ์คํ๋ง์ ์ด๋ค๋ฉด ์ฑ๊ธํค์ ์ง์ ๊ตฌํํ ์ผ์ ๊ฑฐ์ ์๋ค. ๋์ ๋น์ ์ํ๋ฅผ ๊ฐ์ง ์๊ฒ(stateless) ์ค๊ณํ๋ ๊ฒ ์ค์ํ๋ค. ์ฑ๊ธํค ๋น์ ๊ฐ๋ณ ํ๋๋ฅผ ๋๋ฉด ๋ชจ๋ ์์ฒญ์ด ๊ทธ ํ๋๋ฅผ ๊ณต์ ํด์ ๋์์ฑ ๋ฒ๊ทธ๊ฐ ์๊ธด๋ค.
// ์ํ: ์ฑ๊ธํค ๋น์ ๊ฐ๋ณ ์ํ
@Service
public class CounterService {
private int count = 0; // ๋ชจ๋ ์์ฒญ์ด ๊ณต์ → ๋์์ฑ ๋ฒ๊ทธ
public void increment() { count++; }
}
์ฑ๊ธํค ๋น์ ๋ฌด์ํ๋ก ๋๊ณ , ์ํ๊ฐ ํ์ํ๋ฉด ๋ฉ์๋ ํ๋ผ๋ฏธํฐ๋ ์ง์ญ ๋ณ์๋ก ๋ค๋ฃจ๋ ๊ฒ์ด ์์น์ด๋ค.
2. ์ ๋ต ํจํด (Strategy) — if-else ์ง์ฅ ํ์ถ
๊ฐ์ฅ ์์ฃผ ์ฐ๊ณ , ํจ๊ณผ๋ ํ์คํ ํจํด์ด๋ค. ์๊ณ ๋ฆฌ์ฆ(์ ๋ต)์ ์ธํฐํ์ด์ค๋ก ์ถ์ํํ๊ณ , ์คํ ์์ ์ ๊ณจ๋ผ ์ฐ๋ ๊ตฌ์กฐ๋ค.
๊ฒฐ์ ์๋จ์ด ๋์ด๋๋ ์ํฉ์ ๋ ์ฌ๋ ค๋ณด์. ์ฒ์์ if-else๋ก ์์ํ๋ค.
// ์ํฐํจํด: ๊ฒฐ์ ์๋จ์ด ๋ ๋๋ง๋ค ์ด ๋ฉ์๋๋ฅผ ์์ ํด์ผ ํ๋ค
public PaymentResult pay(PaymentRequest request) {
if (request.type() == CARD) {
// ์นด๋ ๊ฒฐ์ ๋ก์ง
} else if (request.type() == BANK) {
// ๊ณ์ข์ด์ฒด ๋ก์ง
} else if (request.type() == POINT) {
// ํฌ์ธํธ ๊ฒฐ์ ๋ก์ง
}
// ๊ฒฐ์ ์๋จ ์ถ๊ฐ = ์ด ์ฝ๋ ์์ (OCP ์๋ฐ)
}
๊ฒฐ์ ์๋จ์ด ์ถ๊ฐ๋ ๋๋ง๋ค ์ด ๋ฉ์๋๋ฅผ ๊ฑด๋๋ ค์ผ ํ๋ค. ๊ฐ๋ฐฉ-ํ์ ์์น(OCP) ์๋ฐ์ด๋ค. ์ ๋ต ํจํด์ผ๋ก ํ๋ฉด ์ด๋ ๊ฒ ๋๋ค.
// ์ ๋ต ์ธํฐํ์ด์ค
public interface PaymentProcessor {
boolean supports(PaymentType type);
PaymentResult process(PaymentRequest request);
}
@Component
public class CardPaymentProcessor implements PaymentProcessor {
public boolean supports(PaymentType type) { return type == PaymentType.CARD; }
public PaymentResult process(PaymentRequest request) {
// ์นด๋ ๊ฒฐ์ ๋ก์ง
return PaymentResult.success();
}
}
@Component
public class PointPaymentProcessor implements PaymentProcessor {
public boolean supports(PaymentType type) { return type == PaymentType.POINT; }
public PaymentResult process(PaymentRequest request) {
// ํฌ์ธํธ ๊ฒฐ์ ๋ก์ง
return PaymentResult.success();
}
}
์ฌ๊ธฐ์ ์คํ๋ง์ ๊ฐ๋ ฅํจ์ด ๋๋ฌ๋๋ค. ์ธํฐํ์ด์ค ํ์ ์ List๋ก ์ฃผ์ ๋ฐ์ผ๋ฉด, ์คํ๋ง์ด ๋ชจ๋ ๊ตฌํ์ฒด๋ฅผ ์๋์ผ๋ก ๋ชจ์์ ๋ฃ์ด์ค๋ค.
@Service
public class PaymentService {
private final List<PaymentProcessor> processors; // ๋ชจ๋ ๊ตฌํ์ฒด ์๋ ์ฃผ์
public PaymentService(List<PaymentProcessor> processors) {
this.processors = processors;
}
public PaymentResult pay(PaymentRequest request) {
return processors.stream()
.filter(p -> p.supports(request.type()))
.findFirst()
.orElseThrow(() -> new UnsupportedPaymentException(request.type()))
.process(request);
}
}
์ด์ ์ ๊ฒฐ์ ์๋จ์ PaymentProcessor๋ฅผ ๊ตฌํํ @Component๋ฅผ ์ถ๊ฐํ๊ธฐ๋ง ํ๋ฉด ๋๋ค. PaymentService๋ ํ ์ค๋ ๊ณ ์น์ง ์๋๋ค. ์ด๊ฒ ์ ๋ต ํจํด + ์คํ๋ง DI์ ์ ์ ์กฐํฉ์ด๋ค.
3. ํ ํ๋ฆฟ ๋ฉ์๋ (Template Method) — ํ๋ฆ์ ๊ณ ์ , ์ผ๋ถ๋ง ๋ณ๊ฒฝ
์ ์ฒด ์ฒ๋ฆฌ ํ๋ฆ์ ๊ณ ์ ํ๋, ์ผ๋ถ ๋จ๊ณ๋ง ํ์ ํด๋์ค๊ฐ ๋ฐ๊พธ๋๋ก ํ๋ ํจํด์ด๋ค. "๋ผ๋๋ ๊ฐ๊ณ ์๋ง ๋ค๋ฅธ" ์์ ์ ์ด๋ค.
๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์์ → ๊ฒ์ฆํ๊ณ → ์ ์ฅํ๋ ํ๋ฆ์ด ์๋ค๊ณ ํ์. ํ๋ฆ์ ํญ์ ๊ฐ์ง๋ง ๋ฐ์ดํฐ ์์ค(CSV, API, DB)๋ง๋ค ์ธ๋ถ ๊ตฌํ์ด ๋ค๋ฅด๋ค.
public abstract class DataImporter {
// ํ
ํ๋ฆฟ ๋ฉ์๋: ํ๋ฆ์ ๊ณ ์ ํ๋ค (final๋ก ์ค๋ฒ๋ผ์ด๋ ๋ฐฉ์ง)
public final void importData(String source) {
List<Row> raw = read(source); // ๋จ๊ณ 1
List<Row> valid = validate(raw); // ๋จ๊ณ 2
save(valid); // ๋จ๊ณ 3
log.info("{}๊ฑด ์ํฌํธ ์๋ฃ", valid.size());
}
// ํ์ ํด๋์ค๊ฐ ์ฑ์ฐ๋ ๋ถ๋ถ
protected abstract List<Row> read(String source);
protected abstract List<Row> validate(List<Row> rows);
protected abstract void save(List<Row> rows);
}
public class CsvDataImporter extends DataImporter {
protected List<Row> read(String source) { /* CSV ํ์ฑ */ }
protected List<Row> validate(List<Row> rows) { /* CSV ๊ฒ์ฆ */ }
protected void save(List<Row> rows) { /* DB ์ ์ฅ */ }
}
importData()์ ์์๋ ๋๊ตฌ๋ ๋ชป ๋ฐ๊พผ๋ค. ๊ฐ ๋จ๊ณ์ ๊ตฌํ๋ง ๋ฌ๋ผ์ง๋ค.
์คํ๋ง ์ด๋์ ์๋: JdbcTemplate์ด ๋ํ์ ์ด๋ค. ์ปค๋ฅ์ ์ป๊ธฐ → ์ฟผ๋ฆฌ ์คํ → ๊ฒฐ๊ณผ ๋งคํ → ์ปค๋ฅ์ ๋ฐํ์ด๋ผ๋ ํ๋ฆ์ ๊ณ ์ ๋ผ ์๊ณ , ๊ฐ๋ฐ์๋ RowMapper๋ก "๊ฒฐ๊ณผ ๋งคํ" ๋ถ๋ถ๋ง ์ฑ์ด๋ค. RestTemplate๋ ๊ฐ์ ๊ตฌ์กฐ๋ค.
4. ํฉํ ๋ฆฌ ํจํด (Factory) — ๊ฐ์ฒด ์์ฑ ์ฑ ์ ๋ถ๋ฆฌ
๊ฐ์ฒด ์์ฑ ๋ก์ง์ ํ๊ณณ์ผ๋ก ๋ชจ์ผ๋ ํจํด์ด๋ค. new๋ฅผ ์ง์ ์ฐ๋ฉด ํด๋ผ์ด์ธํธ ์ฝ๋๊ฐ ๊ตฌ์ฒด ํด๋์ค์ ๋ฌถ์ด๋๋ฐ, ํฉํ ๋ฆฌ๊ฐ ๊ทธ ๊ฒฐ์ ์ ๋์ ํ๋ค.
public class NotificationFactory {
public static Notification create(Channel channel) {
return switch (channel) {
case EMAIL -> new EmailNotification();
case SMS -> new SmsNotification();
case PUSH -> new PushNotification();
};
}
}
// ์ฌ์ฉํ๋ ์ชฝ์ ๊ตฌ์ฒด ํด๋์ค๋ฅผ ๋ชฐ๋ผ๋ ๋๋ค
Notification noti = NotificationFactory.create(Channel.EMAIL);
noti.send("์ฃผ๋ฌธ์ด ์๋ฃ๋์์ต๋๋ค");
ํธ์ถํ๋ ์ฝ๋๋ EmailNotification์ด๋ผ๋ ๊ตฌ์ฒด ํ์ ์ ๋ชฐ๋ผ๋ ๋๋ค. ์ ์ฑ๋์ด ์๊ธฐ๋ฉด ํฉํ ๋ฆฌ๋ง ์์ ํ๋ฉด ๋๋ค.
์คํ๋ง ์ด๋์ ์๋: ์คํ๋ง ์ปจํ ์ด๋ ์์ฒด๊ฐ ๊ฑฐ๋ํ ํฉํ ๋ฆฌ๋ค. BeanFactory๋ผ๋ ์ด๋ฆ๋ถํฐ๊ฐ ๊ทธ๋ ๋ค. @Bean ๋ฉ์๋๋ ํฉํ ๋ฆฌ ๋ฉ์๋ ํจํด์ ๊ตฌํ์ด๋ค. ์ฐ๋ฆฌ๊ฐ new๋ก ๊ฐ์ฒด๋ฅผ ๋ง๋ค์ง ์๊ณ ์ปจํ ์ด๋์์ ๊บผ๋ด ์ฐ๋ ๊ฒ ์์ฒด๊ฐ ํฉํ ๋ฆฌ ํจํด ์์์ ๋์ํ๋ ๊ฒ์ด๋ค.
5. ์ต์ ๋ฒ ํจํด (Observer) — ๋์จํ๊ฒ ์ฐ๊ฒฐํ๊ธฐ
ํ ๊ฐ์ฒด์ ์ํ๊ฐ ๋ฐ๋๋ฉด, ๊ทธ๊ฒ์ ๊ตฌ๋ ํ๋ ๊ฐ์ฒด๋ค์๊ฒ ์๋์ผ๋ก ํต์งํ๋ ํจํด์ด๋ค. ๋ฐํ์์ ๊ตฌ๋ ์๋ฅผ ๋์จํ๊ฒ ๋ถ๋ฆฌํ๋ค.
์ฃผ๋ฌธ์ด ์์ฑ๋๋ฉด ์ด๋ฉ์ผ ๋ฐ์ก, ์ฌ๊ณ ์ฐจ๊ฐ, ํต๊ณ ์ง๊ณ๊ฐ ์ผ์ด๋์ผ ํ๋ค๊ณ ํ์. ์ด๊ฑธ OrderService์ ๋ค ์ฑ์ฌ๋ฃ์ผ๋ฉด ๊ฒฐํฉ๋๊ฐ ํญ๋ฐํ๋ค.
// ์ํฐํจํด: OrderService๊ฐ ๋ชจ๋ ํ์ ์์
์ ์ง์ ํธ์ถ
public void createOrder(OrderRequest request) {
Order order = orderRepository.save(...);
emailService.sendConfirmation(order); // ์ด๋ฉ์ผ๊ณผ ๊ฒฐํฉ
inventoryService.decrease(order); // ์ฌ๊ณ ์ ๊ฒฐํฉ
statisticsService.record(order); // ํต๊ณ์ ๊ฒฐํฉ
}
์ต์ ๋ฒ ํจํด(์คํ๋ง ์ด๋ฒคํธ)์ผ๋ก ํ๋ฉด ๋ฐํ๊ณผ ์ฒ๋ฆฌ๊ฐ ๋ถ๋ฆฌ๋๋ค.
// ์ด๋ฒคํธ ์ ์
public record OrderCreatedEvent(Long orderId) {}
// ๋ฐํ์: ์ฃผ๋ฌธ ์์ฑ ํ ์ด๋ฒคํธ๋ง ๋์ง๋ค
@Service
public class OrderService {
private final ApplicationEventPublisher publisher;
public void createOrder(OrderRequest request) {
Order order = orderRepository.save(request.toEntity());
publisher.publishEvent(new OrderCreatedEvent(order.getId()));
// ์ดํ ๋ฌด์จ ์ผ์ด ์ผ์ด๋๋์ง OrderService๋ ๋ชจ๋ฅธ๋ค
}
}
// ๊ตฌ๋
์(์ต์ ๋ฒ): ๊ฐ์ ์์์ ๋ฐ์ํ๋ค
@Component
public class OrderEventHandler {
@EventListener
public void sendEmail(OrderCreatedEvent event) {
// ์ฃผ๋ฌธ ํ์ธ ์ด๋ฉ์ผ ๋ฐ์ก
}
@EventListener
public void decreaseInventory(OrderCreatedEvent event) {
// ์ฌ๊ณ ์ฐจ๊ฐ
}
}
OrderService๋ ์ด๋ฉ์ผ·์ฌ๊ณ ·ํต๊ณ์ ์กด์ฌ์กฐ์ฐจ ๋ชจ๋ฅธ๋ค. ํ์ ์์ ์ ์ถ๊ฐํ๊ณ ์ถ์ผ๋ฉด @EventListener ๋ฉ์๋๋ง ๋๋ฆฌ๋ฉด ๋๋ค.
์คํ๋ง ์ด๋์ ์๋: ApplicationEvent์ @EventListener๊ฐ ์ต์ ๋ฒ ํจํด ๊ทธ ์์ฒด๋ค. @TransactionalEventListener๋ฅผ ์ฐ๋ฉด ํธ๋์ญ์ ์ปค๋ฐ ์ดํ์๋ง ์ต์ ๋ฒ๊ฐ ๋์ํ๊ฒ ํ ์๋ ์๋ค.
6. ๋ฐ์ฝ๋ ์ดํฐ ํจํด (Decorator) — ๊ธฐ๋ฅ์ ๊ฒน๊ฒน์ด ์ ํ๊ธฐ
์๋ ๊ฐ์ฒด๋ฅผ ๊ทธ๋๋ก ๋๊ณ , ๊ฐ์ ์ธํฐํ์ด์ค๋ก ๊ฐ์ธ ๊ธฐ๋ฅ์ ๋ง๋ถ์ด๋ ํจํด์ด๋ค. ์์ ๋์ ์กฐํฉ์ผ๋ก ๊ธฐ๋ฅ์ ํ์ฅํ๋ค.
public interface Notifier {
void send(String message);
}
// ๊ธฐ๋ณธ ๊ตฌํ
public class SlackNotifier implements Notifier {
public void send(String message) {
// ์ฌ๋์ผ๋ก ์ ์ก
}
}
// ๋ฐ์ฝ๋ ์ดํฐ: ๊ฐ์ ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ๊ณ , ์๋ณธ์ ๊ฐ์ผ๋ค
public class LoggingNotifier implements Notifier {
private final Notifier delegate;
public LoggingNotifier(Notifier delegate) {
this.delegate = delegate;
}
public void send(String message) {
log.info("์ ์ก ์์: {}", message);
delegate.send(message); // ์๋ณธ ๋์
log.info("์ ์ก ์๋ฃ");
}
}
// ์ฌ์ฉ: ๊ฒน๊ฒน์ด ๊ฐ์ผ๋ค
Notifier notifier = new LoggingNotifier(new RetryNotifier(new SlackNotifier()));
notifier.send("๋ฐฐํฌ ์๋ฃ"); // ๋ก๊น
→ ์ฌ์๋ → ์ค์ ์ ์ก
์๋ณธ SlackNotifier๋ ์๋์ง ์๊ณ ๋ก๊น , ์ฌ์๋ ๊ฐ์ ๊ธฐ๋ฅ์ ๋ฐ๊นฅ์์ ์ ํ๋ค.
์คํ๋ง/์๋ฐ ์ด๋์ ์๋: ์๋ฐ I/O์ new BufferedReader(new FileReader(...))๊ฐ ๊ต๊ณผ์์ ์ธ ๋ฐ์ฝ๋ ์ดํฐ๋ค. ์คํ๋ง์์๋ AOP ํ๋ก์๊ฐ ๊ฐ์ ์๋ฆฌ๋ก ๋์ํ๋ค. @Transactional์ด ๋ถ์ ๋น์, ์ค์ ๋ก๋ ํธ๋์ญ์ ์ฒ๋ฆฌ๋ฅผ ๋ง์ ํ ํ๋ก์ ๊ฐ์ฒด๊ฐ ์ฃผ์ ๋๋ค.
ํ๋์ ์ ๋ฆฌ
| ํจํด | ํด๊ฒฐํ๋ ๋ฌธ์ | ์คํ๋ง/์๋ฐ์์์ ์ |
| ์ฑ๊ธํค (Singleton) | ์ธ์คํด์ค๋ฅผ ํ๋๋ง ๊ณต์ | ์คํ๋ง ๋น ๊ธฐ๋ณธ ์ค์ฝํ |
| ์ ๋ต (Strategy) | ์กฐ๊ฑด๋ง๋ค ๋ค๋ฅธ ์๊ณ ๋ฆฌ์ฆ์ if-else ์์ด | List<Interface> ๋น ์ฃผ์ |
| ํ ํ๋ฆฟ ๋ฉ์๋ | ํ๋ฆ์ ๊ฐ๊ณ ์ผ๋ถ ๋จ๊ณ๋ง ๋ค๋ฅผ ๋ | JdbcTemplate, RestTemplate |
| ํฉํ ๋ฆฌ (Factory) | ๊ฐ์ฒด ์์ฑ ์ฑ ์์ ๋ถ๋ฆฌ | BeanFactory, @Bean |
| ์ต์ ๋ฒ (Observer) | ๋ฐํ์-๊ตฌ๋ ์๋ฅผ ๋์จํ๊ฒ ์ฐ๊ฒฐ | @EventListener |
| ๋ฐ์ฝ๋ ์ดํฐ | ์๋ณธ์ ์ ๊ฑด๋๋ฆฌ๊ณ ๊ธฐ๋ฅ ํ์ฅ | AOP ํ๋ก์, @Transactional |
๋ง์น๋ฉฐ
๋์์ธ ํจํด์ 23๊ฐ์ฉ ์ธ์ฐ๋ ๊ฑด ํฐ ์๋ฏธ๊ฐ ์๋ค. ๊ทธ๋ณด๋ค "์ง๊ธ ๋ด๊ฐ ๊ฒช๋ ๋ฌธ์ ๊ฐ ์ด๋ค ํจํด์ผ๋ก ํ๋ฆฌ๋๊ฐ" ๋ฅผ ๋ ์ฌ๋ฆด ์ ์๋ ๊ฒ ์ค์ํ๋ค. ๊ฒฐ์ ์๋จ์ด ์๊พธ ๋๋ฉด ์ ๋ต ํจํด, ํ์ ์์ ์ด ์ค์ค์ด ๋ถ์ผ๋ฉด ์ต์ ๋ฒ ํจํด ํ๋ ์์ผ๋ก.
๊ทธ๋ฆฌ๊ณ ํ ๊ฐ์ง ๋. ์ฐ๋ฆฌ๊ฐ ๋งค์ผ ์ฐ๋ ์คํ๋ง์ ์ด ํจํด๋ค์ ๊ฑฐ๋ํ ์ ์์ฅ์ด๋ค. @EventListener๋ฅผ ์ธ ๋ "์, ์ด๊ฒ ์ต์ ๋ฒ๊ตฌ๋" ํ๊ณ ์ธ์ํ๋ ์๊ฐ, ํ๋ ์์ํฌ์ ์ค๊ณ ์๋๊ฐ ๋ณด์ด๊ธฐ ์์ํ๋ค. ํจํด์ ์๋ค๋ ๊ฑด ๊ฒฐ๊ตญ ๋จ์ด ์ง๋์ ์ข์ ์ฝ๋๋ฅผ ๋ ์ ์ฝ๊ฒ ๋๋ ์ผ์ด๊ธฐ๋ ํ๋ค.
ํจํด์ ๋ชฉ์ ์ด ์๋๋ผ ๋๊ตฌ๋ค. ํจํด์ ์ํ ํจํด์ ์คํ๋ ค ์ฝ๋๋ฅผ ๋ณต์กํ๊ฒ ๋ง๋ ๋ค. ๋ฌธ์ ๊ฐ ๋จผ์ ๋ณด์ด๊ณ , ๊ทธ๋ค์์ ํจํด์ด ๋ฐ๋ผ์ค๋ ์์๊ฐ ๋ง๋ค.
์ฐธ๊ณ ์ถ์ฒ
- GoF, ใDesign Patterns: Elements of Reusable Object-Oriented Softwareใ
- Spring Framework Docs: Application Events — https://docs.spring.io/spring-framework/reference/core/beans/context-introduction.html
- Refactoring Guru: Design Patterns — https://refactoring.guru/design-patterns
'๐ป Engineering Log > Architecture & Design' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
| SOLID ์์น โ ์ข์ ๊ฐ์ฒด์งํฅ ์ค๊ณ์ ๋ค์ฏ ๊ฐ์ง ๊ธฐ์ค (0) | 2026.06.01 |
|---|