1️⃣
[読書メモ]オブジェクト設計スタイルガイド 8章1節 with TypeScript
オブジェクト設計スタイルガイドを読みながら、TypeScriptでやるならどうやるかを考えながら書きました。
要約的に読める内容になっていると思うので、サクッと3分ぐらいで読める記事となっています。
8 責務の分割
8.1 リードモデルとライトモデルを分ける
リファクタ前の例
class PurchaseOrder {
private _purchaseOrderId: number;
private _productId: number;
private _quantity: number;
private _wasReceived: boolean;
private constructor() {}
// ① 簡略化のためプリミティブ型を使っているが、実際はValueObjectを使う
static place(purchaseOrderId: number, productId: number, quantity: number) {
const order = new PurchaseOrder();
order._purchaseOrderId = purchaseOrderId;
order._productId = productId;
order._quantity = quantity;
order._wasReceived = false;
return order;
}
markAsReceived() {
this._wasReceived = true;
}
get purchaseOrderId() {
return this._purchaseOrderId;
}
get productId() {
return this._productId;
}
get quantity() {
return this._quantity;
}
get wasReceived() {
return this._wasReceived;
}
}
更新時の使用例: この処理では書き込みのみに関心がある
class ReceiveItems {
private repository: repository;
constructor(repository: repository) {
this.repository = repository;
}
receiveItems(purchaseOrderId: number) {
const order = this.repository.find(purchaseOrderId);
order.markAsReceived();
this.repository.save(order);
}
}
取得時の使用例: この処理では読み込みのみに関心がある
class StockReportController {
private repository: repository;
constructor(repository: repository) {
this.repository = repository;
}
execute(request: any) {
const allOrders = this.repository.findAll();
const stockReport = {}:
allOrders.forEach((order: any) => {
if (!order.wasReceived) {
continue;
}
if (!stockReport[order.productId]) {
stockReport[order.productId] = 0;
}
stockReport[order.productId] += order.quantity;
});
return new JsonResponse(stockReport);
}
}
リファクタ: リードモデルとライトモデルを分ける
class PurchaseOrderForStockReport {
private _productId: number;
private _quantity: number;
private _wasReceived: boolean;
constructor(productId: number, quantity: number, wasReceived: boolean) {
this._productId = productId;
this._quantity = quantity;
this._wasReceived = wasReceived;
}
get productId() {
return this._productId;
}
get quantity() {
return this._quantity;
}
get wasReceived() {
return this._wasReceived;
}
}
class PurchaseOrder {
private _purchaseOrderId: number;
private _productId: number;
private _quantity: number;
private _wasReceived: boolean;
private constructor() {}
static place(purchaseOrderId: number, productId: number, quantity: number) {
const order = new PurchaseOrder();
order._purchaseOrderId = purchaseOrderId;
order._productId = productId;
order._quantity = quantity;
order._wasReceived = false;
return order;
}
markAsReceived() {
this._wasReceived = true;
}
}
Discussion