Philocode – Telegram
تعریف‌کردن کلاس‌ها به صورت final، چرا؟

اگه کلمۀ کلیدی final رو به کلاسی اضافه کنیم، امکان extendکردن اون کلاس وجود نخواهد داشت.

مثال:
<?php
final class A {}
class B extends A {}
خروجی:
PHP Fatal error: Class B may not inherit from final class (A)

می‌فرمایند که composition راه بهتر و منعطف‌تری از inheritance ــــه (همیشه؟)، برای همین وقتی ترجیحمون استفاده از final باشه، راه inheritance رو می‌بندیم و کسانی که با کلاس کار دارند می‌فهمند که باید به جای inheritance و overrideکردن، دنبال راه دیگه‌ای برای تغییر رفتار کلاس باشند و به نحوی اونها رو به اجرای اصل Composition over inheritance سوق می‌دیم.

برای مطالعۀ بیشتر، این لینک‌هارو داشته باشید:
https://matthiasnoback.nl/2018/09/final-classes-by-default-why
https://en.wikipedia.org/wiki/Composition_over_inheritance
https://medium.com/@orhanobut/favor-composition-over-inheritance-a3e5462d01f5
https://stackoverflow.com/questions/32308276/when-to-favor-inheritance-over-composition
👍3
کد بالا، اصطلاحاً tight coupling داره و کد ما شدیداً به کلاس Facebook درهم‌تنیده شده. اگه مثل کد پایین از dependency injection استفاده کنیم، به loose coupling می‌رسیم و خیلی راحت میشه در هنگام تست‌نوشتن، یه mock رو به جای اون سرویس واقعی پاس داد و بقیۀ منطق کلاس رو تست کرد. از طرفی اصل دوم و پنجم SOLID رو رعایت کردیم و می‌تونیم هر سرویس دیگه‌ای مثل Twitter رو بدون تغییردادن این کلاس وارد ماجرا کنیم و انعطاف کلاس Publisher رو حفظ کنیم.

حمله‌ای؟ نظری؟ سوالی؟
👍1
از زیبایی‌های Typenoscript:

interface Todo {
noscript: string;
}

const todo: Readonly<Todo> = {
noscript: "Delete inactive users",
};

todo.noscript = "Hello";

⛔️ Cannot assign to 'noscript' because it is a read-only property.
👍1
Philocode
از زیبایی‌های Typenoscript: interface Todo { noscript: string; } const todo: Readonly<Todo> = { noscript: "Delete inactive users", }; todo.noscript = "Hello"; ⛔️ Cannot assign to 'noscript' because it is a read-only property.
البته توی PHP هم می‌تونیم مثل این رو داشته باشیم، ولی از Utility Typeها خبری نیست و باید داخل خود کلاس تعریف بشه:

class Developer
{
public readonly name;
}

$developer = new Developer();
$developer->name = 'John';

⛔️ Error: Cannot modify readonly property Developer::$name...

اینطوری بیرون از آبجکت نمی‌شه پراپرتی‌هارو تغییر داد.
👍1
Philocode
تعریف‌کردن کلاس‌ها به صورت final، چرا؟ اگه کلمۀ کلیدی final رو به کلاسی اضافه کنیم، امکان extendکردن اون کلاس وجود نخواهد داشت. مثال: <?php final class A {} class B extends A {} خروجی: PHP Fatal error: Class B may not inherit from final class (A) می‌فرمایند…
استثنایی که برای این می‌تونه وجود داشته باشه، دیزاین پترن Template ــــه.

این مثال رو بیبنید:
class SomeJob
{
public function handle()
{
$this->firstStep();
$this->secondStep();
$this->thirdStep();
$this->fourthStep();
}
}
مثلاً اون چهارتا متد، روی همون کلاس SomeJob تعریف شدند و هر کدوم از اونها، مرحله‌ای از انجام کاره؛ مثلاً اولی روغن می‌ریزه، دومی تخم مرغ رو اضافه می‌کنه، سومی نمک رو اضافه می‌کنه و چهارمی هم یه چیز دیگه. Template Pattern می‌گه بذارید که این مراحل قابل overrideکردن باشند، تا بشه بعضی از این مراحل رو توی کلاسی که از این کلاس ارث می‌بره، تغییر داد؛ مثلاً به جای مرحلۀ سوم که نمک می‌ریزه، مرگ موش اضافه کنه. (چه مثال دارکی)

اینجا overrideکردن جزئی از ذات این پترنه و معنی نداره با final از overrideشدنش جلوگیری کنیم!
ساختار لاراول بر اساس Technical Responsibilityهاست، بر خلاف Nest.js که پروژه رو بر حسب ماژول تقسیم می‌کنه و می‌شه بر اساس Domain Modelها پروژه رو پیش برد.
👍1😱1
حتماً دیدید که بعضی از سایت‌ها از markdown استفاده کردند و می‌شه کد زبان‌های مختلفی رو نشون داد:
```php
$sum = $a + $b;
```
ولی شاید این رو ندونید که بعضی جاها از جمله گیت‌هاب، می‌شه به تغییرات (حذف و اضافه) کد با این syntax اشاره کرد:
```diff
- old line
+ new line
```
😱5
Philocode
https://www.youtube.com/watch?v=DuB6UjEsY_Y
می‌دونستید چرا توی PHP متغیرهامون $ دارن؟
ربطی به پول‌دوست‌بودن راسموس نداره؛ صرفاً هدف این بوده که وقتی متغیر رو داخل یه string می‌ذاری، قاطی نشه! 😁
😁4
اگه می‌خوایید REST API رو خیلی عمیق بفهمید و مصاحبه‌کنندۀ بعدی رو خَجَل کنید، این چند صفحه رو بخونید:
https://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm
👍3🔥2😁1
چند سالت بود که فهمیدی می‌شه ریسپانس رو اینطوری قابل کش کرد؟ 🤭
🔥4
متد DELETE توی REST API باید idempotent باشه. یعنی اگه من صد بار این ریکوست رو بفرستم:
DELETE /api/students/45
نباید state تغییر کنه، فقط و فقط یک ریسورس (که همون دانش‌آموز کوشا و محترم شمارۀ 45 ــه) حذف می‌شه و دفعات بعدی هم اتفاق جدیدی برای ریسورس student رخ نمی‌ده و صرفاً خطای 404 برمی‌گرده.

حالا چرا این مسئله مهمه؟ برای اینکه ممکنه به دلایل عمدی یا غیر عمدی (مثل خطای شبکه)، یک ریکوست، بیشتر از یک‌بار ارسال بشه.

مثال قبلی درست بود، ولی این مثال رو ببینید:
DELETE /api/students/last
در اینجا با هر بار صدازدن، آخرین نمونه از ریسورس student حذف می‌شه و اگه ده‌بار صدا بزنیم، ده‌تا ریسورس مختلف حذف می‌شن! چنین چیزی اشتباهه، چون قرار بود که متد DELETE به صورت idempotent کار کنه!
🔥7
🔥1
👍1🤔1
😁8