Q&A
■利用しているDartのバージョン
Dart ver: v3.56.0
■概要
これまであまりクラスのデザインパターン等を意識して利用したことがなかったのですが、sqllite
というパッケージを学んでいる際に以下のようなコードに出会いました。勉強の参考にさせていただいたQiitaの記事はこちらです。
static
や_createInstance()
周りのコードが理解できずに調べているとこれはおそらくシングルトンというクラスを作りたいのかというところに行きつきました。
ともすると、一つわからない点が生じるのですが、Dart-シングルトンの組み合わせで学んでいると、クラス内でインスタンスを生成しそのインスタンスを同じクラス内でfactory Singleton(){ return _instance;}
のようにfactory constructor
を利用しているようですが、そのようなコードは見たりません。
その一方で、DbHelper._createInstance(); //???
のように何らかのコンストラクタを呼び出しているようにも見えます。
■ご質問
- このコードはそもそもデザインパターンでいうシングルトンクラスを作ろうとしている理解であっていますか?
- そうであるとしたら、なぜ一般的なfactoryコンストラクタを使わずにこのような記述になっているのでしょうか(シンタックスシュガーか何かでしょうか?
- そうでないとしたら、どのようなデザインパターンの視点でこのコードを学べば良いのでしょうか?
よろしくお願い申し上げます。
Dart
1import 'package:flutter_crud/model/cats.dart'; 2import 'package:path/path.dart'; 3import 'package:sqflite/sqflite.dart'; 4 5// catsテーブルのカラム名を設定 6const String columnId = '_id'; 7const String columnName = 'name'; 8const String columnGender = 'gender'; 9const String columnBirthday = 'birthday'; 10const String columnMemo = 'memo'; 11const String columnCreatedAt = 'createdAt'; 12 13// catsテーブルのカラム名をListに設定 14const List<String> columns = [ 15 columnId, 16 columnName, 17 columnGender, 18 columnBirthday, 19 columnMemo, 20 columnCreatedAt, 21]; 22 23// catsテーブルへのアクセスをまとめたクラス 24class DbHelper { 25 // DbHelperをinstance化する 26 static final DbHelper instance = DbHelper._createInstance(); 27 static Database? _database; 28 29 DbHelper._createInstance(); //??? 30 31 // databaseをオープンしてインスタンス化する 32 Future<Database> get database async { 33 return _database ??= await _initDB(); // 初回だったら_initDB()=DBオープンする 34 } 35 36 // データベースをオープンする 37 Future<Database> _initDB() async { 38 String path = join(await getDatabasesPath(), 'cats.db'); // cats.dbのパスを取得する 39 40 return await openDatabase( 41 path, 42 version: 1, 43 onCreate: _onCreate, // cats.dbがなかった時の処理を指定する(DBは勝手に作られる) 44 ); 45 } 46 47 // データベースがなかった時の処理 48 Future _onCreate(Database database, int version) async { 49 //catsテーブルをcreateする 50 await database.execute(''' 51 CREATE TABLE cats( 52 _id INTEGER PRIMARY KEY AUTOINCREMENT, 53 name TEXT, 54 gender TEXT, 55 birthday TEXT, 56 memo TEXT, 57 createdAt TEXT 58 ) 59 '''); 60 } 61 62 // catsテーブルのデータを全件取得する 63 Future<List<Cats>> selectAllCats() async { 64 final db = await instance.database; 65 final catsData = await db.query('cats'); // 条件指定しないでcatsテーブルを読み込む 66 67 return catsData.map((json) => Cats.fromJson(json)).toList(); // 読み込んだテーブルデータをListにパースしてreturn 68 } 69 70// _idをキーにして1件のデータを読み込む 71 Future<Cats> catData(int id) async { 72 final db = await instance.database; 73 var cat = []; 74 cat = await db.query( 75 'cats', 76 columns: columns, 77 where: '_id = ?', // 渡されたidをキーにしてcatsテーブルを読み込む 78 whereArgs: [id], 79 ); 80 return Cats.fromJson(cat.first); // 1件だけなので.toListは不要 81 } 82 83// データをinsertする 84 Future insert(Cats cats) async { 85 final db = await database; 86 return await db.insert( 87 'cats', 88 cats.toJson() // cats.dartで定義しているtoJson()で渡されたcatsをパースして書き込む 89 ); 90 } 91 92// データをupdateする 93 Future update(Cats cats) async { 94 final db = await database; 95 return await db.update( 96 'cats', 97 cats.toJson(), 98 where: '_id = ?', // idで指定されたデータを更新する 99 whereArgs: [cats.id], 100 ); 101 } 102 103// データを削除する 104 Future delete(int id) async { 105 final db = await instance.database; 106 return await db.delete( 107 'cats', 108 where: '_id = ?', // idで指定されたデータを削除する 109 whereArgs: [id], 110 ); 111 } 112}
回答1件
下記のような回答は推奨されていません。
このような回答には修正を依頼しましょう。
2023/01/26 06:14
2023/01/26 07:11
2023/01/26 08:14
2023/01/26 08:32
2023/01/26 15:57
2023/01/26 23:21
2023/01/27 01:01