Anophel-آنوفل کد نویسی تمیز در لاراول | بهترین نکات و اصول

کد نویسی تمیز در لاراول | بهترین نکات و اصول

انتشار:
1
0

در توسعه وب، لاراول به عنوان یک فریمورک قدرتمند و محبوب PHP ظاهر شده است. سینتکس زیبا، ویژگی‌های غنی، و یک جامعه پر جنب و جوش آن را به انتخابی ارجح برای ساخت برنامه‌های وب تبدیل می‌کند. با این حال، نوشتن کد تمیز و قابل نگهداری در لاراول برای اطمینان از کارآمد و مقیاس پذیر بودن پروژه های شما ضروری است. در این مقاله، ما به هنر کدنویسی تمیز در لاراول می پردازیم و بهترین شیوه ها، نکات و تکنیک ها را بررسی می کنیم تا به شما در ایجاد کدهایی کمک کنیم که نه تنها کاربردی، بلکه ظریف نیز هستند.

ما در آنوفل یک مقاله درباره نوشتن کد های تمیز: بهترین روش ها و اصول ها را نیز داریم و پیشنهاد می کنیم حتما آن را نیز مطالعه کنید، در آن نیز یک سری تکنیک های عمومی برای هر زبانی را بررسی کردیم. در این مقاله ما فقط بر روی لاراول تمرکز خواهیم کرد. آشنایی با دیزاین پترن ها در لاراول نیز کمک بزرگی در کدنویسی صحیح به شما کمک بزرگی خواهد کرد.

آشنایی با Clean Code در لاراول

لاراول به سینتکس زیبا و رسا مشهور است، اما نوشتن کد تمیز فراتر از آن است. این در مورد ساختار برنامه شما به روشی است که خواندن، درک و نگهداری آسان باشد. کد تمیز شانس بروز اشکالات را کاهش می دهد، همکاری بین توسعه دهندگان را افزایش می دهد و امکان مقیاس پذیری یکپارچه را فراهم می کند.

چرا کدنویسی پاک اهمیت دارد؟

کد پاک فقط ترجیح یک توسعه دهنده نیست. این یک ضرورت است این بدهی فنی را کاهش می دهد و تغییرات و پیشرفت های آینده را ساده تر می کند. همچنین کار تیمی بهتری را تقویت می کند زیرا درک کدهای تمیز برای توسعه دهندگان آسان تر است.

درک ORM گویا لاراول

ORM Eloquent لاراول تعاملات پایگاه داده را ساده می کند. با ایجاد مدل های سازماندهی شده و بهینه سازی پرس و جوهای پایگاه داده خود برای عملکرد، از آن به طور موثر استفاده کنید.

استفاده موثر از مدل ها

مدل ها در لاراول جداول پایگاه داده را نشان می دهند. یاد بگیرید که چگونه مدل هایی ایجاد کنید که ساختار داده شما را به طور دقیق منعکس کند.

بهینه سازی کوئری های پایگاه داده

کوئری های پایگاه داده کارآمد برای سرعت برنامه بسیار مهم هستند. تکنیک هایی را برای بهینه سازی کوئری های خود کشف کنید.

لاراول را به روز نگه دارید

به روز نگه داشتن لاراول مزایای زیر را به همراه دارد:

امنیت بهبود یافته: زیرا لاراول به طور مرتب اصلاحات امنیتی را منتشر می کند.
عملکرد بهتر: به روز رسانی لاراول اغلب شامل بهبود عملکرد، مانند زمان بارگذاری سریع تر و کد کارآمدتر است.
ویژگی ها و قابلیت های جدید: به همین دلیل است که ما از لاراول استفاده می کنیم و آن را دوست داریم و دلیلی که زندگی ما را تغییر داد.
سازگاری با آخرین بسته های رسمی و جامعه.


اگر به‌روزرسانی‌های لاراول شما را می‌ترسانند، به این دلیل است که پایگاه کد شما آزمایش نشده است و این بهترین روشی است که باید اجرا کنید.

پکیج ها را به روز نگه دارید

دسترسی به ده ها پکیج از اکوسیستم رسمی لاراول و همچنین هزاران پکیج اجتماعی چیزی است که کار ما را آسان می کند.

اما هرچه پکیج های بیشتری استفاده کنید، نقاط شکست بیشتری را می توانید در معرض آن قرار دهید.

اجرای منظم به‌روزرسانی composer یکی از ساده‌ترین روش‌ها برای اتخاذ است و راه طولانی را به سمت یک پایگاه کد امن‌تر پیش می‌برد.

به ساختار پوشه بندی پیش‌فرض بچسبید

آیا می دانید چرا از یک فریمورک استفاده می کنید؟

این کار شما را با مجموعه‌ای از دستورالعمل‌ها تنظیم می‌کند که می‌توانید از آن‌ها پیروی کنید تا مطمئن شوید همه اعضای تیم شما در یک صفحه هستند.
بسیاری از ویژگی‌های پیچیده، خسته‌کننده و آزمایش‌شده در نبرد را به صورت رایگان ارائه می‌کند، بنابراین می‌توانید روی کدنویسی آنچه که مختص پروژه‌تان است تمرکز کنید.
بنابراین، آیا پایبندی به ساختار پروژه پیش‌فرض لاراول بهترین روش محسوب می‌شود؟

راحتی. روش پیش فرض لاراول برای انجام کارها مستند شده است. وقتی هفته‌ها یا ماه‌ها بعد به پروژه‌ای باز می‌گردید، از گذشته خود به خاطر این کار تشکر خواهید کرد.
کار با هم تیمی ها بسیار آسان تر است. آنها لاراول را می شناسند، درست مثل شما. از این دانش رایج برای کمک به پیشرفت پروژه به جای اختراع مجدد چرخ هر بار استفاده کنید.
چه زمانی نباید به پیش فرض ها پایبند باشید؟

زمانی که اندازه پروژه شما واقعاً مستلزم انجام کارها متفاوت است.

از policies  برای authorization استفاده کنید

استفاده ازpolicies برای مجوز در لاراول برای حفظ یک برنامه سازمان یافته و قابل نگهداری ضروری است. در اینجا سه دلیل کلیدی برای استفاده از policies وجود دارد:

استفاده مجدد از منطق مجوز در چندین کنترلر: با متمرکز کردن قوانین مجوز، می توانید از سازگاری اطمینان حاصل کنید و از تکرار کد در بخش های مختلف برنامه خود جلوگیری کنید.


بارگیری کد از کنترل‌کننده‌های متورم: انتقال منطق مجوز به خط‌مشی‌ها به کنترل‌کننده‌های شما کمک می‌کند تا بر روی مسئولیت‌های اصلی خود تمرکز کنند و خواندن و نگهداری آنها آسان‌تر باشد.


کد مربوط به مجوز را به راحتی پیدا کنید: ذخیره خط‌مشی‌ها در پوشه برنامه/خط‌مشی‌ها یافتن و به‌روزرسانی قوانین مجوز را در صورت نیاز برای توسعه‌دهندگان آسان می‌کند.

// app/Policies/PostPolicy.php
public function update(User $user, Post $post)
{
    return $user->id === $post->user_id;
}

// app/Http/Controllers/PostController.php
public function update(Request $request, Post $post)
{
    $this->authorize('update', $post);

    // ...
}

اصل تک مسئولیتی بودن

اصل تک مسئولیتی (SRP) بیان می کند که یک تابع باید یک کار را انجام دهد و آن را به خوبی انجام دهد. درک، آزمایش و نگهداری توابع کوتاه‌تر آسان‌تر است. اگر یک تابع خیلی طولانی یا پیچیده شد، آن را به توابع کوچکتر و قابل مدیریت تقسیم کنید.پس هر class و هر method باید یک وظیفه داشته باشد.

پیشنهاد می کنم 5 اصل سالید را حتما مطالعه کنید.

در کد زیر از این اصل استفاده نشده و اشتباه می باشد:

public function getFullNameAttribute(): string
{
    if (auth()->user() && auth()->user()->hasRole('client') && auth()->user()->isVerified()) {
        return 'Mr. ' . $this->first_name . ' ' . $this->last_name;
    } else {
        return $this->first_name[0] . '. ' . $this->last_name;
    }
}

اما بر اساس اصل تک وظیفه ای بخواهیم کد بالا را بنویسم:

public function getFullNameAttribute(): string
{
    return $this->isVerifiedClient() ? $this->getFullNameLong() : $this->getFullNameShort();
}

public function isVerifiedClient(): bool
{
    return auth()->user() && auth()->user()->hasRole('client') && auth()->user()->isVerified();
}

public function getFullNameLong(): string
{
    return 'Mr. ' . $this->first_name  . ' ' . $this->last_name;
}

public function getFullNameShort(): string
{
    return $this->first_name[0] . '. ' . $this->last_name;
}

هر متد ما در بالا یک وظیفه دارد و این باعث خوانا تر شدن و اگر باگی به وجود آمد به راحتی بتوان آن را تشخیص داده و دیباگ کرد.

مدل های بزرگ،‌ کنترلرهای کوچک

این اصل به این معناست که مدل‌های شما باید مسئولیت‌های بزرگ و پیچیده‌تری را انجام دهند در حالی که کنترلرها باید ساده و مسئولیت‌های کوچک‌تری را داشته باشند.

به عبارت دیگر، مدل‌ها باید وظیفه دسترسی به داده‌ها و انجام عملیات مربوط به دیتابیس مانند ایجاد، خواندن، به‌روزرسانی و حذف را داشته باشند. این اعمال مربوط به داده باید در مدل‌ها انجام شوند تا از ایجاد کدهای پیچیده در کنترلرها جلوگیری شود.

به عنوان مثال، اگر شما یک برنامه مدیریت کاربران دارید، کنترلر مربوط به کاربران باید مسئولیت‌های مانند نمایش لیست کاربران، ایجاد کاربر جدید و نمایش جزئیات کاربر را داشته باشد. اما عملیات مربوط به ذخیره کاربر در دیتابیس و اعتبارسنجی اطلاعات ورودی باید در مدل کاربر انجام شود.

این رویکرد به شما کمک می‌کند تا کد شما منطقی‌تر، قابل نگهداری‌تر و قابلیت افزایش بهتری داشته باشد. همچنین در صورت نیاز به تغییرات در عملیات مربوط به دیتابیس، شما تنها نیاز به تغییر در مدل دارید و کنترلرها و دیگر قسمت‌های برنامه تحت تأثیر قرار نمی‌گیرند. این بهینگی در توسعه و نگهداری نرم‌افزار بسیار مفید است.

معماری MVC را رعایت کنید.

اگر از Query Builder یا raw SQL queries استفاده میکنید، تمام منطق پایگاه داده را در model ها یا Repository classes قرار بدهید.

در کد زیر این اشتباه تکرار شده :

public function index()
{
    $clients = Client::verified()
        ->with(['orders' => function ($q) {
            $q->where('created_at', '>', Carbon::today()->subWeek());
        }])
        ->get();

    return view('index', ['clients' => $clients]);
}

اما اگر بخواهیم صحیح تر بنویسم باید تمام عملیات مربوط به دیتابیس را در مدل ها بنویسم:

public function index()
{
    return view('index', ['clients' => $this->client->getWithNewOrders()]);
}

class Client extends Model
{
    public function getWithNewOrders()
    {
        return $this->verified()
            ->with(['orders' => function ($q) {
                $q->where('created_at', '>', Carbon::today()->subWeek());
            }])
            ->get();
    }
}

اعتبارسنجی

همانند اصل بالا شما باید عملیات مربوط به valdiation را در کلاس Request classes بنویسید، نه در کنترلر ها.

انجام اعتبارسنجی‌ها در کلاس‌های Request در Laravel به عنوان یک شیوه خوب و مناسب شناخته می‌شود. با انجام اعتبارسنجی‌ها در Request، کد کنترلر شما ساده‌تر و خواناتر می‌شود و مسئولیت اعتبارسنجی به جایی که واقعاً تخصصی است منتقل می‌شود. این به توسعه‌دهندگان کمک می‌کند که کدهایی تمیزتر و قابل نگهداری‌تر بنویسند.

بنابراین، استفاده از کلاس‌های Request برای اعتبارسنجی در Laravel توصیه می‌شود و به بهبود ساختار کد و بهره‌وری برنامه کمک می‌کند.

در کد زیر این اشتباه وجود دارد:

public function store(Request $request)
{
    $request->validate([
        'title' => 'required|unique:posts|max:255',
        'body' => 'required',
        'publish_at' => 'nullable|date',
    ]);

    ...
}

اما روش صحیح:

public function store(PostRequest $request)
{
    ...
}

class PostRequest extends Request
{
    public function rules()
    {
        return [
            'title' => 'required|unique:posts|max:255',
            'body' => 'required',
            'publish_at' => 'nullable|date',
        ];
    }
}

منطق برنامه باید در service class باشد
هر کنترلر باید یک وظیفه مشخص داشته باشد و منطق برنامه باید در service classes قرار گیرد. این رویکرد به بهبود تنظیم و مدیریت کد کمک می‌کند و کد کنترلرها را ساده‌تر و خواناتر می‌کند. به عنوان مثال، در یک برنامه وب ممکن است داشته باشیم:

کنترلر UserContorller: که مسئولیت مدیریت کاربران و ارتباط با رابط کاربری دارد.

کنترلر ProductController: که مسئولیت مدیریت محصولات و ارتباط با رابط کاربری مربوط به محصولات را دارد.

کلاس UserService: که منطق مربوط به کاربران را انجام می‌دهد.

کلاس ProductService: که منطق مربوط به محصولات را انجام می‌دهد.

کنترلرها تنها وظیفه مربوط به ارتباط با ورودی و خروجی و ارسال درخواست‌ها به service classes را دارند. به عبارت دیگر، آنها واسطه بین رابط کاربری و منطق برنامه هستند.

این رویکرد به تجزیه و تحلیل کد به اجزاء کوچکتر کمک می‌کند و از تکرار متد‌ها در کنترلرها جلوگیری می‌کند. همچنین این امکان را فراهم می‌کند که تست‌های واحد برای منطق برنامه نوشته شود و کد بهبود یابد.

بنابراین، از تقسیم منطق برنامه به کنترلرها و service classes بهره ببرید تا کد شما سازماندهی شده تر و قابل نگهداری تر باشد.

در کد زیر این مورد رعایت نشده:

public function store(Request $request)
{
    if ($request->hasFile('image')) {
        $request->file('image')->move(public_path('images') . 'temp');
    }
    
    ...
}

روش صحیح تر:

public function store(Request $request)
{
    $this->articleService->handleUploadedImage($request->file('image'));

    ...
}

class ArticleService
{
    public function handleUploadedImage($image)
    {
        if (!is_null($image)) {
            $image->move(public_path('images') . 'temp');
        }
    }
}

اصل DRY یا خودت را تکرار نکن

این اصل به بهبود بهره‌وری کد، کاهش تکرار کدها، و افزایش قابلیت نگهداری کمک می‌کند. در Laravel و توسعه وب، از اصول بازاستفاده در برنامه نویسی بهره‌گیری می‌شود. این اصول به شما کمک می‌کنند کد خود را به شکل بهینه‌تری بنویسید. به چند مورد از این اصول در Laravel اشاره می‌کنم:

استفاده از Blade Directives در قالب‌ها (Blade Templates): در قالب‌های Blade، شما می‌توانید از Blade Directives برای بازاستفاده از کدها استفاده کنید. این اصل به شما این امکان را می‌دهد که بخش‌هایی از کد را در قالب‌ها مجدداً استفاده کنید. برای مثال، می‌توانید یک قالب برای نمایش فرم‌ها ایجاد کرده و آن را در صفحات مختلف بازاستفاده کنید.

استفاده از Eloquent Scopes در مدل‌ها: Eloquent Scopes در Laravel امکان تعریف شرایط مشترک در دیتابیس را فراهم می‌کنند. با تعریف این اسکوپ‌ها در مدل‌ها، می‌توانید شرایطی را که بارها در کوئری‌ها استفاده می‌کنید را به صورت تمیز و قابل استفاده مجدد تعریف کنید.

استفاده از Service Classes برای منطق کسب و کار: به جای نوشتن منطق کسب و کار در کنترلرها، بهتر است این منطق را در Service Classes جداگانه نوشته و در کنترلرها بازاستفاده کنید. این اصل به کاهش تکرار کدها و تمیزتر نگه داشتن کد کمک می‌کند.

استفاده از میدلور ها (Middleware): میدلور ها در Laravel اجازه می‌دهند تا قطعاتی از منطق را قبل از ورود به کنترلر اجرا کنید. با تعریف میدلورهای مناسب، می‌توانید قطعاتی از کد را درخواست‌های مختلف بازاستفاده کنید.

استفاده از Repository Pattern: این الگو به شما امکان می‌دهد که عملیات مرتبط با دیتابیس را در کلاس‌های Repository جداگانه انجام دهید. این باعث می‌شود که قابلیت بازاستفاده از این کلاس‌ها در سراسر برنامه به وجود آید.

استفاده از پیکربندی‌ها (Configurations): در Laravel، می‌توانید اطلاعات پیکربندی را در فایل‌های پیکربندی تعریف کنید و در سراسر برنامه از آن‌ها بازاستفاده کنید. این به شما امکان می‌دهد تا تغییرات پیکربندی را به راحتی اعمال کنید و کدهای مشابه را دوباره ننویسید.

اگر اصل تک مسئولیتی را استفاده کنید به شما کمک میکند تا کار تکراری نکنید.

کد زیر اشتباه می باشد:

public function getActive()
{
    return $this->where('verified', 1)->whereNotNull('deleted_at')->get();
}

public function getArticles()
{
    return $this->whereHas('user', function ($q) {
            $q->where('verified', 1)->whereNotNull('deleted_at');
        })->get();
}

روش صحیح تر :

public function scopeActive($q)
{
    return $q->where('verified', 1)->whereNotNull('deleted_at');
}

public function getActive()
{
    return $this->active()->get();
}

public function getArticles()
{
    return $this->whereHas('user', function ($q) {
            $q->active();
        })->get();
}

استفاده از Eloquent ORM

استفاده از Eloquent ORM به عنوان ORM (Object-Relational Mapping) اصلی در Laravel یک رویکرد خوب برای توسعه نرم‌افزار و تعامل با دیتابیس است. Eloquent به توسعه‌دهندگان امکان می‌دهد با دیتابیس به شکل شی‌گرا و با استفاده از مدل‌ها کار کنند. این به شما این امکان را می‌دهد که کدهایی خوانا و قابل نگهداری بنویسید.

در زیر تعدادی از مزایای استفاده از Eloquent ORM در Laravel آمده است:

قابلیت تعریف روابط میان مدل‌ها: Eloquent به شما اجازه می‌دهد تا روابط پیچیده میان مدل‌ها را به شکل ساده و بدون نیاز به نوشتن کوئری‌های پیچیده تعریف کنید. این امکان به توسعه‌دهندگان کمک می‌کند تا داده‌ها را به شکل مناسبتر و قابلیت تغییر بالاتری طراحی کنند.

مدیریت رویدادها (Events) و اعلان‌ها (Notifications): Eloquent امکان تعریف و مدیریت رویدادها و اعلان‌ها برای مدل‌ها را فراهم می‌کند. این ویژگی به توسعه‌دهندگان امکان می‌دهد تا در تعامل با داده‌ها عملیات مشخصی را انجام دهند.

استفاده از Scopes: با استفاده از Scopes، می‌توانید کوئری‌های مخصوص به یک مدل را به صورت مرتب و تعریف کنید. این باعث می‌شود که کدهای کوئری مرتبط با مدل در کد کلی شما تمیزتر و قابلیت نگهداری‌تر باشند.

قابلیت Soft Deletes: در Eloquent امکان استفاده از Soft Deletes را فراهم می‌کند که به شما اجازه می‌دهد رکوردهای حذف شده را به صورت نرم از دیتابیس حذف کنید و به راحتی به آن‌ها دسترسی داشته باشید.

کمک به تست واحد: استفاده از Eloquent و مدل‌ها امکان تست واحد برنامه را به راحتی تر می‌کند. شما می‌توانید Mock‌ها را برای مدل‌ها ایجاد کنید و تست‌هایی برای منطق کسب و کار خود بنویسید.

به طور کلی، استفاده از Eloquent ORM و مدل‌ها به شما این امکان را می‌دهد تا به شکل سازماندهی‌تر، خواناتر، و قابلیت توسعه‌پذیرتری کدهای خود را بنویسید. این اصول باعث می‌شوند که توسعه نرم‌افزار در Laravel به صورت موثرتری انجام شود و کد شما بهبود یابد.

حال به جای استفاده از Query Builder و raw SQL queries از Eloquent ORM استفاده کنید. همچنین به جای استفاده از Arrays از Collections استفاده کنید.

در کد زیر این اشتباه وجود دارد:

SELECT *
FROM `articles`
WHERE EXISTS (SELECT *
              FROM `users`
              WHERE `articles`.`user_id` = `users`.`id`
              AND EXISTS (SELECT *
                          FROM `profiles`
                          WHERE `profiles`.`user_id` = `users`.`id`) 
              AND `users`.`deleted_at` IS NULL)
AND `verified` = '1'
AND `active` = '1'
ORDER BY `created_at` DESC

اگه به درستی بنویسیم:

Article::has('user.profile')->verified()->latest()->get();

ایجاد یک مدل بهتر
برای راحتی کار و کوتاه تر شدن کد، در html طوری مقادیر name هر input یا ... را نامگذاری کنید که با column های جدول مربوطه یکسان باشد تا laravel آن ها رو با یک کامند خیلی سریع مپ و ذخیره کند.

کد زیر طولانی و اشتباه می باشد:

$article = new Article;
$article->title = $request->title;
$article->content = $request->content;
$article->verified = $request->verified;

// Add category to article
$article->category_id = $category->id;
$article->save();

روش صحیح تر:

$category->article()->create($request->all());

استفاده از eager loading

استفاده از eager loading در Laravel یکی از بهترین روش‌ها برای جلوگیری از مشکل N+1 در دیتابیس است. وقوع مشکل N+1 به معنای اجرای کوئری‌های جداگانه برای هر مورد مرتبط با یک مورد اصلی در دیتابیس است، که می‌تواند به افزایش بسیار زمان‌بر در دسترسی به داده‌ها منجر شود.

استفاده از eager loading به شما امکان می‌دهد تا همه داده‌های مرتبط با یک مورد اصلی را در یک کوئری از دیتابیس بازیابی کنید، به جای انجام کوئری جداگانه برای هر مورد مرتبط. برای این منظور می‌توانید از توابع with و load در Eloquent استفاده کنید.

روش اشتباه :

@foreach (User::all() as $user)
    {{ $user->profile->name }}
@endforeach

روش صحیح تر:

$users = User::with('profile')->get();

@foreach ($users as $user)
    {{ $user->profile->name }}
@endforeach

یک مثال دیگر:

// بدون استفاده از eager loading (مشکل N+1)
$authors = Author::all();
foreach ($authors as $author) {
    $books = $author->books; // برای هر نویسنده کوئری اجرا می‌شود
}

// با استفاده از eager loading (بدون مشکل N+1)
$authors = Author::with('books')->get();
foreach ($authors as $author) {
    $books = $author->books; // یک کوئری برای همه نویسندگان اجرا می‌شود
}

کامنت نویسی و نام های معنی دار

کامنت‌گذاری یک عملیات بسیار مهم است که به توسعه‌دهندگان کمک می‌کند تا کد را بهبود دهند، قابل نگهداری کنند، و به توسعه‌دهندگان دیگر اجازه دهند که به راحتی کد را درک کنند. همچنین برای هر تابع یا هر متد یا هر … یک اسم با معنا و توصیفی انتخاب کنید.

در کد زیر این اشتباه صورت گرفته:

if (count((array) $builder->getQuery()->joins) > 0)

ولی روش صحیح تر :

// Determine if there are any joins.
if (count((array) $builder->getQuery()->joins) > 0)

//or
if ($this->hasJoins())

مدیریت فایل های جاوااسکریپتی و PHP

استفاده از جاوااسکریپت (JS) و کدهای CSS مستقیماً در تمپلیت‌های Blade و استفاده از کدهای HTML در کلاس‌های PHP در Laravel توصیه نمی‌شود. این رویکرد‌ها ممکن است به دلایل زیر مشکل‌ساز شوند:

1. عدم مدیریت جداگانه: استفاده از کدهای JS، CSS و HTML در تمپلیت‌های Blade و کلاس‌های PHP می‌تواند منجر به عدم مدیریت جداگانه این کدها شود. این بدان معناست که تغییرات در یک بخش ممکن است تاثیرات ناخواسته‌ای در بخش‌های دیگر ایجاد کند.

2. کاهش قابلیت خوانایی: تمپلیت‌های Blade برای نمایش داده‌ها به صورت خوانا و تمیز طراحی شده‌اند. افزودن کدهای JS و CSS به تمپلیت‌ها می‌تواند خوانایی و درک تمپلیت‌ها را کاهش دهد.

3. عدم استفاده از ویژگی‌های Laravel: Laravel دارای ویژگی‌ها و ابزارهای خود برای مدیریت کدهای JS و CSS است. استفاده از این ویژگی‌ها، مانند Mix برای ترکیب و بهینه‌سازی کدها، بهینه‌تر و مدیریت‌پذیرتر است.

4. تضاد در اصول تفکیک مسئولیت: اصول تفکیک مسئولیت (Separation of Concerns) توصیه می‌کنند که کدهای مختلف، مانند HTML، CSS، و JS، در لایه‌های جداگانه و در فایل‌های جداگانه قرار گیرند. این اصل به بهبود قابلیت نگهداری و توسعه‌پذیری کمک می‌کند.

به عنوان جایگزین، شما می‌توانید کدهای JS و CSS خود را در فایل‌های مخصوص خود قرار داده و از ابزارهای Laravel برای مدیریت آن‌ها استفاده کنید. همچنین، کدهای HTML خود را در تمپلیت‌های Blade به شکل خوانا و تمیز اضافه کنید و از اصول تفکیک مسئولیت پیروی کنید. این رویکرد به بهبود قابلیت نگهداری و توسعه نرم‌افزار شما کمک می‌کند.

در زیر این اشتباه وجود دارد:

let article = `{{ json_encode($article) }}`;

اما روش صحیح تر :

//in php file
<input id="article" type="hidden" value='@json($article)'>

Or

<button class="js-fav-article" data-article='@json($article)'>{{ $article->name }}<button>

//in js file:
let article = $('#article').val();

استفاده از Config و language

استفاده از فایل‌های پیکربندی (config) و فایل‌های زبان (language) در Laravel به توسعه‌دهندگان این امکان را می‌دهد تا متن‌ها و تنظیمات مختلف برنامه را به صورت جداگانه از کد منبع نگهداری و مدیریت کنند. این رویکرد به مزایای زیر منجر می‌شود:

1. قابلیت ترجمه : با استفاده از فایل‌های زبان، می‌توانید متن‌ها را برای چندین زبان مختلف ترجمه کنید و برنامه خود را چند زبانه کنید. این به شما امکان می‌دهد تا برنامه خود را به مخاطبان جهانی تقدیم کنید.

2. قابلیت تغییر تنظیمات بدون تغییر در کد: با استفاده از فایل‌های پیکربندی، می‌توانید تنظیمات مختلف برنامه را به صورت مرکزی در فایل‌های config ذخیره کنید. این به شما امکان می‌دهد تا تغییرات در تنظیمات را بدون نیاز به تغییر در کد منبع اعمال کنید.

3. کاهش تداخل‌ها و اشکال‌زدایی سریع‌تر: با جدا کردن متن‌ها و تنظیمات از کد، اشکال‌زدایی و پیدا کردن مشکلات در برنامه سریع‌تر و آسان‌تر می‌شود. همچنین، تداخل‌ها بین متن‌ها و کد منبع کاهش می‌یابد.

4. مدیریت بهتر تیم‌های توسعه‌دهنده: با استفاده از این رویکرد، توسعه‌دهندگان می‌توانند به صورت موازی بر روی متن‌ها و تنظیمات کار کنند بدون اینکه به تداخل با یکدیگر برخورد کنند.

برای استفاده بهینه از این رویکرد، شما می‌توانید فایل‌های config و language را در Laravel ایجاد کنید و از توابع مخصوصی برای دسترسی به اطلاعات در این فایل‌ها استفاده کنید. این رویکرد به بهبود مدیریت کدها و توسعه نرم‌افزار شما کمک می‌کند و از پیچیدگی‌های غیرضروری جلوگیری می‌کند.

در کد زیر این اشتباه صورت گرفته:

public function isNormal()
{
    return $article->type === 'normal';
}

return back()->with('message', 'Article created!');

روش صحیح تر:

public function isNormal()
{
    return $article->type === Article::TYPE_NORMAL;
}

return back()->with('message', __('app.article_added'));

استفاده از ابزار های استاندارد

توصیه استفاده از ابزارها و قابلیت‌های رسمی و داخلی Laravel یک مورد بسیار مهم است که به توسعه‌دهندگان کمک می‌کند تا پروژه‌هایشان را بهبود دهند و از پیچیدگی‌های غیرضروری جلوگیری کنند. از جمله مزایای استفاده از ابزارها و قابلیت‌های رسمی Laravel می‌توان به موارد زیر اشاره کرد:

یکپارچگی و سازگاری بهتر: ابزارها و قابلیت‌های رسمی Laravel با بخش‌های دیگر این چارچوب بهتر سازگار هستند. این به معنای این است که در تعامل با بخش‌های مختلف برنامه، مشکلات کمتری پیش می‌آید.

پشتیبانی از جامعه: استفاده از ابزارها و قابلیت‌های رسمی Laravel به شما این امکان را می‌دهد که از جامعه گسترده Laravel برای پشتیبانی و حل مشکلات استفاده کنید. توسعه‌دهندگان دیگر از این ابزارها استفاده می‌کنند و به شما کمک می‌کنند تا مشکلات را برطرف کنید.

کاهش هزینه و زمان توسعه: استفاده از ابزارها و قابلیت‌های رسمی Laravel به شما کمک می‌کند تا کد منبع را ساده‌تر و بهینه‌تر بنویسید. این به تعجیل در توسعه و کاهش هزینه‌ها کمک می‌کند.

استانداردهای رسمی: Laravel دارای استانداردهای رسمی برای نحوه استفاده از قابلیت‌ها و ابزارهای خود است. این استانداردها به شما کمک می‌کنند تا کد منبع خود را به صورت مطابق با استانداردهای Laravel بنویسید.

قابلیت‌های به روز و پشتیبانی: ابزارها و قابلیت‌های رسمی Laravel به روز رسانی می‌شوند و توسط تیم توسعه Laravel پشتیبانی می‌شوند. این به شما اطمینان می‌دهد که به مرور زمان از آخرین قابلیت‌ها و بهبودهای ایجاد شده استفاده می‌کنید.

به عنوان یک توسعه‌دهنده Laravel، اهمیت استفاده از ابزارها و قابلیت‌های رسمی این فریمورک را درک کنید و تا حد امکان از آن‌ها استفاده کنید. این رویکرد به بهبود کیفیت و پایداری پروژه‌های شما کمک می‌کند و همچنین به توسعه‌دهندگان دیگر کمک می‌کند تا به راحتی کد شما را درک و مدیریت کنند.

برای مثال برای دیپلوی کردن از لاراول Forge استفاده کنید و از پکیج های غیر رسمی دیگر استفاده نکنید.

استفاده از قرار داد های لاراول برای نامگذاری

استفاده از قراردادهای نامگذاری Laravel یک رویکرد خوب برای نام‌گذاری متغیرها، جداول دیتابیس، مسیرها و سایر اجزای پروژه است. این قراردادها به شما کمک می‌کنند تا به صورت یکپارچه و مطابق با استانداردهای Laravel نام‌گذاری کنید. از استاندارد های php که به PSR معروف است استفاده کنید به عنوان مثال:

بخش مربوطهقاعده اسم گذاری روش قابل قبول روش اشتباه
Controllerاسامی مفردArticleControllerArticlesController
Routeاسامی جمعarticles/1article/1
Route nameروش snake_case همراه با نقاط اتصالusers.show_activeusers.show-active, show-active-users
Modelاسامی مفردUserUsers
hasOne or belongsTo relationshipاسامی مفردarticleCommentarticleComments, article_comment
All other relationshipsاسامی جمعarticleCommentsarticleComment, article_comments
Tableاسامی جمعarticle_commentsarticle_comment, articleComments
Pivot tableنام مدل ها با اسامی مفرد و ترتیب الفباییarticle_useruser_article, articles_users
Table columnروش snake_case بدون اسم مدلmeta_titleMetaTitle; article_meta_title
Model propertyروش snake_case$model->created_at$model->createdAt
Foreign keyاسامی مفرد model name with _id suffixarticle_idArticleId, id_article, articles_id
Primary key-idcustom_id
Migration-2017_01_01_000000_create_articles_table2017_01_01_000000_articles
Methodروش camelCasegetAllget_all
Method in resource controllertablestoresaveArticle
Method in test classروش camelCasetestGuestCannotSeeArticletest_guest_cannot_see_article
Variableروش camelCase$articlesWithAuthor$articles_with_author
Collectionتوصیفی و اسامی جمع$activeUsers = User::active()->get()$active, $data
Objectتوصیفی و اسامی مفرد$activeUser = User::active()->first()$users, $obj
Config and language files indexsnake_casearticles_enabledArticlesEnabled; articles-enabled
Viewkebab-caseshow-filtered.blade.phpshowFiltered.blade.php, show_filtered.blade.php
Configsnake_casegoogle_calendar.phpgoogleCalendar.php, google-calendar.php
Contract (interface)صفت یا اسمAuthenticationInterfaceAuthenticatable, IAuthentication
TraitصفتNotifiableNotificationTrait
Trait (PSR)adjectiveNotifiableTraitNotification
EnumsingularUserTypeUserTypes, UserTypeEnum
FormRequestsingularUpdateUserRequestUpdateUserFormRequest, UserFormRequest, UserRequest
SeedersingularUserSeederUsersSeeder

فرمت بندی و سینتکس صحیح

استفاده از Syntax‌های معنادار و کوتاه در کد، به خوانایی و تفهیم بهتر کدها کمک می‌کند و کدهای شما را از پیچیدگی‌های غیرضروری خارج می‌کند.

روش اشتباه :

$request->session()->get('cart');
$request->input('name');

به صورت صحیح تر:

session('cart');
$request->name;

استفاده از Facades و loC continer

استفاده از IoC Container (Inversion of Control Container) و Facades در Laravel به شما این امکان را می‌دهد که به جای ایجاد آبجکت‌ها با new، dependency های خود را به صورت خودکار دریافت کنید. این رویکرد به بهبود قابلیت تست‌نویسی و کاهش وابستگی‌های متغیرها در کدها کمک می‌کند. 

این کد زیر اشتباه می باشد:

$user = new User;
$user->create($request->all());

به صورت درست تر:

public function __construct(User $user)
{
    $this->user = $user;
}

...

$this->user->create($request->all());

استفاده صحیح از فایل env.

 

استفاده از فایل env. در Laravel برای ذخیره اطلاعات محرمانه و پیکربندی‌ها یک رویکرد امنیتی است. اطلاعاتی مانند رمزعبورها و تنظیمات مربوط به محیط توسعه و تولید در این فایل ذخیره می‌شوند. اما برای استفاده از این اطلاعات در برنامه‌های Laravel به صورت امن و مدیریت‌پذیر، می‌توانید از متدهای ارائه شده توسط Laravel استفاده کنید. به صورت خلاصه، مراحل زیر را دنبال کنید:

1. تعریف تنظیمات مرتبط در فایل config:
در فایل‌های پیکربندی Laravel، تنظیمات مرتبط با برنامه خود را تعریف کنید. به عنوان مثال، اگر یک کلید API برای اتصال به یک سرویس خارجی دارید، می‌توانید آن را در فایل config/services.php تعریف کنید.

2. استفاده از () envدر تنظیمات:
در تنظیمات مرتبط با برنامه، از تابع ()env برای دریافت اطلاعات از فایل env. استفاده کنید. این تابع به عنوان آرگومان ورودی نام متغیر مورد نظر را دریافت می‌کند.

روش اشتباه:

$apiKey = env('API_KEY');

به صورت صحیح:

// config/api.php
'key' => env('API_KEY'),

// Use the data
$apiKey = config('api.key');

قالب استاندارد زمان و تاریخ

در Laravel، استفاده از Accessors و Mutators برای دستکاری تاریخ و زمان به روش استاندارد بسیار مفید است. این ابزارها به شما این امکان را می‌دهند که مقادیر تاریخ و زمان در مدل‌های خود را به صورت مطلوبی تغییر دهید و نمایش دهید. اما سعی کنید به صورت استاندارد استفاده کنید.

روش اشتباه:

{{ Carbon::createFromFormat('Y-d-m H-i', $object->ordered_at)->toDateString() }}
{{ Carbon::createFromFormat('Y-d-m H-i', $object->ordered_at)->format('m-d') }}

به صورت صحیح:

// Model
protected $casts = [
    'ordered_at' => 'datetime',
];

public function getSomeDateAttribute($date)
{
    return $date->format('m-d');
}

// View
{{ $object->ordered_at->toDateString() }}
{{ $object->ordered_at->some_date }}

فایل Route 

توصیه می‌شود منطق برنامه را در فایل‌های route خود قرار ندهید. در Laravel، معمولاً فایل‌های route برای تعریف مسیرها و متدهای کنترلر برای اجرای منطق برنامه استفاده می‌شوند. این رویکرد به بهبود خوانایی کد، جدا کردن وظایف مختلف و افزایش قابلیت تست‌نویسی کمک می‌کند.

روش اشتباه:

// Route
Route::get('user/1', function (User $user) {
    return new UserResource($user);
});

به صورت صحیح:

// Route
Route::get('user/1', 'UserController@show');

// Controlelr
class UserController extends Controller 
{
    public function show(User $user) {
        return new UserResource($user);
    }
}

استفاده نکردن از PHP خام در balde

تا حد ممکن از PHP خام در فایل های blade استفاده نکنید. خب، در این صورت می‌توانیم از دستورات Blade در فایل‌های Blade استفاده کنیم تا کد PHP را کاهش دهیم. در ادامه، نمونه‌هایی از کد با استفاده از دستورات Blade را می‌دهم:

//in blade.php

{{-- اگر کاربر مشتری باشد و حساب کاربری شما قابل تشخیص باشد --}}
@if (auth()->user() && auth()->user()->hasRole('client') && auth()->user()->isVerified())
    {{-- نام کامل به صورت آقای [نام] [نام خانوادگی] نمایش داده می‌شود --}}
    آقای {{ $this->first_name }} {{ $this->last_name }}
@else
    {{-- در غیر این صورت --}}
    {{-- نام کوچک اولیه و نام خانوادگی به نام اولیه. نام نمایش خانوادگی داده می شود --}}
    {{ $this->first_name[0] }}. {{ $this->last_name }}
@endif

در این کد، از دستورات Blade مانند if@ و else@ برای ایجاد شرایط و از {{ }} برای نمایش تغییرات PHP استفاده شده است. این کد نه تنها کمک به کاهش کدهای PHP خام است.

نتیجه

کدنویسی تمیز و استفاده از اصول اصلی در لاراول یک تلاش یکباره نیست. این یک تمرین مداوم است که در دراز مدت نتیجه می دهد. با رعایت بهترین شیوه ها و نوشتن کدهای ظریف و قابل نگهداری، می توانید برنامه های وب قوی بسازید که در تست زمان مقاومت کنند.

#لاراول#کدنویسی#php#clean_code#laravel_2023#کد_نویسی_تمیز
نظرات ارزشمند شما :
Loading...