자기개발/검색한 자료 정리

Java에서 자주 사용되는 디자인 패턴 소개

실버블렛 2023. 4. 26. 11:30
반응형

Java에서 자주 사용되는 디자인 패턴 소개

디자인 패턴은 소프트웨어 설계에서 자주 발생하는 문제들을 해결하기 위한 재사용 가능한 설계 방식입니다. 이 글에서는 Java에서 자주 사용되는 디자인 패턴들을 소개하며, 각 패턴의 개념과 예제를 설명합니다.

1. 싱글턴 패턴 (Singleton Pattern)

싱글턴 패턴은 클래스의 인스턴스가 단 하나만 존재하도록 보장하는 패턴입니다. 이를 통해 전역 변수를 사용하지 않고도 어디서든 해당 인스턴스에 접근할 수 있습니다.

예제:

public class Singleton {
    private static Singleton instance;

    private Singleton() {}

    public static synchronized Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

2. 팩토리 메서드 패턴 (Factory Method Pattern)

팩토리 메서드 패턴은 객체 생성 로직을 서브 클래스에게 위임하여, 클라이언트 코드가 구체적인 클래스와 결합되지 않도록 하는 패턴입니다.

예제:

public interface Animal {
    void speak();
}

public class Dog implements Animal {
    public void speak() {
        System.out.println("Woof!");
    }
}

public class Cat implements Animal {
    public void speak() {
        System.out.println("Meow!");
    }
}

public abstract class AnimalFactory {
    public abstract Animal createAnimal();
}

public class DogFactory extends AnimalFactory {
    public Animal createAnimal() {
        return new Dog();
    }
}

public class CatFactory extends AnimalFactory {
    public Animal createAnimal() {
        return new Cat();
    }
}

3. 옵저버 패턴 (Observer Pattern)

옵저버 패턴은 객체 간의 일대다 의존 관계를 구현하여, 한 객체의 상태가 변경될 때 관련된 모든 객체들에게 자동으로 알림을 전달하는 패턴입니다.

예제:

public interface Observer {
    void update();
}

public interface Subject {
    void registerObserver(Observer observer);
    void removeObserver(Observer observer);
    void notifyObservers();
}

public class ConcreteSubject implements Subject {
    private List<Observer> observers = new ArrayList<>();

    public void registerObserver(Observer observer) {
        observers.add(observer);
    }

    public void removeObserver(Observer observer) {
        observers.remove(observer);
    }

    public void notifyObservers() {
        for (Observer observer : observers) {
            observer.update();
        }
    }
}

public class ConcreteObserver implements Observer {
    public void update() {
        System.out.println("Update received");
    }
}

4. 스트래티지 패턴 (Strategy Pattern)

스트래티지 패턴은 알고리즘을 캡슐화하여, 실행 시점에서 알고리즘을 선택할 수 있게 하는 패턴입니다.

예제:

public interface SortingStrategy {
    void sort(int[] numbers);
}

public class BubbleSort implements SortingStrategy {
    public void sort(int[] numbers) {
        // Bubble sort algorithm implementation
    }
}

public class QuickSort implements SortingStrategy {
    public void sort(int[] numbers) {
        // Quick sort algorithm implementation
    }
}

public class SortContext {
    private SortingStrategy strategy;

    public void setStrategy(SortingStrategy strategy) {
        this.strategy = strategy;
    }

    public void sort(int[] numbers) {
        strategy.sort(numbers);
    }

}

public class Main {
    public static void main(String[] args) {
        SortContext context = new SortContext();

        // Selecting Bubble Sort strategy
        context.setStrategy(new BubbleSort());
        context.sort(new int[] {
            4,
            2,
            1,
            3
        });

        // Selecting Quick Sort strategy
        context.setStrategy(new QuickSort());
        context.sort(new int[] {
            5,
            3,
            8,
            7
        });
    }
}

5. 데코레이터 패턴 (Decorator Pattern)

데코레이터 패턴은 객체에 동적으로 새로운 기능을 추가할 수 있게 하는 패턴입니다. 이 패턴은 상속 대신 컴포지션을 사용하여 기능을 확장합니다.

예제:

public interface Coffee {
    String getDescription();
    double getCost();
}

public class BasicCoffee implements Coffee {
    public String getDescription() {
        return "Basic Coffee";
    }

    public double getCost() {
        return 1.0;
    }
}

public abstract class CoffeeDecorator implements Coffee {
    protected Coffee coffee;

    public CoffeeDecorator(Coffee coffee) {
        this.coffee = coffee;
    }

    public abstract String getDescription();
    public abstract double getCost();
}

public class MilkDecorator extends CoffeeDecorator {
    public MilkDecorator(Coffee coffee) {
        super(coffee);
    }

    public String getDescription() {
        return coffee.getDescription() + ", with Milk";
    }

    public double getCost() {
        return coffee.getCost() + 0.5;
    }
}

public class Main {
    public static void main(String[] args) {
        Coffee coffee = new BasicCoffee();
        coffee = new MilkDecorator(coffee);

        System.out.println(coffee.getDescription());
        System.out.println(coffee.getCost());
    }
}

이 글에서는 Java에서 자주 사용되는 디자인 패턴 중 5가지를 소개했습니다. 이러한 패턴들은 소프트웨어 설계에 있어서 유용한 도구로 활용될 수 있으며, 개발자들이 검색을 통해 필요한 시점에 찾아볼 수 있습니다.

반응형