LaravelでViewModelを利用していますが、読みづらいViewModelが非常に多い印象です。
わかりやすいViewModelがなぜ必要?
入れ替わりが激しいIT業界なので、開発メンバーもよく変わります。
新規メンバーはまずコードを読み込む時間が必要です。
仕様がわからない以上、プロダクトのイメージを掴めず、実装イメージが思い浮かばないためです。
ということは、新規メンバーの仕様理解が追いつくまで、開発スピードは遅れます。
そのため、我々エンジニアは仕様理解できるコードを求められます。
なので当然、ViewModelもわかりやすく書く必要があります。
とはいえ、難しく考える必要はありません。
ある工夫をするだけで、非常に読みやすくなります。
ということで今回、そのViewModelの工夫を解説します!
読みづらいViewModelの例
早速ですが、読みづらいViewModelを見てみましょう!
/**
* 製品情報のViewModel
*/
class ProductViewModel extends ViewModel
{
private Product $product;
public function __construct(Product $product)
{
$this->product = $product;
}
/**
* @inheritDoc
*/
public function toMap(): array
{
return [
'product_number' => $this->product->product_number,
'product_name' => $this->product->name,
'product_detail' => $this->product->detail,
'product_price' => $this->product->price,
'product_size' => $this->product->size,
'product_published_at' => $this->product->published_at,
'product_seller_name' => $this->product->seller->name,
'product_seller_email' => $this->product->seller->email,
'product_seller_link' => route('seller.show', ['uuid' => $this->product->seller->uuid]),
];
}
}
パッとみて何の情報が書かれているか、わかりますか?
return [
'product_number' => $this->product->product_number,
'product_name' => $this->product->name,
'product_detail' => $this->product->detail,
'product_price' => $this->product->price,
'product_size' => $this->product->size,
'product_published_at' => $this->product->published_at,
'product_seller_name' => $this->product->seller->name
'product_seller_email' => $this->product->seller->email,
'product_seller_link' => route('seller.show', ['uuid' => $this->product->seller->uuid]),
];
読みづらいです…よね。
よく見ると, Product
と Seller
に分かれています。
項目が少ないので理解できますが、これ以上増えると理解しづらいですよね。
このようなViewModelだと、仕様理解に時間がかかってしまいます。
そこで、わかりやすく分割してあげます。
読みやすいViewModelの例
次に、わかりやすいViewModelを見てみましょう!
/**
* 製品情報のViewModel
*/
class ProductViewModel extends ViewModel
{
private Product $product;
public function __construct(Product $product)
{
$this->product = $product;
}
/**
* @inheritDoc
*/
public function toMap(): array
{
return [
...$this->product(),
...$this->seller(),
];
}
/**
* 製品情報
*
* @return array
*/
private function product(): array
{
return [
'product_number' => $this->product->product_number,
'product_name' => $this->product->name,
'product_detail' => $this->product->detail,
'product_price' => $this->product->price,
'product_size' => $this->product->size,
'product_published_at' => $this->product->published_at,
];
}
/**
* 販売者情報
*
* @return array
*/
private function seller(): array
{
return [
'product_seller_name' => $this->product->seller->name,
'product_seller_email' => $this->product->seller->email,
'product_seller_link' => route('seller.show', ['uuid' => $this->product->seller->uuid]),
];
}
}
かなり読みやすくなりました。
下記の部分に注目してください。
/**
* @inheritDoc
*/
public function toMap(): array
{
return [
...$this->product(),
...$this->seller(),
];
}
product
とseller
の2構成だとわかりますよね。
これで、このViewModelはProduct
とSeller
の情報を扱っていることが伝わります。
/**
* @inheritDoc
*/
public function toMap(): array
{
return [
...$this->product(),
...$this->seller(),
];
}
/**
* @inheritDoc
*/
public function toMap(): array
{
return [
'product_number' => $this->product->product_number,
'product_name' => $this->product->name,
'product_detail' => $this->product->detail,
'product_price' => $this->product->price,
'product_size' => $this->product->size,
'product_published_at' => $this->product->published_at,
'product_seller_name' => $this->product->seller->name,
'product_seller_email' => $this->product->seller->email,
'product_seller_link' => route('seller.show', ['uuid' => $this->product->seller->uuid]),
];
}
さらにPHPDocによるコメントを追加されたことで、日本語でも説明されています。
/**
* 製品情報
*
* @return array
*/
private function product(): array
{
...
}
/**
* 販売者情報
*
* @return array
*/
private function seller(): array
{
...
}
これだけ書かれていれば、初めて読んだ方でもViewModelの構成が理解できます。
まとめ
- ViewModelの配列は分割して、スプレッド構文でマージしよう!
- 分割した配列はメソッド分けして、PHPDocなどのコメントで解説しよう!
- インデントを揃えてわかりやすくしよう!
上記3点を意識するだけで、非常に読みやすくなります。
読み手に優しいコードを意識いていくことで、開発コストは削減できます。
コメント