仕様理解に差が出る、些細な心遣いでViewModelは読みやすくなる

LaravelのViewModelが圧倒的にわかりやすくなる

読みづらいViewModelを見かけませんか?

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]),
        ];

読みづらいです…よね。

よく見ると, ProductSellerに分かれています。

項目が少ないので理解できますが、これ以上増えると理解しづらいですよね。

このような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(),
        ];
    }

productsellerの2構成だとわかりますよね。

これで、このViewModelはProductSellerの情報を扱っていることが伝わります。

比較すると、差は歴然ですね。

    /**
     * @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点を意識するだけで、非常に読みやすくなります。

読み手に優しいコードを意識いていくことで、開発コストは削減できます。

下記の記事もオススメです。

ぎゅう
WEBエンジニア
渋谷でWEBエンジニアとして働く。
LaravelとVue.jsをよく取り扱い、誰でも仕様が伝わるコードを書くことを得意とする。
先輩だろうがプルリクにコメントをして、リファクタしまくる仕様伝わるコード書くマン
よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメントする

目次
閉じる