1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【TypeScript】factory.tsのすすめ

Posted at

はじめに

  • オブジェクト生成処理がソースコードの色々な箇所に乱立して困ったことがあります。それを解決できるライブラリがあるので紹介します。

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

サンプルコード一式

おわりに

  • オブジェクト生成処理がコンパクトになり共通化出来るので再利用性が増します。
  • 重複コードを減らすことが出来ます。
  • オブジェクト生成処理が乱立しているソースコードに対してリファクタリングの一環として導入するのはいかがでしょうか。
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?