امیر صالحی
امیر صالحی
خواندن ۲ دقیقه·۱۲ روز پیش

دیزاین safe قسمت اول - هرگز null برنگردون

مقدمه نداریم چون وقت نداریم

توی پروژه هاتون اگه یه سری بزنید حتما میبینید که یک سری از متد ها دو نوع return type دارن، مثال زیر رو نگاه کنید.

public function get(string $imdbID): ?Movie { }


اگه به کد بالا دقت کنید میبینید که هم داره Movie میگردونه و هم داره null بر میگردونه (علامت سوال ? نشون دهنده اینکه میتونه null برگردونه)

مشکلش چیه؟

زمانی که شما در return یک method دارید null برمیگردونید در حقیقت دارید هندل کردن اینکه اصلا resultی بوده یا نه رو میندازید گردن client، شاید از خودتون سوال بپرسید که client کیه؟ کلاینت میشه جایی که این کد داره استفاده میشه، برای مثال:

class MovieController { public function __construct(private MovieService $movieService) { } public function get(MovieRequest $request) { $imdbID = $request->get('imdb_id'); $movie = $this->movieService->get($imdbID); if (is_null($movie)){ // Not found } return $movie } }

همونطور که در کل بالا پیداست جایی که داره از سرویس MovieService استفاده میشه یک Controllerهه که توی متد get این controller داره getش صدا زده میشه، حالا اگه دقت کنید یه شرط گذاشته شده که اگه null بود چی کار کنه و اگه null نبود چی کار بکنه.

این باعث میشه که دیزاینی که ما داریم برای کدمون انجام میدیم از safe بودنش بزنه و خطا کردن رو راحت میکنه.

راه حل چیه؟

چک کردن اینکه آیا Movie هست یا نه رو بر عهده سرویس بزارید و اگه نبود Exception بده، توی یه پست دیگه راجب Command method و Query method ها صحبت میکنم

/** * @throws MovieApplicationException */ public function get(string $imdbID): Movie { $movie = $this->movieRepository->findByIMDBID($imdbID); if (is_null($movie)) { throw MovieApplicationException::couldNotFindMovie(); } return $movie; }

و سمت client هم به شکل زیر میشه

public function get(MovieRequest $request): Response { $imdbID = $request->get('imdb_id'); try { $movie = $this->movieService->get($imdbID); } catch (BusinessException $exception) { return JsonResponse::unprocessableEntity($exception->getMessage()); } return JsonResponse::ok('', [ 'title' => $movie->title, 'language' => $movie->language, 'country' => $movie->country, 'poster' => $movie->poster, 'url' => $movie->url, 'imdbRating' => $movie->imdb_rating, 'imdbID' => $movie->imdb_id, 'imdbVotes' => $movie->imdb_votes, ]); }

برای safe کردن دیزاین یک کد کارهای بیشتری میشه انجام داد که به مرور توی نوشته های بعدی دربارش صحبت میکنم

خلاصه

به جای null برگردوندن exception پرت کن

safe designoopnullexceptiongt movie
علاقه مند به دنیای استارت آپ و توسعه فردی
شاید از این پست‌ها خوشتان بیاید