この記事は ex-crowdworks Advent Calendar 2024の14日目の記事です。
はじめに
今年、株式会社クラウドワークスを退職した@nisyuuです。寒くなってきたのでこたつを出しました。
エンジニアとしてクラウドワークステック(旧クラウドテック)というフリーランスと企業をマッチングするエージェントサービスを開発していました。
Ruby on Railsを利用してアプリを開発していると、ビューロジックが調整されていないため、コードが複雑になる場合があります。
そのような場面で、PresenterやDecoratorの機構を使用することでコードをクリーンにし、管理しやすくすることができます。
本記事では、PresenterとDecoratorの基本的な概念について紹介し、それぞれのメリット、デメリット、実装例を見ていきます。
Presenterとは
Presenterは、モデルに属する表示ロジックを隠蔽するためのクラスです。ビューの責務を分離し、ビューのロジックをコントローラから切り離すことができます。
Presenterのメリットとデメリット
メリット
- ロジックを分離することでコードの読みやすさが向上する
- ビューロジックがモデルに依存しなくなる
デメリット
- 新たなクラスを追加するため、プロジェクトが複雑に見える可能性がある
- 実装コストが増える
Presenterの実装例
下記は、Presenterを実装するための基本的なコード例です。
class ProductPresenter
def initialize(product)
@product = product
end
def display_price
"\#{formatted_price}"
end
def stock_status
@product.stock > 0 ? 'In Stock' : 'Out of Stock'
end
private
def formatted_price
sprintf('%.2f', @product.price)
end
attr_reader :product
end
Decoratorとは
Decoratorは、コンポーネントの機能を拡張するために使用され、クラスの負担を小さくし、純粋な機能に集中することができます。
Railsではactive_decorator
gemが普及しており、それを利用することが推奨されます。
Decoratorのメリットとデメリット
メリット
- ロジックを再利用しながら、モデルの機能を拡張できる
- コンポーネントを実装している程度でビューへのロジック転射を調整できる
デメリット
- 実装するにはDecoratorに関する十分な知識が必要
- コンポーネントを拡張しすぎると、利用性が低下する可能性がある
Decoratorの実装例
下記はactive_decorator
gemを使用したDecoratorの基本的なコード例です。
class UserDecorator < Draper::Decorator
delegate_all
def formatted_name
"#{object.first_name} #{object.last_name}".titleize
end
end
Helperを使わずにPresenterとDecoratorを使う理由
RailsのHelperは、ビュー内のロジックを簡潔に記述するための便利な機能ですが、以下のような理由でPresenterやDecoratorを使うことが推奨される場合があります。
再利用性の向上
Helperはビューごとに特化した内容になりがちで、再利用が難しいことがあります。PresenterやDecoratorを使用することで、モデルに紐づくロジックを再利用可能な形で整理できます。
テストのしやすさ
Helperは一般的にテストが困難ですが、PresenterやDecoratorは独立したクラスであるため、単体テストが容易です。
コードの可読性の向上
Helperにロジックを詰め込みすぎると可読性が低下する場合があります。PresenterやDecoratorを導入することで、ロジックを整理し、コードの構造を明確にできます。
責務の分離
Presenterは表示ロジック、Decoratorはモデルの拡張といったように、役割が明確になります。これにより、コード全体の責務が分離され、管理しやすくなります。
おわりに
PresenterとDecoratorは、Railsアプリを深いレベルでカスタマイズするための重要な機構です。Presenterはビューロジックを分離し、Decoratorはモデルの機能を拡張するという個別の役割を持っています。これらを適切に使い分けることで、コードの読みやすさや保守性も高められるでしょう。