디자인 패턴
프로그램을 설계할 때 발생했던 문제점들을 해결할 수 있도록 하나의 규약 형태로 만들어 놓은 것
1. 싱글톤 패턴(singleton pattern)
하나의 클래스에 오직 하나의 인스턴스만 가지는 패턴 ex) 데이터베이스 연결 모듈
장점
1) 하나의 인스턴스를 다른 모듈들이 공유하므로, 인스턴스 생성 비용이 줄어든다.
단점
1) 의존성이 높아진다.
2) 단위 테스트(TDD)는 테스트가 서로 독립적이고 어떤 순서로든 실행 가능해야하는데 방해가 된다.
해결 방법
의존성 주입(DI)을 통해 모듈 간의 결합을 느슨하게 만든다.
메인 모듈이 직접 다른 하위 모듈에 대한 의존성을 주는 것이 아닌 중간에 의존성 주입자(injector)를 통해 메인 모듈이 '간접'적으로 의존성을 주입하게 한다. 이를 "디커플링 된다"고 함
- 의존성 주입의 장점 : 테스팅하기 쉽고 마이그레이션하기 수웛하다.
- 의존성 주입의 단점 : 모듈이 더욱 분리되어, 클래스 수가 늘어나 복잡성이 증가한다.
2. 팩토리 패턴(factory pattern)
객체 생성 부분을 떼어내 추상화한 패턴이자, 상속 관계의 두 클래스에서 상위 클래스가 중요한 뼈대를 결정하고 하위 클래스에서 객체 생성에 관한 구체적 내용을 결정하는 패턴
장점
1. 상위 클래스가 인스턴스 생성 방식을 알 필요 없기 때문에 유연성을 가진다.
2. 코드를 리팩토링하더라도, 한 곳만 고치면 되므로 유지 보수성이 증가한다.
3. 전략/정책 패턴(strategy/policy pattern)
객체의 행위를 바꾸고 싶은 경우, "직접" 수정하지 않고 전략이라 부르는 '캡슐화한 알고리즘'을 컨텍스트 안에서 바꿔주며 상호 교체가 가능하게 만드는 패턴
- 전략 패턴을 활용한 라이브러리 : Node.js의 passport
예시
1. 싱글톤 패턴
class Singleton {
private static class singleinstanceHolder {
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() { // 인스턴스 생성
return singleInstanceHolder.INSTANCE;
}
}
public class Main {
public static void main(String[] args) {
Singleton a = Singleton.getInstance();
Singleton b = Singleton.getInstance();
}
}
2. 팩토리 패턴
abstract class Coffee {
public abstract int getPrice();
@Override
public String toString() {
return "this coffee is " + this.getPrice();
}
}
class CoffeeFactory { // 상위 팩토리
public static Coffee getCoffee(String type, int price) {
if ("Latte".equalsIgnoreCase(type)) return new Latte(price);
else if ("Americano".equalsIgnoreCase(type)) return new Americano(price);
}
}
// 하위 팩토리
class Latte extends Coffee {
private int price;
public Latte(int price) {
this.price = price;
}
@Override
public int getPrice() {
return this.price;
}
}
class Americano extends Coffee {
private int price;
public Americano(int price) {
this.price = price;
}
@Override
public int getPrice() {
return this.price;
}
}
public class Main {
public static void main(String[] args) {
Coffee latte = CoffeeFactory.getCoffee("Latte", 4000);
Coffee ame = CoffeeFactory.getCoffee("Americano", 3000);
}
}
3. 전략 패턴
interface PaymentStrategy {
public void pay(int amount);
}
class KAKAOCardStrategy implements PaymentStrategy {
private String name;
private String cardNumber;
private String cvv;
private String dateOfExpriy;
...
}
class LUNACardStrategy implements PaymentStrategy {
private String emailId;
private String password;
...
}
...
class ShoppingCart {
...
public int calculateTotal() { ... }
public void pay(PaymentStrategy paymentMethod) {
int amount = calculateTotal();
paymentMethod.pay(amount);
}
}
public class Main {
public static void main(String[] args) {
ShoppingCart cart = new ShoppingCart();
...
cart.pay(new LUNACardStrategy("kundol@example.com", "puku"));
cart.pay(new KAKAOCardStrategy("ju hongchul", "123456", "123", "12/02"));
}
}
'CS' 카테고리의 다른 글
| [OS] 프로세스 상태와 계층 구조 (0) | 2025.10.07 |
|---|---|
| [OS] 프로세스 (0) | 2025.10.07 |
| [OS] 운영체제란 (0) | 2025.10.07 |
| 01-2. 컴퓨터 구조 (0) | 2025.03.07 |
| 01. 컴퓨터 구조 (0) | 2025.02.26 |