117 lines
5 KiB
YAML
117 lines
5 KiB
YAML
uuid:
|
|
- value: 12fb6cce-1f55-4359-b189-700c8ba16935
|
|
langcode:
|
|
- value: en
|
|
type:
|
|
- target_id: daily_email
|
|
target_type: node_type
|
|
target_uuid: 8bde1f2f-eef9-4f2d-ae9c-96921f8193d7
|
|
revision_timestamp:
|
|
- value: '2025-05-11T09:00:38+00:00'
|
|
revision_uid:
|
|
- target_type: user
|
|
target_uuid: b8966985-d4b2-42a7-a319-2e94ccfbb849
|
|
revision_log: { }
|
|
status:
|
|
- value: true
|
|
uid:
|
|
- target_type: user
|
|
target_uuid: b8966985-d4b2-42a7-a319-2e94ccfbb849
|
|
title:
|
|
- value: |
|
|
Services vs Actions
|
|
created:
|
|
- value: '2023-07-05T00:00:00+00:00'
|
|
changed:
|
|
- value: '2025-05-11T09:00:38+00:00'
|
|
promote:
|
|
- value: false
|
|
sticky:
|
|
- value: false
|
|
default_langcode:
|
|
- value: true
|
|
revision_translation_affected:
|
|
- value: true
|
|
path:
|
|
- alias: /daily/2023/07/05/services-vs-actions
|
|
langcode: en
|
|
body:
|
|
- value: |
|
|
<p>When creating a custom module, where do you put your business logic?</p>
|
|
|
|
<p>You want to keep classes like Controllers and Commands simple and move any reusable logic into separate files.</p>
|
|
|
|
<p>Usually, this means 'Service' classes, but another approach I like is to use 'Action' classes.</p>
|
|
|
|
<h2 id="what-is-an-action-class%3F">What is an Action class?</h2>
|
|
|
|
<p>An Action is a PHP class representing a single action that must be performed.</p>
|
|
|
|
<p>It usually contains a single method with a descriptive name summarising the task, such as <code>GetAccessToken</code>.</p>
|
|
|
|
<p>This differs from a generic service like <code>ApiService</code> with multiple methods like <code>getAccessToken()</code>.</p>
|
|
|
|
<h2 id="using-action-classes">Using Action classes</h2>
|
|
|
|
<p>I'll register Action classes in the service container to use dependency injection and autowiring and easily inject the Action into other classes that need it, like Controllers and Commands.</p>
|
|
|
|
<p>If you need multiple implementations, multiple actions can implement the same Interface and make them swappable, such as having <code>GetAccessToken</code> and <code>GetAndCacheAccessToken</code> implement the same <code>GetsAccessToken</code> interface.</p>
|
|
|
|
<p>That also enables using design patterns like Decorators with Actions.</p>
|
|
|
|
<h2 id="why-i-like-actions">Why I like Actions</h2>
|
|
|
|
<p>I like more readable and meaningful class names and prefer working with multiple simpler classes than those with fewer complex ones.</p>
|
|
|
|
<p>I like leveraging design patterns I'm used to, such as the Decorator pattern, by having common interfaces and contracts.</p>
|
|
|
|
<p>I like that if I need to add another implementation, I can add it without changing the existing code, so it follows the SOLID principles.</p>
|
|
|
|
<h2 id="what-about-you%3F">What about you?</h2>
|
|
|
|
<p>Do you use Action classes in your code, or do you use Services or something else?</p>
|
|
|
|
<p>Reply to this email and let me know.</p>
|
|
|
|
|
|
format: full_html
|
|
processed: |
|
|
<p>When creating a custom module, where do you put your business logic?</p>
|
|
|
|
<p>You want to keep classes like Controllers and Commands simple and move any reusable logic into separate files.</p>
|
|
|
|
<p>Usually, this means 'Service' classes, but another approach I like is to use 'Action' classes.</p>
|
|
|
|
<h2 id="what-is-an-action-class%3F">What is an Action class?</h2>
|
|
|
|
<p>An Action is a PHP class representing a single action that must be performed.</p>
|
|
|
|
<p>It usually contains a single method with a descriptive name summarising the task, such as <code>GetAccessToken</code>.</p>
|
|
|
|
<p>This differs from a generic service like <code>ApiService</code> with multiple methods like <code>getAccessToken()</code>.</p>
|
|
|
|
<h2 id="using-action-classes">Using Action classes</h2>
|
|
|
|
<p>I'll register Action classes in the service container to use dependency injection and autowiring and easily inject the Action into other classes that need it, like Controllers and Commands.</p>
|
|
|
|
<p>If you need multiple implementations, multiple actions can implement the same Interface and make them swappable, such as having <code>GetAccessToken</code> and <code>GetAndCacheAccessToken</code> implement the same <code>GetsAccessToken</code> interface.</p>
|
|
|
|
<p>That also enables using design patterns like Decorators with Actions.</p>
|
|
|
|
<h2 id="why-i-like-actions">Why I like Actions</h2>
|
|
|
|
<p>I like more readable and meaningful class names and prefer working with multiple simpler classes than those with fewer complex ones.</p>
|
|
|
|
<p>I like leveraging design patterns I'm used to, such as the Decorator pattern, by having common interfaces and contracts.</p>
|
|
|
|
<p>I like that if I need to add another implementation, I can add it without changing the existing code, so it follows the SOLID principles.</p>
|
|
|
|
<h2 id="what-about-you%3F">What about you?</h2>
|
|
|
|
<p>Do you use Action classes in your code, or do you use Services or something else?</p>
|
|
|
|
<p>Reply to this email and let me know.</p>
|
|
|
|
|
|
summary: null
|
|
field_daily_email_cta: { }
|