본문 바로가기

개발 언어별 10대(주관적) 디자인 패턴 소개 및 샘플

출입금지 발행일 : 2023-03-06

디자인 패턴 소개 및 샘플

디자인 패턴 소개 및 샘플
개발 언어별 디자인 패턴

1. Singleton Pattern (싱글턴 패턴)

  • 설명: 어떤 클래스가 최초 한 번만 메모리를 할당하고 그 메모리에 객체를 만들어 사용하는 패턴입니다. 이후에는 생성된 객체를 계속해서 반환하여 사용합니다. 이 패턴을 이용하면, 전역 변수를 사용하지 않고 객체를 공유하여 사용할 수 있습니다.
  • 예시 코드 (Java)
public class Singleton {
    private static Singleton instance = null;

    private Singleton() {}

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

2. Factory Pattern (팩토리 패턴)

  • 설명: 객체를 생성하는 인터페이스를 정의하고, 인스턴스화할 클래스를 서브 클래스에서 결정하는 패턴입니다.
  • 예시 코드 (Python)
class Shape:
    def draw(self):
        pass

class Circle(Shape):
    def draw(self):
        print("Circle.draw")

class Square(Shape):
    def draw(self):
        print("Square.draw")

class ShapeFactory:
    @staticmethod
    def createShape(shape_type):
        if shape_type == "Circle":
            return Circle()
        elif shape_type == "Square":
            return Square()
        else:
            return None

3. Observer Pattern (옵저버 패턴)

  • 설명: 객체 간의 일대다 의존 관계를 정의하여, 객체의 상태 변화를 관찰하는 패턴입니다.
  • 예시 코드 (C#)
interface IObserver {
    void Update();
}

interface ISubject {
    void Attach(IObserver observer);
    void Detach(IObserver observer);
    void Notify();
}

class ConcreteSubject : ISubject {
    private List<IObserver> observers = new List<IObserver>();
    private int state;

    public void Attach(IObserver observer) {
        observers.Add(observer);
    }

    public void Detach(IObserver observer) {
        observers.Remove(observer);
    }

    public void Notify() {
        foreach (var observer in observers) {
            observer.Update();
        }
    }

    public int State {
        get { return state; }
        set {
            state = value;
            Notify();
        }
    }
}

class ConcreteObserver : IObserver {
    private string name;
    private int observerState;
    private ConcreteSubject subject;

    public ConcreteObserver(string name, ConcreteSubject subject) {
        this.name = name;
        this.subject = subject;
    }

    public void Update() {
        observerState = subject.State;
        Console.WriteLine($"Observer {name} state is now {observerState}");
    }
}

4. Adapter Pattern (어댑터 패턴)

  • 설명: 서로 다른 두 인터페이스를 맞추어, 클래스들이 함께 동작하도록 만드는 패턴입니다.
  • 예시 코드 (Java)
interface Target {
    void request();
}

class Adaptee {
    public void specificRequest() {
        System.out.println("Adaptee.specificRequest");
    }
}

class Adapter implements Target {
    private Adaptee adaptee;

    public Adapter(Adaptee adaptee) {
        this.adaptee = adaptee;
    }

    public void request() {
        adaptee.specificRequest();
    }
}

 

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

  • 설명: 객체에 추가적인 요건을 동적으로 첨가하며, 기능 확장이 용이한 패턴입니다.
  • 예시 코드 (C++)
class Component {
public:
    virtual void operation() = 0;
};

class ConcreteComponent : public Component {
public:
    void operation() {
        std::cout << "ConcreteComponent.operation" << std::endl;
    }
};

class Decorator : public Component {
protected:
    Component* component;

public:
    Decorator(Component* component) {
        this->component = component;
    }

    void operation() {
        component->operation();
    }
};

class ConcreteDecoratorA : public Decorator {
public:
    ConcreteDecoratorA(Component* component) : Decorator(component) {}

    void operation() {
        Decorator::operation();
        std::cout << "ConcreteDecoratorA.operation" << std::endl;
    }
};

class ConcreteDecoratorB : public Decorator {
public:
    ConcreteDecoratorB(Component* component) : Decorator(component) {}

    void operation() {
        Decorator::operation();
        std::cout << "ConcreteDecoratorB.operation" << std::endl;
    }
};

 

6. Strategy Pattern (전략 패턴)

  • 설명: 동일한 문제를 해결하는 여러 알고리즘이 클래스별로 캡슐화되어 있고, 이들이 필요할 때 교체될 수 있도록 하는 패턴입니다.
  • 예시 코드 (JavaScript)
class Context {
    constructor(strategy) {
        this.strategy = strategy;
    }

    setStrategy(strategy) {
        this.strategy = strategy;
    }

    executeStrategy() {
        this.strategy.execute();
    }
}

class ConcreteStrategyA {
    execute() {
        console.log("ConcreteStrategyA.execute");
    }
}

class ConcreteStrategyB {
    execute() {
        console.log("ConcreteStrategyB.execute");
    }
}

7. Template Method Pattern (템플릿 메소드 패턴)

  • 설명: 알고리즘의 구조를 메소드에 정의하고, 하위 클래스에서 알고리즘 구조의 변경 없이 알고리즘을 재정의하는 패턴입니다.
  • 예시 코드 (C#)
abstract class AbstractClass {
    public void TemplateMethod() {
        PrimitiveOperation1();
        PrimitiveOperation2();
    }

    public abstract void PrimitiveOperation1();
    public abstract void PrimitiveOperation2();
}

class ConcreteClass : AbstractClass {
    public override void PrimitiveOperation1() {
        Console.WriteLine("ConcreteClass.PrimitiveOperation1");
    }

    public override void PrimitiveOperation2() {
        Console.WriteLine("ConcreteClass.PrimitiveOperation2");
    }
}
 

8. Iterator Pattern (반복자 패턴)

  • 설명: 컬렉션의 요소를 순차적으로 접근하는 객체를 만드는 패턴입니다.
  • 예시 코드 (Java)
interface Iterator<T> {
    boolean hasNext();
    T next();
}

interface Aggregate<T> {
    Iterator<T> createIterator();
}

class ConcreteAggregate<T> implements Aggregate<T> {
    private List<T> items = new ArrayList<T>();

    public void addItem(T item) {
        items.add(item);
    }

    public Iterator<T> createIterator() {
        return new ConcreteIterator<T>(items);
    }
}

class ConcreteIterator<T> implements Iterator<T> {
    private List<T> items;
    private int position = 0;

    public ConcreteIterator(List<T> items) {
        this.items = items;
    }

    public boolean hasNext() {
        return position < items.size();
    }

    public T next() {
        T item = items.get(position);
        position++;
        return item;
    }
}

9. Factory Method Pattern (팩토리 메소드 패턴)

  • 설명: 객체를 생성하는 인터페이스를 정의하고, 이를 하위 클래스에서 구현하는 패턴입니다. 팩토리 메소드 패턴을 사용하면 객체 생성을 캡슐화하여, 클라이언트 코드에서 객체 생성에 대한 구체적인 클래스를 분리할 수 있습니다.
  • 예시 코드 (Python)
from abc import ABC, abstractmethod

class Product(ABC):
    @abstractmethod
    def operation(self):
        pass

class ConcreteProductA(Product):
    def operation(self):
        print("ConcreteProductA.operation")

class ConcreteProductB(Product):
    def operation(self):
        print("ConcreteProductB.operation")

class Creator(ABC):
    @abstractmethod
    def factory_method(self) -> Product:
        pass

    def some_operation(self) -> str:
        product = self.factory_method()
        result = f"Creator: {product.operation()}"
        return result

class ConcreteCreatorA(Creator):
    def factory_method(self) -> Product:
        return ConcreteProductA()

class ConcreteCreatorB(Creator):
    def factory_method(self) -> Product:
        return ConcreteProductB()

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

  • 설명: 객체에 추가적인 요건을 동적으로 첨가할 수 있는 패턴입니다. 데코레이터를 사용하면, 서브클래스를 만드는 것보다 유연하게 객체에 기능을 추가할 수 있습니다.
  • 예시 코드 (Java)
interface Component {
    void operation();
}

class ConcreteComponent implements Component {
    public void operation() {
        System.out.println("ConcreteComponent.operation");
    }
}

abstract class Decorator implements Component {
    protected Component component;

    public Decorator(Component component) {
        this.component = component;
    }

    public void operation() {
        component.operation();
    }
}

class ConcreteDecoratorA extends Decorator {
    public ConcreteDecoratorA(Component component) {
        super(component);
    }

    public void operation() {
        super.operation();
        System.out.println("ConcreteDecoratorA.operation");
    }
}

class ConcreteDecoratorB extends Decorator {
    public ConcreteDecoratorB(Component component) {
        super(component);
    }

    public void operation() {
        super.operation();
        System.out.println("ConcreteDecoratorB.operation");
    }
}

 

 

  상기 10대 패턴은 제가 공부 하면서 느꼈던 10대 디자인 패턴일 뿐입니다. ChatGPT에서 코딩을 서포트 하면서 결국은 개발자 본연의 학습이 필요 하지 않을까 싶어서 .. 예전에 공부했던 내용을 리마인드 하고 있습니다.

 

다음주 부터는 각각 패턴들의 추가 설명 및 예제를 다루어 보도록 하겠습니다.

반응형

댓글