はじめに
- オブジェクト生成処理がソースコードの色々な箇所に乱立して困ったことがあります。それを解決できるライブラリがあるので紹介します。
factory.tsについて
- Factoryメソッドが簡単に作成出来るライブラリです。
- オブジェクト生成時にIDなどを連番してくれる機能なども標準搭載しています。
- オブジェクト生成時に指定プロパティの上書きも可能です。
- ネストしたオブジェクトの生成にも対応可能です。
対象読者
- 同じようなオブジェクト初期化処理が複数のソースコードに乱立して苦労している人
- テストコードのオブジェクト初期化処理が乱立して苦労している人
動作環境
- Node.js - 14.x
- TypeScript - 4.5.x
- factory.ts - 0.5.x
サンプルコード
標準パターン
src/sample1.ts
import * as Factory from 'factory.ts';
type SampleData = {
firstName: string;
lastName: string;
};
const sampleDataFactory = Factory.Sync.makeFactory<SampleData>({
firstName: 'Bob',
lastName: 'Kojima',
});
const obj = sampleDataFactory.build();
console.log(`obj - name:${obj.lastName} ${obj.firstName}`);
実行結果
obj - name:Kojima Bob
プロパティの上書き
src/sample2.ts
import * as Factory from 'factory.ts';
type SampleData = {
firstName: string;
lastName: string;
};
const sampleDataFactory = Factory.Sync.makeFactory<SampleData>({
firstName: 'Bob',
lastName: 'Kojima',
});
const obj = sampleDataFactory.build({ lastName: 'Goto' });
console.log(`obj - name:${obj.lastName} ${obj.firstName}`);
実行結果
obj - name:Goto Bob
ID連番確認
src/sample3.ts
import * as Factory from 'factory.ts';
type SampleData = {
id: number;
};
const sampleDataFactory = Factory.Sync.makeFactory<SampleData>({
id: Factory.each((i) => i),
});
const obj1 = sampleDataFactory.build();
const obj2 = sampleDataFactory.build();
console.log(`obj1 - id:${obj1.id}`);
console.log(`obj2 - id:${obj2.id}`);
実行結果
obj1 - id:0
obj2 - id:1
複数件同時生成
src/sample4.ts
import * as Factory from 'factory.ts';
type SampleData = {
id: number;
name: string;
};
const sampleDataFactory = Factory.Sync.makeFactory<SampleData>({
id: Factory.each((i) => i),
name: 'Kawamoto',
});
const items = sampleDataFactory.buildList(2);
console.log(`items[0] - id:${items[0].id}, name:${items[0].name}`);
console.log(`items[1] - id:${items[1].id}, name:${items[1].name}`);
実行結果
items[0] - id:0, name:Kawamoto
items[1] - id:1, name:Kawamoto
プロパティ追加
src/sample5.ts
import * as Factory from 'factory.ts';
type SampleData = {
id: number;
};
const sampleDataFactory = Factory.Sync.makeFactory<SampleData>({
id: Factory.each((i) => i),
});
const nameFactory = Factory.Sync.makeFactory({
name: 'Kojima',
});
const idAndNameFactory = sampleDataFactory.combine(nameFactory);
const obj = idAndNameFactory.build();
console.log(`obj - id:${obj.id}, name:${obj.name}`);
実行結果
obj - id:0, name:Kojima
Factoryをネスト
src/sample6.ts
import * as Factory from 'factory.ts';
type SampleData1 = {
name: string;
};
type SampleData2 = {
data: SampleData1;
items: SampleData1[];
};
const sampleData1Factory = Factory.Sync.makeFactory<SampleData1>({
name: 'Nagane',
});
const sampleData2Factory = Factory.Sync.makeFactory<SampleData2>({
data: sampleData1Factory.build(),
items: sampleData1Factory.buildList(2),
});
const obj = sampleData2Factory.build();
console.log(`obj.data - name:${obj.data.name}`);
console.log(`obj.items[0] - name:${obj.items[0].name}`);
console.log(`obj.items[1] - name:${obj.items[1].name}`);
実行結果
obj.data - name:Nagane
obj.items[0] - name:Nagane
obj.items[1] - name:Nagane
サンプルコード一式
おわりに
- オブジェクト生成処理がコンパクトになり共通化出来るので再利用性が増します。
- 重複コードを減らすことが出来ます。
- オブジェクト生成処理が乱立しているソースコードに対してリファクタリングの一環として導入するのはいかがでしょうか。