⚙️

Dartのfactoryとは?

2022/04/27に公開約4,200字

Factory修飾子のついたコンストラクタのことらしい...
factoryとは🤔
直訳すると「工場」という意味です。

freezeでfactoryってのがあったような?

https://pub.dev/packages/freezed

「おっと」これは、手をつけるのは、まだ速いな😅
そもそもどんな目的で使うのか?

Flutter大学のこんぶさんが、シングルトンっていう専門用語を使っていたのを思い出した。シングルトンパターンでこのfactoryを使うみたいです。

シングルトンパターンのサンプル
main.dart

class Singleton{
  // (1) staticとしてインスタンスを事前に作成
  static final Singleton _instance = Singleton._internal();
  int _counter = 0;
  // (2) Factoryコンストラクタ
  factory Singleton(){
    return _instance;
  }
  // (3) 内部で利用する別名コンストラクタ
  Singleton._internal();

  int increment(){
    return ++_counter;
  }
}
void main(){
  // (4) 利用するコード
  var inst1 = Singleton();
  var inst2 = Singleton();

  print(inst1.increment());  // 1となる
  print(inst2.increment());  // 2となる
}

実行結果

1
2
Exited

実行した結果は、同じインスタンスしか実行されない。

自分もコードを書いてシングルトンについて学んでみて気づいたことがあった!
class Singletonを定義したら、static final Singleton、factory Singleton()、同じクラスの名前にしないと使うことができない!

参考にしたサイト

https://flutter.keicode.com/basics/data-store-singleton.php

main.dart

class WhiteList {
  // (1) staticとしてインスタンスを事前に作成
  static final WhiteList _cache = WhiteList._();
  // 空っぽの配列を用意
  final List _whiteList = <String>[];
  // (2) Factoryコンストラクタ
  factory WhiteList() {
    return _cache;
  }
  // 配列に値を入れて、戻り値として返す。
  List show() {
    return ["A社", "B社", "C社", "D社"];
  }
  // (3) 内部で利用する別名コンストラクタ
  WhiteList._();
}

void main() {
  var ins1 = WhiteList();
  var ins2 = WhiteList();
  print("ホワイト企業はどこか?");
  print(ins1.show());
  print(ins2.show());
}

実行結果

ホワイト企業はどこか?
[A社, B社, C社, D社]
[A社, B社, C社, D社]

一つのインスタンスしか生成されず、ListのString型のデータが表示された。

これが、お決まりの書き方と思っていたのだが、そうじゃないみたい。

static final Singleton _instance = Singleton._internal();
  • _instance、これは_insでも動く。自分で名前を決められる。instanceは、「例」という意味。
  • _internal();、これは _();でも構わない。_internal()という名前は慣例的なものであって、必ずしもこの名前である必要はない。internalは、「内部」という意味。
    でも、命名規則があるでしょうから、気をつけないといけないですね😅
    やっとfactoryっていうワードを理解した気がする。コンストラクターの一種か😅

コンストラクターには、種類がいっぱいあるみたいです。多すぎて覚えるの大変😵‍💫

https://dart.dev/guides/language/language-tour#constructors

追加

Flutterでサンプルプログラムを作ってみた

main.dart

import 'package:flutter/material.dart';
import 'package:singleton_sample/singleton_page/singleton_home.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  // This widget is the root of your application.
  
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const SingletonHome(),
    );
  }
}

singleton_page/singleton_home.dart

import 'package:flutter/material.dart';

class Person {
  static final Person _instance = Person._internal();

  String _name = 'Jboy';
  int _age = 33;

  factory Person() {
    return _instance;
  }

  Person._internal();

  String change() {
    return _name = 'これはペンネームだよ😌';
  }

  int incremetn() {
    return --_age;
  }
}

class SingletonHome extends StatefulWidget {
  const SingletonHome({Key? key}) : super(key: key);

  
  State<SingletonHome> createState() => _SingletonHomeState();
}

class _SingletonHomeState extends State<SingletonHome> {
  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(Person._instance._name),
      ),
      body: Container(
        child: Center(
          child: Column(
            children: [
              SizedBox(height: 20),
              Text('${Person._instance._name}'),
              SizedBox(height: 20),
              Text('Jboyさんは、${Person._instance._age}才です。'),
              SizedBox(height: 20),
              ElevatedButton(
                  onPressed: () {
                    Person._instance.change();
                    setState(() {});
                  },
                  child: Text('名前を変更')),
            ],
          ),
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          Person._instance.incremetn();
          setState(() {});
        },
        child: Icon(Icons.do_disturb_on_outlined),
      ),
    );
  }
}

Discussion

ログインするとコメントできます