Flutter 개발 Story
Factory 본문
Factory란?
Factory란 새로운 인트턴스를 생성하지 않는 생성자를 구현할 때 사용하는 키워드이다.
constructor는 매번 인스턴스를 새로 생성해 비용이 많이 발생하지만, factory는 기존에 이미 생성된 인스턴가 있다면, 그 인스턴스를 return하여 재사용한다.
즉, constructor는 생성자를 호출하면 새로운 인스턴스가 만들어지지만, factory는 생성자를 호출하면, 최초에 생성된 인스턴스를 생성자가 호출될때마다 갖다 쓰는 것이다.
constructor를 사용한 클래스는 항상 새로운 인스턴스를 리턴한다.
(Book({this.title, this.description})을 호출해 새로운 인스턴스를 리턴)
class Book {
final String title;
final String description;
Book({this.title, this.description});
}
final book = Book(...); // 항상 새로운 Book 인스턴스를 생성한다.
아래 코드에서 Logger()가 호출될 때마다 Logger factory 생성자가 호출된다. 만약 Logger('flutter')를 처음 호출하면 _*cache에 없으니 Logger.*internal('flutter') 으로 인스턴스를 새로 생성하여 반환한다(1번). 새로 생성된 인스턴스는 _cache에 저장된다(2번). 한 번 더 호출하면 _cache에 인스턴스가 있으니 기존 인스턴스를 반환한다.
아래 코드를 살펴보자.
아래 코드에서는 Logger()가 호출될 때마다 Logger factory 생성자가 호출된다.
만약 Logger('flutter')를 처음 호출하면, _*cache에 없으니 Logger.*internal('flutter')로 인스턴스를 생성하여 반환한다.
새로 생성된 인스턴스는 _cache에 저장된다.
한 번 더 호출하면 _cache에 인스턴스가 있으니 기존 인스턴스를 반환한다.
class Logger {
final String name;
bool mute = false;
static final Map<String, Logger> _cache =
<String, Logger>{};
// 1번
factory Logger(String name) {
return _cache.putIfAbsent( // 2번
name, () => Logger._internal(name));
}
factory Logger.fromJson(Map<String, Object> json) {
return Logger(json['name'].toString());
}
Logger._internal(this.name);
void log(String msg) {
if (!mute) print(msg);
}
}
factory는 서브클래스의 인스턴스를 반환할 때도 사용할 수 있다고 했다. 아래는 Book 클래스의 서브클래스인 ComicBook의 인스턴스를 반환하는 코드이다. 추가로 contructor와 factory는 아래처럼 named 생성자를 사용할 수 있다.
class Book {
// named generative
Book.comic(String title) : this(title, "Champ");
// named factory
factory Book.comic(String title) {
return ComicBook(title);
}
}
class ComicBook extends Book {
ComicBook(String title) : super(title, "Champ");
}
class DBHelper{
//3.인스턴스를 하나만 생성하도록 한다.
//메모리를 하나로 설정해서 고정적으로 불러서 사용할 것이기 때문에 static 인스턴스 선언
//캡슐화해서 외부로부터 속성들을 보호하기 위해 private 인스턴스 선언
//1번에서 외부로부터 생성되는 것을 방지하지 못했기 때문에 final로 런타임시 초기화
//멀티스레드 이용시 새로운 싱글톤 인스턴스가 생성이 될 것을 방지하기 위해 static으로 메모리를
//할당받자 마자 인스턴스를 생성해 집어 넣기
static final DbHelper _dbHelper = DbHelper._internal();
//2.하나 밖에 없는 생성자를 외부에서 생성못하게 namedConstructor로 캡슐화한다.
DbHelper._internal();
//1.인스턴스를 1개만 생성할 수 있도록 클랙스에 factory 생성자를 만든다.
factory DbHelper() => _dbHelper;
...
}
생성자
- 생성자는 클래스와 이름이 같음
- 생성자에는 반환 유형이 없음
- 생성자는 객체가 생성될 때 자동으로 호출됨
- 생성자를 지정하지 않으면, 인수가 없는 기본 생성자가 생성됨.
싱글톤 패턴
- 전역 변수를 사용하지 않고 객체를 하나만 생성하여, 생성된 객체를 어디에서든지 참조할 수 있도록 하는 패턴
- 생성자가 여러 차례 호출되더라도 실제로 생성되는 객체는 하나이고, 최초 생성 이후에 호출된 생성자는 최초의 생성자가 생성한 객체를 리턴
(객체 하나를 생성해 그 객체만 사용하는 패턴)
Named Constructor
- named constructor는 동일한 클래스에 여러 생성자를 만들 수 있음.
- 각 생성자는 고유한 이름을 갖으며, 그들 각각을 식별할 수 있다.
-> 여러 생성자를 만들고 각 생성자를 처리할 수 있게 됨.
예제)
아래의 코드에서 named construcutor는 Employee.ID(), Employee.name(), Employee.department()임.
class Employee {
int empID;
String empName;
String empDept;
Employee.ID(this.empID); // Named Constructor Creation
Employee.name(this.empName);
Employee.department(this.empDept);
}
main() {
var myEmployee01 = new Employee.ID(15);
var myEmployee02 = new Employee.department("Testing");
var myEmployee03 = new Employee.name("Ashu");
print(myEmployee01.empID);
print(myEmployee02.empDept);
print(myEmployee03.empName);
}
Output
15
Testing
Ashu
참고글
https://another-light.tistory.com/77
https://medium.com/jay-tillu/constructors-in-dart-4f972186c372
'Flutter' 카테고리의 다른 글
MethodChannel (0) | 2021.05.26 |
---|---|
Isolate vs Thread (0) | 2021.05.26 |
Flutter _ Retrofit (0) | 2021.05.24 |
위젯) SingleChildScrollView (0) | 2021.05.11 |
Flutter BLE 다루기 (0) | 2021.04.30 |