본문 바로가기
Dart/Dart Programming language

[고급] Dart고급 객체지향 프로그래밍/디자인 패턴(싱글톤, 팩토리, 옵저버 등) 적용

by Maccrey Coding 2024. 9. 10.
반응형

 

Dart는 현대적인 언어로, 객체지향 프로그래밍(OOP) 패러다임을 지원합니다.

OOP의 핵심 개념과 디자인 패턴을 잘 이해하면, 더 효율적이고 유지보수하기 쉬운 코드를 작성할 수 있습니다.

이번 블로그에서는 Dart에서 자주 사용되는 디자인 패턴인 싱글톤(Singleton), 팩토리(Factory), 옵저버(Observer) 패턴을 초보자도 쉽게 이해할 수 있도록 설명해드리겠습니다.

1. 싱글톤 패턴 (Singleton Pattern)

싱글톤 패턴은 클래스의 인스턴스가 오직 하나만 생성되도록 보장하는 패턴입니다. 이 패턴은 애플리케이션 전체에서 하나의 인스턴스만 필요할 때 유용합니다.

예를 들어, 설정 관리, 데이터베이스 연결 등이 이에 해당할 수 있습니다.

Dart에서 싱글톤 패턴 구현하기

class Singleton {
  // 클래스의 유일한 인스턴스를 저장하는 정적 변수
  static final Singleton _instance = Singleton._internal();

  // private 생성자
  Singleton._internal();

  // 외부에서 접근 가능한 인스턴스 반환
  factory Singleton() => _instance;
  
  // 예제 메서드
  void doSomething() {
    print("싱글톤 패턴 예제 메서드 호출");
  }
}

void main() {
  var singleton1 = Singleton();
  var singleton2 = Singleton();

  print(identical(singleton1, singleton2)); // true
}
  • static final Singleton _instance = Singleton._internal();
    이 줄은 Singleton 클래스의 유일한 인스턴스를 생성합니다. static은 클래스가 로드될 때 한 번만 실행되며, final은 값이 한 번만 설정된 후 변경되지 않음을 의미합니다.
  • Singleton._internal();
    이 부분은 private 생성자로, 외부에서 직접 호출할 수 없습니다. 클래스 내부에서만 호출됩니다.
  • factory Singleton() => _instance;
    factory 생성자는 기존의 인스턴스를 반환하는 역할을 합니다. 이를 통해 항상 같은 인스턴스를 반환하게 됩니다.
  • identical(singleton1, singleton2);
    identical 함수는 두 객체가 동일한 인스턴스인지 확인합니다. 이 경우, true를 출력하면 singleton1과 singleton2가 같은 인스턴스임을 의미합니다.

 

2. 팩토리 패턴 (Factory Pattern)

팩토리 패턴은 객체 생성의 책임을 별도의 팩토리 클래스에 위임하여 객체 생성의 복잡성을 줄이는 패턴입니다.

다양한 타입의 객체를 생성할 필요가 있을 때 유용합니다.

Dart에서 팩토리 패턴 구현하기

abstract class Animal {
  void makeSound();
}

class Dog implements Animal {
  @override
  void makeSound() => print("Woof");
}

class Cat implements Animal {
  @override
  void makeSound() => print("Meow");
}

class AnimalFactory {
  static Animal createAnimal(String type) {
    switch (type) {
      case 'dog':
        return Dog();
      case 'cat':
        return Cat();
      default:
        throw Exception("Unknown animal type");
    }
  }
}

void main() {
  Animal dog = AnimalFactory.createAnimal('dog');
  dog.makeSound(); // Woof

  Animal cat = AnimalFactory.createAnimal('cat');
  cat.makeSound(); // Meow
}

 

  • abstract class Animal
    Animal은 추상 클래스입니다. 추상 클래스는 인스턴스를 생성할 수 없으며, makeSound 메서드를 구현하는 서브클래스에서 구체적인 동작을 정의해야 합니다.
  • class Dog implements Animal와 class Cat implements Animal
    Dog와 Cat 클래스는 Animal을 구현합니다. 각각 makeSound 메서드를 오버라이드하여 개와 고양이의 소리를 출력합니다.
  • class AnimalFactory: AnimalFactory 클래스는 createAnimal 메서드를 통해 객체를 생성합니다. 타입에 따라 적절한 Animal 객체를 반환합니다. 타입이 'dog'일 경우 Dog 객체를, 'cat'일 경우 Cat 객체를 반환합니다.
  • Animal dog = AnimalFactory.createAnimal('dog');: AnimalFactory를 사용하여 Dog 객체를 생성합니다. makeSound 메서드를 호출하면 "Woof"가 출력됩니다.

 

3. 옵저버 패턴 (Observer Pattern)

옵저버 패턴은 주체(Subject)의 상태가 변경될 때 이를 관찰하는 옵저버들에게 자동으로 알리는 패턴입니다.

이벤트 시스템이나 UI 업데이트에서 자주 사용됩니다.

Dart에서 옵저버 패턴 구현하기

class Subject {
  List<Observer> _observers = [];

  void addObserver(Observer observer) {
    _observers.add(observer);
  }

  void removeObserver(Observer observer) {
    _observers.remove(observer);
  }

  void notifyObservers(String message) {
    for (var observer in _observers) {
      observer.update(message);
    }
  }
}

abstract class Observer {
  void update(String message);
}

class ConcreteObserver implements Observer {
  final String name;

  ConcreteObserver(this.name);

  @override
  void update(String message) {
    print('$name received message: $message');
  }
}

void main() {
  Subject subject = Subject();
  
  ConcreteObserver observer1 = ConcreteObserver('Observer 1');
  ConcreteObserver observer2 = ConcreteObserver('Observer 2');

  subject.addObserver(observer1);
  subject.addObserver(observer2);

  subject.notifyObservers('Hello, Observers!'); // Observer 1 received message: Hello, Observers!
                                              // Observer 2 received message: Hello, Observers!
}

 

  • class Subject
    Subject 클래스는 옵저버 목록을 관리합니다. addObserver 메서드는 옵저버를 추가하고, removeObserver 메서드는 옵저버를 제거합니다. notifyObservers 메서드는 모든 옵저버에게 메시지를 전달합니다.
  • abstract class Observer
    Observer는 옵저버가 구현해야 할 update 메서드를 정의하는 추상 클래스입니다.
  • class ConcreteObserver implements Observer
    ConcreteObserver는 Observer를 구현하여 update 메서드를 정의합니다. 옵저버가 메시지를 수신하면, 해당 메시지를 출력합니다.
  • subject.notifyObservers('Hello, Observers!');
    Subject는 모든 등록된 옵저버에게 'Hello, Observers!'라는 메시지를 전달합니다. ConcreteObserver 인스턴스들은 이 메시지를 받아서 출력합니다.

 

 

Dart에서의 고급 객체지향 프로그래밍 및 디자인 패턴 적용 방법을 살펴보았습니다.

싱글톤, 팩토리, 옵저버 패턴은 각각의 용도와 상황에 맞게 활용할 수 있는 강력한 도구들입니다. 이러한 패턴을 이해하고 활용하면, 더 나은 설계와 유지보수가 용이한 코드를 작성할 수 있습니다.

이 블로그가 여러분의 Dart 프로그래밍에 도움이 되었기를 바랍니다!

 

구독!! 공감과 댓글은 저에게 큰 힘이 됩니다.

Starting Google Play App Distribution! "Tester Share" for Recruiting 20 Testers for a Closed Test.

 

Tester Share [테스터쉐어] - Google Play 앱

Tester Share로 Google Play 앱 등록을 단순화하세요.

play.google.com

 

 

반응형