Вітаю/Привіт/Добрий вечір.
Ситуація:
▼Є клас "Integration"
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
final class Integration extends Model
{
protected $fillable = [
'user_id',
...
'sheet_file_id',
...
];
public function user()
{
return $this->belongsTo(User::class);
}
}
▼Є клас сповіщень
namespace App\Domain\Google;
use Closure;
use Illuminate\Support\Facades\Http;
class PushNotifications
{
public string $channelId;
public string $fileId;
public string $token;
public function __construct(string $channelId, string $fileId, string $token)
{
$this->channelId = $channelId;
$this->fileId = $fileId;
$this->token = $token;
}
public function subscribe(): array
{
return $this->request(function ($client) {
return $client->post("https://www.googleapis.com/drive/v3/files/{$this->fileId}/watch", [
'id' => $this->channelId,
'type' => 'web_hook',
'address' => route('webhook'), // todo
'expire' => 86400, // time in seconds = 1 day
]);
});
}
public function unsubscribe(): array
{
return $this->request(function ($client) {
$client->post("https://www.googleapis.com/drive/v3/channels/stop", [
'id' => $this->channelId,
'resource_id' => $this->fileId,
]);
});
}
private function request(Closure $closure)
{
$client = Http::withHeaders([
'Authorization' => "Bearer {$this->token}",
]);
$response = $closure($client);
if ($response->clientError()) {
throw new \Exception($response->json()['error']['message']);
}
return $response->json();
}
}
Ці класи пов'язані. Тому що дані з першого передаються в другий.
Це відбувається таким чином:
new PushNotifications($integration->id, $integration->sheet_file_id, $integration->user->token->access_token)
Але повторювати цей уривок коду декілька раз виглядає як невиконання принципу DRY.
Питання:
Куди можна інкапсулювати цю ініціалізацію класу на основі іншого класу?
Деякі варіанти: (можливо є інші - кращі?)
▼В клас Integration
Додати метод notifications який повертає клас сповіщень
public function notifications()
{
return new PushNotifications($this->id, $this->.........);
}
Але здається це не відповідає принципу єдиного обов'язку - тому не впевенений чи це хороший спосіб.
▼Патерн "Проста фабрика"
final class PushNotificationsFactory
{
public static function makeFromIntegration(Integration $integration): PushNotifications
{
return new PushNotifications($integration->id, $integration->........);
}
}