<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>نوشته های بابک فقیهیان</title>
        <link>https://virgool.io/feed/@faghihian</link>
        <description></description>
        <language>fa</language>
        <pubDate>2026-04-14 22:19:46</pubDate>
        <image>
            <url>https://files.virgool.io/upload/users/1384/avatar/QBOTGQ.png?height=120&amp;width=120</url>
            <title>بابک فقیهیان</title>
            <link>https://virgool.io/@faghihian</link>
        </image>

                    <item>
                <title>فرار از ریفکتور و پاک کردن صورت مسئله</title>
                <link>https://virgool.io/@faghihian/%D9%81%D8%B1%D8%A7%D8%B1-%D8%A7%D8%B2-%D8%B1%DB%8C%D9%81%DA%A9%D8%AA%D9%88%D8%B1-%D9%88-%D9%BE%D8%A7%DA%A9-%DA%A9%D8%B1%D8%AF%D9%86-%D8%B5%D9%88%D8%B1%D8%AA-%D9%85%D8%B3%D8%A6%D9%84%D9%87-zfnisjg7t4d7</link>
                <description>احتمالا هر برنامه نویسی موقعیت هایی در شروع کارش داشته که کدهای بدی نوشته  و یا هر کدوم از ما توی مجموعه های درگیر شدیم که یک کد بد با معماری بدتر با عدم کنترل روی همزمانی ها .... تحویل گرفتیم و سازمان یا اون شرکت درگیرش بوده و یکی از لامپ هایی که توی سر هرکسی روشن شده این بوده که خوب یه محصول جدید بنویسیم بهتر از این از اولش بدونیم چه کردیم و بعد انتقال بدیم یوزرها رو و ......یوزرهای فعلی چه بخواید چه نخواید یک سری مشتری هستن که اگه سرویس خوب نگیرن قاعدتا سرویس شما رو ترک میکنن و شما مجبورید تا طراحی یک سیستم جدید با هر معماری و داستانی به اونها خدمات صحیح بدید .خدمات صحیح یعنی اینکه نرم افزار شما کار اصلیش رو به طور صحیح انجام بده و کاربر بتون نیازی که از محصول نرم افزاری شما داره رو برطرف کنه چون اگه شما نمی تونید توی این مدت خدمات خوبی بدید احتمالا یوزری برای انتقال به پلتفورم جدیدتون نخواهید داشت.پس هزینه برای بهترکردن موضوع فعلی یک تلف کردن سرمایه نیست بلکه یک سرمایه گذاریه.اما هدف من از نوشتن این پست چیه شاید خیلی از دوستانی که این مقاله رو میخونن حرفه ای باشن و راهکارهای جدیدی داشته باشن اما من میخوام اینجا به عمده ترین مشکلات و خطرناکترینشون اشاره کنم که پرتکرار هستن از سازمان های بزرگ تا بیزنس های کوچیک تا شرکت ها با تراکنش های بالای مالی درگیر این عدم دقت در واحد های فنیشون هستن.۱- Race Conditionخطرناکترین مدلی که من توی مجموعه ها دیدم قاطی کردن این هست که اگه چیزی رو توی ترنزاکشن بگذارن  پس در نتیجه هیچ race condition پیش نخواهد اومد در صورتی که این تفکر به شدت غلطه و در مواقعی که یک قسمت خیلی حساسه باید از  lock یا update با شرایط خاص استفاده کرد مثلا optimistic locking یا pessimistic locking که البته شرایط استفادشون با هم فرق میکنه۲- ما کد تمیز می نویسیم  یک داستان خیلی بدی که امروزه درگیرش هستیم این هست که برنامه نویس ها نوشتن یک اسم متغیر صحیح رو همراه با فانکشنال کردنش clean code در نظر میگیرن خیلی ها از SOLID فقط قضیه single responsibility رو میدونن که اون رو هم به اشتباه این میدونن که یک کلاس فقط باید یک وظیفه داشته باشه در صورتی که یکی از چیزهای مهم این قضیه این هست که یک کلاس فقط باید یک دلیل برای تغییر داشته باشه اینکه شما در اولین سرچتون به زبان انگلیسی به مفاهیم solid می رسید و فکر میکنید که کاملا concept ها رو فهمدید یک اشتباه بزرگه بزرگترین هدف در clean code تغییر پذیری راحت یک سیستم بدون فرو ریزی قسمت های دیگست و تمامی نکات در حقیقت برای رسیدن به این داستانه به شدت کتاب clean code از robert c martin یا همون عمو باب uncle bob خودمون هست حواستون باشه این کتاب رو به کتاب clean coder اشتباه نگیرید به نظر من تمامی فصل های این کتاب رو هر برنامه نویسی تحلیل گر سیستمی lead developer و هرکسی که توی زمینه فنی این پروسه فعالیت میکنه باید بخونه.نمونه دیگه مفهوم open close principle هست خیلی ها فکر میکنن یک کلاس رو که نوشتن دیگه حق تغییر اون کلاس رو ندارن و باید اونقدر ایده ال باشه که نیاز به تغییر نداشته باشه خیر در حقیقت شما باید جوری کلاس ها تون رو بسازید و مثلا از مفاهیم factory design pattern استفاده کنید یا مثلا کلاستون رو بشکونید تا برای افزودن یک خاصیت جدید فقط یک چیز اضافه کنید نه اینکه قسمت های دیگر رو تغییر بدید.مشکل بعدی مفهوم dependency injection هست خیلی ها دوباره اصلا استفاده از این قضیه رو نمی دونن و فکر میکنن inject کردن کلاس یوزر مثلا در لاروال میتونه کارشون رو حل بکنه در صورتی که این قضیه هنوز شما رو به اون کلاس بی نیاز نکرده در حقیقت شما باید اول مفهوم inversion of control رو متوجه بشید و بعد ببینید چطور dependecy injection توی این قضیه بهتون کمک میکنه داستان بعدی هم اینکه مفهوم dependency injection با singelton فرق میکنه و برای این نیست که شما یه چیزی رو از اول برنامتون مثل bootstrap load کنید. ونویسی آسونه اما ما که نمی نویسیم کردناکثر مجموعه هایی که من دیدم با مانیتور کردن کوئری هاشون تونستم متوجه بشم که خیلی از اونها یا کوئری هاشون مانیتور نکردن و یا هر فیلدی که توی دیتابیس رو داشتن روش سرچ میزدن تک تک ایندکس کردن و اصلن از ایندکس چندتایی و ترتیب ایندکسینگ بر اساس کوئری سرچ آگاهی نداشن . یا مثلا چثدر میتونه hash column ها به جلوگیری از ایندکسهای بزرگ کمک منه میتونید اطلاعات بیشتر رو از اینجا ببینید و فکر میکنم خوندن این صفحه میتونه بهتون خیلی کمک بکنه۴-عدم استفاده از queue و  message brokerخیلی از کسایی که دیدم هنوز خیلی از صف هاشون رو در جاهایی که نیاز نیست خودشون با دیتابیس هندل میکنن بماند که باید دوباره مفاهیم race condition رو در pickup کردن جاب ها در نظر بگیرن و اصلا اگاهی از وجود beanstalkd و ....... نداشتن5- عدم استفاده از interfaceیکی از مفاهیمی که خیلی در حقش ظلم میشه و همه فقط اسمشو شنیدن اینو توی پروداکتهای بزرگ و با تغییرات بالا دیدیم interface هست اصلا چرا از interface استفاده میشه چطور میتونه کمک بکنه چقدر design pattern ها با کمک interface پیاده سازی میشن 6- عدم توجه به sql anti patterns این مورد رو فقط میتونم موکول کنم به کتاب اقای bill karwin sql antipatterns  که فوق العادست من کل این کتاب رو خوندم و به شدت پیشنهاد میکنم کسایی که میخوان دیتابیس طراحی کنن قبل از اینکه هیچی نشده سریعا تصمیم به دیتابیس های nosql پناه میبرن در مواردی که اصلا نیاز نیست اول این کتاب رو بخونن7- تست نویسی آسونه اما ما که نمی نویسیم قطعا یکی از بزرگترین دروغ هایی که شنیدم این بوده که tdd  اولش سخته و سرعت کد نویسی رو بالا میبره نه tdd سرعت maintenance رو بالا میبره ولی در کل کد نویسی شما رو نسبت به بزن برو جلو زمان بر تر میکنه اگه دیدید کسی گفت این جملرو بدونید tdd ننوشته و بزرگترین مسئله شما بعد از پاس کردن هر تست موظف به ریفکتور هستید نه اینکه تستون رو جوری بنویسید که سورس ریفکتور شده تولید کنید این خیلی مهمه در ابتدای کار و گرنه دچار کمالگرایی میشید و دیگه نمیتونید تست بنویسید  و .......خیلی موارد دیگه هست که به نظرم باید بگم که شاید یک نوشته دیگه براش نوشتم اما سعی کردم توی این شلوغی های کاری این مطالب رو عنوان کنم شاید بتونه کمکی به چندین نفر بکنه .</description>
                <category>بابک فقیهیان</category>
                <author>بابک فقیهیان</author>
                <pubDate>Sat, 31 Aug 2019 01:11:36 +0430</pubDate>
            </item>
                    <item>
                <title>چگونه از jwt در لاراول استفاده کنیم ؟</title>
                <link>https://virgool.io/laravel-community/%DA%86%DA%AF%D9%88%D9%86%D9%87-%D8%A7%D8%B2-jwt-%D8%AF%D8%B1-%D9%84%D8%A7%D8%B1%D8%A7%D9%88%D9%84-%D8%A7%D8%B3%D8%AA%D9%81%D8%A7%D8%AF%D9%87-%DA%A9%D9%86%DB%8C%D9%85-c4ewb43bsyke</link>
                <description>سلام دوستان این اولین پستی هست که در مورد فنی می نویسم و خیلی موضوعات مختلف هست  که دوست دارم بهش بپردازم  و کمک کنم تا بقیه راحت تر مشکلشون حل بشه. امیدوارم وقتم آزاد تر بشه و بتونم مسائلی رو که در ۶ سال پیش باهاشون دستو پنجه نرم کردم را باهاتون در میون بگذارم. خیلی از ماها  احتمالا بخوایم برای یک اپ  که از طریق مثلا یک rest api  با سرور در ارتباط هست از یک توکن استفاده کنیم . یکی از راه ها  استفاده از توکن هست که بعد از لاگین یک توکن به کاربر داده می شود و کاربر در درخواست های بعدی این توکن را به سمت سرور ارسال میکنه تا احراز هویت بشه. اما با این کار اتفاقی که می افته اینکه سرور با توکن گرفته شده یک درخواست به پایگاه داده می دهد که کاربر با توکن ارسال شده پیدا بشه بعد از اون با شناسه اصلی کاربر مثلا کامنت های اخیر کاربر گرفته بشه.اما jwt یا همان json web token چون دارای یک امضای دیجیتال هست و بین client و server بصورت امن جابه جا میشه یعنی  شما نیازی به چک کردن توکن در دیتابیس ندارید  و حتی نگه داریش هم نمی کنید!!!‌ یعنی یک درخواست کمتر و در اپلیکیشن های بزرگتر کلی درخواست کمتر .... البته این یکی از مزیت های استفاده از jwt هست و مزیت های دیگه هم داره  شما ممکنه هر جایی براتون مناسب نباشه که از jwt استفاده کنید. چون در هر  مسیری در هر پروژه ای نیاز شماست که نشون میده چه ابزاری برای شما مناسبه    اگه میخواید نحوه کار کردن json web token رو بدونید می تونید از این لینک استفاده کنید.اما برای استفاده از jwt در لاراول میتونید از پکیج  tymondesigns/jwt-auth استفاده کنید.برای اینکار در پروژه لاراوالی خودتون با composer این پکیج رو نصب کنید :composer require tymon/jwt-authپس از نصب این پکیج خط زیر رو به  providers در config/app.php  اضافه کنید :Tymon\JWTAuth\Providers\JWTAuthServiceProvider::classو  دو خط زیر رو هم به  قسمت aliases در همان فایل اضافه کنید:JWTAuth =&gt; Tymon\JWTAuth\Facades\JWTAuth::class,
JWTFactory =&gt; Tymon\JWTAuth\Facades\JWTFactory::classپس از اون دستور زیر روی اجرا کنید تا فایل jwt.php در قسمت config ایجاد بشه و بتونید تنظیمات رو تغییر بدید :php artisan vendor:publish --provider=&quot;Tymon\JWTAuth\Providers\JWTAuthServiceProvider&quot;پس از اون شما به یک secret-key نیاز دارید که با دستور زیر میتونید اون رو بسازید:php artisan jwt:generateتا به اینجا شما پکیج رو نصب کردید اما الان نیاز به معرفی middleware ها دارید تا بتونید روی route های دلخواهتون حتما احراز هویت بخواید ( مثلا ویرایش و ساخت یک محصول جدید یا ... که به لاگین بودن کاربر نیاز داره ) برای اینکار در فایل app/http/Kernel.php  در قسمت routeMiddleware این دو middleware رو اضافه کنید&#x27;jwt.auth&#x27; =&gt; &#x27;Tymon\JWTAuth\Middleware\GetUserFromToken&#x27;,&#x27;jwt.refresh&#x27; =&gt; &#x27;Tymon\JWTAuth\Middleware\RefreshToken&#x27;به کمک jwt.auth ما میتونیم روی گروهی از route ها درخواست دهنده رو ملزم به لاگین کنیم و به کمک jwt.refresh ما می تونیم برای رفرش کردن توکن اقدام کنیم.حالا می ریم که route ها خودمون رو از این middleware ها عبور بدیم در فایل routes/api.php اینگونه می نویسیم :Route::post(&#039;login&#039;, &#039;AuthController@login&#039;);
Route::post(&#039;register&#039;, &#039;AuthController@register&#039;);

// Refresh route
Route::get(&#039;/refresh&#039;,function(){
})-&gt;middleware(&#039;jwt.refresh&#039;);

// Login required routes
Route::group([&#039;middleware&#039; =&gt; [&#039;jwt.auth&#039;]], function() {
    Route::Resource(&#039;/product&#039;,&#039;ProductControler&#039;);
});صرف آشنایی شما با لاراول نیاز به توضیح بیشتر در این قسمت نیست .حال باید بدنه AuthController رو بسازیم  ( شما باید یک controller بسازید  اسم اون دلخواهه ... فقط باید در route هاتون هم به همون controller اشاره کنید )/**
 * 
 *
 * @param Request $request
 * @return \Illuminate\Http\JsonResponse
 */
public function login(Request $request)
{
    $rules = [
        &#039;email&#039; =&gt; &#039;required|email&#039;,
        &#039;password&#039; =&gt; &#039;required&#039;,
    ];
    $input = $request-&gt;only(&#039;email&#039;, &#039;password&#039;);
    $validator = Validator::make($input, $rules);
    if ($validator-&gt;fails()) {
        $error = $validator-&gt;messages()-&gt;toJson();
        return response()-&gt;json([&#039;success&#039; =&gt; false, &#039;error&#039; =&gt; $error]);
    }
    $credentials = [
        &#039;email&#039; =&gt; $request-&gt;email,
        &#039;password&#039; =&gt; $request-&gt;password
    ];
    try {
        // attempt to verify the credentials and create a token for the user
        if (!$token = JWTAuth::attempt($credentials)) {
            return response()-&gt;json([&#039;success&#039; =&gt; false, &#039;error&#039; =&gt; &#039;Wrong email or password.&#039;], 401);
        }
    } catch (JWTException $e) {
        return response()-&gt;json([&#039;success&#039; =&gt; false, &#039;error&#039; =&gt; &#039;could_not_create_token&#039;], 500);
    }
    return response()-&gt;json([&#039;success&#039; =&gt; true, &#039;data&#039; =&gt; [&#039;token&#039; =&gt; $token]]);
}

public function register(Request $request)
{
     // you registration section .... 
}
/**
 * Log out
 * Invalidate the token, so user cannot use it anymore
 * They have to relogin to get a new token
 *
 * @param Request $request
 */
public function logout(Request $request)
{
    $this-&gt;validate($request, [&#039;token&#039; =&gt; &#039;required&#039;]);
    try {
        JWTAuth::invalidate($request-&gt;input(&#039;token&#039;));
        return response()-&gt;json([&#039;success&#039; =&gt; true]);
    } catch (JWTException $e) {
        return response()-&gt;json([&#039;success&#039; =&gt; false, &#039;error&#039; =&gt; &#039;Destory faild&#039;], 500);
    }
}در قسمت لاگین ما اعتبار سنجی می کنیم که آیا کاربر با یوزنیم و پسورد وارد شده قادر به لاگین هست یا نه و بعد توکن ساخته شده رو براش میفرستیم. نکته:زمان های expire توکن و رفرش توکن رو میتونید در فایل  config/jwt.php تغییر بدید.اما یک نکته همون طوری که گفتم ما توکنی رو سمت سرور ذخیره نمیکنیم پس اگر کاربری بخواد لاگ ات کنه یا در حقیقت توکن فعلیش رو از اعتبار ساقط کنه چه باید بکنه ما که در سمت سرور جایی نداریم که بخوایم اون توکن رو پاک کنیم. در jwt اگر شما با همان زمان token expire کارتون راه نمیفته  ( که خیلی ها میفته ) و حتما میخواید لاگ ات کنید ( علاوه بر اینکه میتونید سمت کاربر توکن رو هم حذف کنید )  در حقیقت توکن ها رو میبرن توی یک black list و اگر کاربر درخواست داد میبینن که آیا توکن توی بلک لیست هست اگر نیست اجازه دسترسی بهش نمیدن اما یه سوال اگر اینکار رو بکنیم که در حقیقت دوباره داریم یه درخواست به پایگاه داده اضافه می کنیم و این یک مشکله دقیقا درسته به خاطر همین: یکی از راهکارها  اینه که مثلا توکن های بلک لیست رو توی لایه های کش مثل redis نگه داری می کنن و بعد از اینکه زمان expire توکن رسید اونو پاک میکنن. که با توجه به زمان توکن این لیست مثلا هر یک ساعت یکبار کلی ریزش میکنه و اونقدر بزرگ نمیشه ( بسته به بزرگی پروژه و تعداد کاربرهای متفاوت خواهد بود ).شما میتونید پس از این راهکارها یک یوزر در لاروال بسازید و بعد با postman درخواستتون رو با   header :Authorization Bearer [توکن شما] به سمت سرورتون ارسال کنید و نتیجه رو ببینید.امیدوارم آموزش بالا تونسته باشه بهتون کمک کنه.</description>
                <category>بابک فقیهیان</category>
                <author>بابک فقیهیان</author>
                <pubDate>Fri, 19 Jan 2018 20:05:25 +0330</pubDate>
            </item>
                    <item>
                <title>اولین پست ویرگولی من</title>
                <link>https://virgool.io/@faghihian/%D8%A7%D9%88%D9%84%DB%8C%D9%86-%D9%BE%D8%B3%D8%AA-%D9%88%DB%8C%D8%B1%DA%AF%D9%88%D9%84%DB%8C-%D9%85%D9%86-mn4vfapkqnzs</link>
                <description>اول از هر چیز به علی آجودانیان و تیمش بابت طراحی فوق العاده ویرگول تبریک میگم و فقط میتونم بگم ادامه بدید.امیدوارم بتونم اینجا مطالب خوبی رو به اشتراک بگذارم و فرصت کنم بنویسم.ممنون که نوشتن فارسی رو زنده نگه می دارید.</description>
                <category>بابک فقیهیان</category>
                <author>بابک فقیهیان</author>
                <pubDate>Thu, 12 Oct 2017 15:28:50 +0330</pubDate>
            </item>
            </channel>
</rss>