말랑한 하루

[Flutter] (Proejct) MapleApp: 12. Singleton Pattern 적용 본문

개발/Flutter

[Flutter] (Proejct) MapleApp: 12. Singleton Pattern 적용

지수는말랑이 2024. 1. 7. 23:12
반응형

인스턴스란, 객체 지향 프로그래밍에서 해당 클래스의 구조로 컴퓨터 저장 공간에서 할당된 실체를 의미합니다. 클래스는 속성과 행위로 구성된 일종의 설계도입니다.

 

이런 인스턴스는, 하나의 클래스에서 호출할 때마다 새롭게 생성되므로 컴퓨터 저장 공간을 지속적으로 차지하게 됩니다. 그러므로 하나의 클래스에서 하나의 인스턴스만이 생성되도록 하면 컴퓨터 내 저장 공간을 효율적으로 관리할 수 있게 된다. 또한, 언제 어디서나 인스터스를 호출해도 동일한 인스턴스를 활용할 수 있어 코드가 유연해지기 좋다.

 

우리는 이것을 Singleton이라 부른다. Singleton은 디자인 패턴 중 하나로, 오직 하나의 인스턴스를 활용한다는 목적으로 설계되었다. 이 Singleton을 Dart에서는 어떻게 구현하는지, 나는 무엇을 위해서 Singleton Pattern을 접목하려는지 써내려가려 합니다..

 

하지만 제가 사용하게 된 가장 중요한 이유는, 여러 Notifier에서 Dio 객체를 생성해서 새롭게 options를 할당하고 interceptors 추가하는 과정이 번거롭다 생각해, Dio 객체에 Singleton Pattern을 적용하려 했습니다. 이는 코드 품질을 향상 시킬 뿐만 아니라, Application을 최적화 하는데도 도움이 된다 생각했습니다.

 

🥕 Singleton Pattern in Dart

※ reference : https://dart.dev/language/constructors#factory-constructors

 

Dart에서 Singleton pattern을 적용하는 방법은 다음 예제와 함께 시작하겠습니다.

class Singleton {
	//_internal을 사용하기도 합니다. 명명 규칙은 _이외 자유입니다.
	static final SingleTon _instance 
					= Singleton._privateConstructor();
	
	//Singleton class가 생성되는 최초 1회 실행됩니다.
	Singleton._privateConstructor() {

	}
	
	factory Singleton() {
		return _instance;
	}
}

 

🍒 _internal

qna : https://stackoverflow.com/questions/57812052/the-difference-between-the-use-of-constructor-classname-and-classname

 

빈 생성자를 만드는 선언으로, Dart에서는 생성자가 없는 경우 자동으로 Public한 생성자를 만들어 버리기 때문에, private로 명명한 빈 생성자를 만들어 Dart가 자동으로 만드는 생성자를 방지합니다.

Dart에서는 underscore, _를 붙이면 Private를 의미합니다. Dart의 더 다양한 생성자를 보려면 qna를 참조하세요

 

🍒 factory

factory 키워드는 클래스의 새로운 instance를 생성하지 않는 생성자를 실행할 때 사용해야 합니다. factory 생성자는 cache에서 Instance를 반환하거나 subType의 instance를 반환할 수 있습니다. factory 생성자의 다른 사용법은 initializer list에서 처리할 수 없는 로직을 사용하여 final 변수를 초기화 하는 것입니다.

 

🥕 Singleton pattern with dio

그렇다면 학습한 내용을 dio에 적용 시켜 보겠습니다.

class DioInstance {
	static final DioIstance _instance 
				= DioInstance._internal();
	late Dio dio;

	DioInstance._internal() {
		dio = Dio();
		dio.options.baseUrl = ~;
		dio.options.headers = ~;
		dio.interceptors.add(LogIntercepter(~));
	}

	factory DioInstance() {
		return _instance;
	}
}

_internal()를 활용해서 DioInstance를 private로 생성하였고, DioInstance class가 처음 생성될 때만 _internal()가 실행되므로 Dio를 생성하고 기본 옵션을 설정해줍니다.

 

이후 우리가 queryParamters나, header를 변경하고 싶으면 DioInstance를 받아서, dio에 접근하고 options를 수정하면 됩니다.

반응형
Comments