روتها/Routes در پروژه های بزرگ لاراولی ممکن هست زیاد و شلوغ بشن، خوانایی پایین بیاد و هنگام ویرایش دچار سردرگمی بشین. در این مطلب سه روش برای حل این مشکل رو توضیح میدم و شما میتونید با توجه به پروژه و ارزیابی خودتون یکی رو انتخاب کنید.
این Provider مسیر های تعریف شده رو در routes/web.php و routes/api.php لود میکنه. میتونید روتها رو به فایلهای کوچکتر تبدیل و در RouteServiceProvider تعریفشون کنید. دقیقا مثل کاری که به طور پیشفرض با web.php و api.php انجام داده. در مثال زیر متد بوت RouteServiceProvider رو ویرایش و posts رو اضافه کردم. در routes/posts.php مسیر های مربوط به ماژول post من قرار داره.
public function boot()
{
$this->configureRateLimiting();
$this->routes(function () {
Route::middleware('api')
->prefix('api')
->group(base_path('routes/api.php'));
Route::middleware('web')
->group(base_path('routes/web.php'));
// new routes.
Route::middleware('api')
->group(base_path('routes/posts.php'));
});
}
به نظرم این روش پیچیدگی روتهای زیاد رو حل میکنه اما یک پیچیدگی جدید به وجود میاره. شما و همکارانتون باید بدونید از یک روش و محل دیگه ای برای لود مسیرها استفاده کردین. در صورتی که توقع میره روتها و تعریفشون در پوشه routes باشن.
ادامه...
لاراول اسکات / Laravel Scout ابزاری برای قابلیت جستجوی تمام متن(full-text search) در مدل هاست. از درایور هایی مانند Algolia، Meilisearch و خود database لاراول(در حال حاضر MySQL یا PostgreSQL) پشتیانی میکنه.
با یک مثال ساده نصب و استفاده از Scout رو ادامه میدم، فرض کنید جدولی به نام contents با فیلدهای id, title, abstract و text داریم که محتوای وبسایت شما رو در بر میگیره.
ابتدا با استفاده از کامپورز و دستور زیر لاراول اسکات رو نصب میکنیم.
composer require laravel/scout
سپس با artisan vendor:publish فایل پیکربندی اسکات رو به پوشه config اضافه میکنیم.
php artisan vendor:publish --provider="Laravel\Scout\ScoutServiceProvider"
فایل پیکربندی رو باز کنید. (config/scout.php)
همونطور که میبینید driver به طور پیشفرض algolia ست شده. در این مثال تصمیم دارم از PostgreSQL استفاده کنم پس داخل .env مقدار SCOUT_DRIVER رو database قرار میدم. تمام!
SCOUT_DRIVER=database
ادامه...
هنگام پیاده سازی API یکی از شیوه های بسیار کاربردی و مفیدی که میشه استفاده کرد API Resources هست. با استفاده از این روش به جای پاس دادن مدل یا آرایه ای از مدل ها به عنوان response، لایه ای بین Eloquent و خروجی JSON تعریف میشه. در این لایه که Resource/منبع نام داره دقیقا مشخص میکنیم چه دیتایی به عنوان JSON پاس بدیم. این کار باعث میشه response همون چیزی باشه که نیازش داریم، بدون اضافات. یا اینکه ممکن هست لازم بشه همیشه همراه با مدل، روابط خاصی رو هم داشته باشیم و یا در جاهای خاص، خروجی متفاوتی از یک مدل رو به نمایش بذاریم.
به عنوان مثال جدول کاربران شامل نام و نام خانوادگی، بیو، ایمیل، تاریخ ایجاد، بروزرسانی و حذف(deleted_at) رو در نظر بگیرید. برای سرویس لیست کاربران قرار نیست متن بیو رو نشون بدیم. deleted_at هم که برای soft delete هست و 99 درصد اوقات کلا نیازی به نمایش نداریم. پس همونطور که جلوتر پیاده سازیش رو توضیح میدم، دوتا Resource ایجاد میکنیم، یکی برای لیست کاربران که فیلدهای id, name, email در اون تعریف میشه و یکی هم برای نمایش تکی کاربر که شامل تمام فیلدهاست.
شاید با خودتون فکر کنید بدون API Resources در لاراول هم میشه این کار رو انجام داد. بله اما تمیز نیست و قابلیت استفاده مجدد مثل Resources هم ندارید.
ادامه...لاراول پاینت / laravel pint یه code style fixer بر پایه PHP-CS-Fixer هست که به طور خودکار اشتباهات خارج از سبک و اصول کدنویسی رو اصلاح میکنه. البته خود PHP-CS-Fixer قابلیت ادقام با اکثر editor و IDE های محبوب رو داره اما به نظرم آوردنش توی لاراول و استفاده ازش آسونتره.
لاراول پاینت / laravel pint موقع ادغام سورس کدهای خارجی/قدیمی یا زمانی که کد شما دچار بدهی فنی شده کاربرد داره.
- مرتب کردن کامنت های چند خطی
- اصلاح سینتکس و مرتب کردن تو رفتگی آرایهها(داخل کد های قدیمی آرایه رو با array() تعریف میکردیم اما سینتکس جدیدش به [] تغییر پیدا کرده.)
- خط خالی بعد از namespace و tag های php
- ترکیب isset و unset های متوالی
// before
if (isset($a) && isset($b)) {}
unset($a);
unset($b);
// after
if (isset($a, $b)) {}
unset($a, $b);
ادامه...
سلام،
ساعت 10 شب 30 آبان 1401. حال هممون خوب نیست...
بعد از کلی وقت اومدم توی لینکدین تا وضعیت شغلیم رو open to work بزنم. متوجه شدم خیلیا مثل من به علت اوضاع بد موجود شغلشون رو از دست دادن. حس کردم وقت نوشتن تجربیاتم در این زمینه است. من فقر رو با پوست و خون و استخونم درک کردم، اگر ازم بپرسین بزرگترین ترست چیه میگم بی پولی. لازم دونستم بگم توی این شرایط بهتره چکار کرد و توصیه ای براتون دارم.
اینجا قرار نیست توضیح بدم چطور رزومه بهتری بنویسید یا چطور مصاحبه کنید، از یه مقدار عقب ترش میگم و خوشحال میشم این مطلب به دردتون بخوره.
حتما چنین کدی رو قبلا دیدین:
public function index() : JsonResponse
{
$cars = Car::with('facilities', 'type', 'color', 'rentalDetail')->all();
return response()->json($cars, 200);
}
هوم... . مورد بدی توش دیده نمیشه. یک سرویس ساده که لیست خودرو ها رو میده. اما منطق/logic توی کنترلر نوشته شده. هر چند به عقیده من آوردن منطق در کنترلر برای app های کوچک مشکلی به وجود نمیاره اما با رشد نرم افزار بیشتر و بیشتر نیاز به یک ساختار منسجم و متمرکز رو حس میکنید.
به عنوان یک روش جایگزین و بهتر میشه از الگوی طراحی مخزن یا بهتر هست بگیم Repository Design Pattern استفاده کرد. مثل همیشه ساده بگم، در این روش مسئولیت ارتباط و استخراج داده ها رو از روی دوش مدل برمیداریم و اون رو در کلاس های Repository پیاده میکنیم، داخل کنترلر هم فقط متد هاشون رو صدا میزنیم.
public function index() : JsonResponse
{
$cars = $this->carRepository->get();
return response()->json($cars, 200);
}
این روش مزیت های زیادی داره از جمله:
- ایجاد ساختاری منسجم و متمرکز
- حذف کد های تکراری
- توسعه و نگهداری آسانتر
- کاهش خطا و خطایابی سریعتر
- از بین بردن وابستگی های بین مدل و کنترلر
- کد تمیز و واضحتر
خب به نظرم توضیحات تا همین اندازه کافی هست و بهتره بریم سراغ یک نمونه ساده از پیاده سازی این روش تا مزایایی که بهمون میده رو بیشتر درک کنید.
ادامه...گاهی موقع انتخاب زبان برنامه نویسی، ابزار و... بین دوراهی سختی قرار میگیریم. حالا بزرگترین اشتباهی که میشه مرتکب شد مشورت گرفتن در مرحله اوله. چون اغلب، متخصصین همواره وزنه سنگینی به نام تعصب رو به دوش میکشن. نتیجه این میشه که مسیر خودشون رو بهتون پیشنهاد میدن. اونا به شرایط، علاقمندی ها و اتفاقی که قراره برای شما در آینده بیوفته اهمیتی نخواهند داد!
در درجه اول اگر به موردی علاقه دارین امتیاز ویژه ای براش در نظر بگیرید چون خیلی توی موفقیت شما موثر خواهد بود.
میرسیم به بازار کار. دغدغه مهمیه. بازار خودتون رو انتخاب کنید. نیازمندی های داخل کشور با خارج از اون کمی متفاوته. فرض رو بر داخل میگیریم. آگهی های استخدام داخل رو با توجه به علاقه و شرایطی که دارین بررسی کنید.
مثلا اگر محل زندگی شما جوری هست که مجبور به دورکاری هستید، آگهی های استخدام دورکاری رو چک کنید. نیازمندی هاشون، حقوق و دستمزد و... به انتخاب شما کمک میکنه.
فرض کنید بین یادگیری Angular و React گیر کردیم. الان که مشغول نوشتن این مطلب هستم توی یکی از سایت های کاریابی Angular صد و ده تا و React دویست و پنجاه آگهی استخدام داره.
توی مرحله بعد میریم سراغ میزان حقوق دستمزد هر کدومشون و...
همین سرچ کوچیک نشون میده امروز React Developer شانس بیشتری برای استخدام داره.
این کارو توی بازه ها و سایت های مختلف باید انجام داد(هفتگی یا ماهانه). چون گرفتن آمار در یک روز و یک منبع ممکنه شما رو به اشتباه بندازه.
حالا بعد از کلی سبک و سنگین کردن میتونید مشورت بگیرید. اینجا دیگه متوجه تعصب طرف مقابلتون خواهید شد.
گاهی داخل app نیاز به یک فیلد با مقادیر مشخصی داریم. مثل status در جدول payments که میتونه paid یا unpaid باشه. از اونجایی که در پروژه های مختلف این فیلد رو به روش های متفاوتی پیاده میکردن تصمیم گرفتم در موردش کمی بنویسم. به طور کلی سه دیتا تایپ برای این قبیل فیلد ها انتخاب میشن که در موردشون توضیح میدم.
- string/varchar: ساده ترین رویکرد انتخاب دیتا تایپ string هست. وضوح خوبی هم داره. چون هنگام توسعه با یک نگاه به سطر مورد نظرتون متوجه وضعیتش میشید. حتی میتونید توی فرانت دقیقا این رشته رو چاپ کنید(ولی نه توی app های چند زبانه). اما بسته به طول رشته طبیعتا فضایی برای ذخیره سازی در نظر گرفته میشه. هر چند موضوع فضا خیلی وقته به حاشیه رفته و کمتر کسی نگران پر شدن هارد سرورشه، اما اگر سطرهای زیادی داشته باشید هنگام پیمایش اطلاعات، کندی رو حس خواهید کرد. مورد بعدی تغییرات هست. فرض کنید پس از مدتی متوجه غلط املایی در یکی از آیتم ها میشید، تمام سطر ها باید update بشن.
- enum: چیزی که ازش به شدت متنفرم! من دوست ندارم منطق و فرآیند برنامه رو توی دیتابیس ببرم. چرا که مثلا هنگام تغییرات و یا کم و زیاد شدن آیتم ها مجبورم جدول رو هم بروز کنم.
- tinyint: یک رویکرد مناسب برای بهبود سرعت query ها و ملایم در هنگام تغییرات یا افزودن گزینه های بیشتر. نیازی نیست به طور مستقیم با اعداد کار کنید، میتویند از جدول میانی یا ثابت ها بهره برد. من به طور پیشفرض از ثابت ها برای آیتم های کم و جدول در مواقعی که گزینه های زیادی یاا اطلاعات اضافی مثل توضیحات و... داریم استفاده میکنم.
انتخاب هر یک از این روش ها بستگی به شرایط و app شما داره. میتونید string رو برای پروژه های کوچک و اطلاعات کم استفاده کنید. enum توی پروژه هایی که به شما ارث رسیده(یک پروژه قدیمی که مشغول توسعه نسخه جدیدش هستید) و فرآیند ها و منطق برنامه از قبل مشخص هست هزینه تغییرات پایینی داره. tinyint هم زمانی که در یک پروژه بزرگ یا مواقعی که تغییرات زیادی هنگام توسعه اتفاق میوفته کارآمد هست.
برای deploy روش های زیادی وجود داره که اغلب وارد پیچیدگی هایی میشن. من تصمیم دارم کوتاه و ساده در موردش بنویسم و از تنظیمات جانبی اون صرف نظر میکنم.
در مرحله اول به یک http server نیاز داریم. من خودم مخالف استفاده از فریمورک های golang هستم ولی الان دم دسته و مثال رو با gin انجام میدم. شما هر طور خواستین بنویسید.
package main
import (
"github.com/gin-gonic/gin"
"net/http"
)
func main() {
router := gin.Default()
router.GET("/", func(context *gin.Context) {
context.JSON(http.StatusOK, gin.H{
"status": "OK",
})
})
router.Run(":8080")
}
به Dockerfile نیاز داریم. پیشفرض به پورت 8080 گوش میده و app رو اجرا میکنه(پورت http server هم روی 8080 ست شده).
FROM golang:1.13
ENV APP_NAME app
ENV PORT 8080
WORKDIR /go/src/app
CMD ./${APP_NAME}
EXPOSE ${PORT}
ادامه...
توی مطلب قبلی جستجو با استفاده از wildcard query رو توضیح دادم. الگو های wildcard ساده بودن اما کار راه انداز. برای تعریف الگوهای کامل و البته پیچیده تر میشه از عبارات باقاعده یا regex هم استفاده کرد. در این صفحه میتونید ببینید داخل الستیک چه عملگر هایی از regex پشتیبانی میشه.
مثال زیر اسنادی رو که فیلد user شون با k شروع و با y تموم بشه رو match میکنه.
GET /_search
{
"query": {
"regexp": {
"user": {
"value": "k.*y"
}
}
}
}
با استفاده از wildcard query میتونید الگو های ساده ای برای matching تعریف کنید. wildcard از دو عملگر پشتیبانی میکنه.
? : یک کاراکتر تکی رو match میکنه.
* : صفر یا بیشتر. هر تعداد کاراکترُ match میکنه.
مثال زیر اسنادی رو پیدا میکنه که نویسنده هاشون با حرف t شروع شده باشن.
GET /_search
{
"query": {
"wildcard": {
"authors": {
"value": "t*"
}
}
}
}
قبلا در مورد جستجوی ساده نوشتم. توی این مطلب میخواییم ببینیم چطور برای جستجو از عملگر های and، or و not در query استفاده کنیم. boolean query این قابلیت رو به ما میده. باهاش query های مرکب/ترکیبی مینویسیم. این پرس و جوی مرکب شامل must، filter، should و must_not میشه.
- must: برای matching یا تطابق در اسناد استفاده میشه. و روی score_ تاثیر میذاره که توی مطالب قبلی در موردش توضیح دادم. برابر با AND
- filter: برای فیلتر اسناد هست و روی score_ تاثیر نداره.
- should: مواردی رو درش قرار میدیم که میخواییم در اسناد وجود داشته باشه. برابر با OR
- must_not: برعکس must، مواردی که در این بخش تعریف میکنیم نباید در اسناد وجود داشته باشن. اینم میشه گفت یه مدل فیلتر هست و معادل عملگر NOT
ادامه...توی مطالب قبلی هنگام ارسال درخواست و در قسمت body از عبارت query برای جستجوهامون استفاده کردیم.
{
...
"multi_match": {
"query": "guide"
}
...
}
در واقع query به این سوال پاسخ میده: چقدر اسناد موجود با مقدار query(در اینجا guide) مطابقت داره. الستیک سرچ میزان این مطابقت رو در خروجی درخواست و متا فیلد score_ محاسبه میکنه و قرار میده. مرتب سازی/sort خروجی هم بر همین اساس و معیاره.
ادامه...توی مطلب قبلی در مورد تفاوت match و multi_match توضیح دادم. معمولا هنگام جستجو و استفاده از multi_match بهتره اولویت های بالاتر یا پایین تری برای فیلد هامون در نظر بگیریم. به طور پیشفرض الستیک سرچ هنگام جستجو و match کردن بین فیلد ها تفاوتی قائل نمیشه. الستیک معیاری به نام boost داره که مقدار اولیه اش 1.0 هست و شما میتونید با افزایش این مقدار به فیلدهاتون برای match شدن اولویت بدین.
مثلا یک document با دو فیلد title و content رو در نظر بگیرید. میخواییم هنگام جستجو اولویت title برای match شدن دو برابر content باشه. چون از نظر ما title مهمتره و اگر بتونیم در title چیزی پیدا کنیم به احتمال خیلی زیاد نتیجه جستجوی بهتری خواهیم داشت.
برای boosting یا اولویت دادن دو راه وجود داره. هنگام تعریف mappings یا زمان جستجو. اگر سیاست های جستجوی ما مشخص باشه بهتره داخل mapping این کار انجام بشه.
ادامه...توی مطلب قبلی در مورد جستجوی ساده و پایه در الستیک سرچ نوشتم. برای همه ی ما اتفاق افتاده عمدی یا غیر عمدی داخل گوگل چیز اشتباهی رو جستجو کردیم و خودش توضیح داده آیا منظورت فلان مورد بود؟ حقیقتا گوگل تشخیص میده ما اشتباه نوشتیم و اون رو بهمون گوشزد میکنه. بیایید اسم این مدل جستجو رو بذاریم جستجوی کثیف یا درهم. اتفاقا الستیک هم چنین قابلیتی رو بهمون میده و خوشبختانه برای فارسی هم به خوبی کار میکنه :)
خب برای جستجوی کثیف چکار باید کرد؟ ما توی این مدل کوئری که خود استیک بهش fuzzy query میگه به جای multi_match یا match از fuzzy استفاده میکنیم! به همین راحتی :)
fuzzy query مواردی که مشابه و نزدیک مورد جستجوی ماست رو هم match میکنه. برای اینکار fuzzy همه ی حالت های ممکن رو بررسی میکنه و نتایجی که بیشترین مطابقت رو دارنُ برمیگردونه. این نکته رو گفتم که بدونید مثل جستجو های ساده کم هزینه نیست و در جای مناسب نه همه جا ازش استفده کنید. مثلا گوگل نمیاد توی اسنادش fuzzy search کنه. اون عبارت جستجوی شما رو fuzzy search میکنه تا برای جستجوی دقیق اصلاحش کنید.
ادامه...اولین مطلب در مورد کوئری های جستجو در elasticsearch رو با ساده ترین روش یا به عبارتی basic match شروع میکنم. دو روش برای match کردن یا جستجو وجود داره. روش اول از طریق پارامتر داخل url هست و روش دوم ارسال query در body درخواست/request.
توی روش اول هیچ کنترلی روی خروجی الستیک ندارین ولی خب کار راه انداره. اما برعکس، با روش دوم میتونید فیلد های جستجو و موارد دیگه ای که بعدا بیشتر در موردش مینویسم رو مشخص یا تنظیم کنید.
مثال: جستجوی guide در ایندکس developit_ir. کلمه guide در تمام فیلد ها جستجو میشه.
GET /developit_ir/_search?q=guide
نمونه خروجی:
"hits": [
{
"_index": "developit_ir",
"_type": "_doc",
"_id": "1",
"_score": 3.541,
"_source": {
"title": "developit.ir",
"authors": [
"ehsan rezaei"
],
"summary": "elasticsearch guide :)",
"publish_date": "2020-01-01"
}
}
]
ادامه...
سلام. صدای من رو از رسپینا نسخه 3 میشنوید :دی
این نسخه رو با نصب افزونه twig در Yii2 افتتاح میکنیم. هر چند من زیاد با template engine موافق نیستم و فکر میکنم مناسب پروژه های کوچیک نیست و صرفه زمانی و اقتصادی نداره. ولی خب به هر حال گاهی وجودش لازمه.
دستور زیرُ اجرا کنید:
php composer.phar require --prefer-dist yiisoft/yii2-twig
یا توی فایل کامپوزر قرارش بدین:
"yiisoft/yii2-twig": "~2.0.0"
ادامه...
به مناسبت روز جهانی چپ دست ها البته با کمی تاخیر! باید بگم به عنوان یک چپ دست فکر نکم! نکته ی قابل توجه اینکه از پیام های داخل شبکه های اجتماعی متوجه شدم 10 درصد جامعه چپ دست نیستن و برعکس، راست دست ها در اقلیت به سر میبرن!
خب بیایین واقع بین باشیم، اگر 10 تا از رهبران بزرگ جهان رو تحت عنوان چپ دست های ماندگار تاریخ لیست کردن نماد خاص بودن نیست چون بقیه شون راست دست بودن! در کل فکر نمیکنم این تمایل استفاده از دست چپ به جز تفاوت که ممکنه در دوران رشد جنین اتفاق بیوفته چیز دیگه ای برامون داشته باشه.
و البته دردسر! موردی که کمتر بهش اشاره شده. توجه داشته باشین که بسیاری از ابزارها برای افراد راست دست طراحی شده. مثلا خود من با دکمه ی روشن و خاموش ماشین ریش تراشم مشکل دارم و باید از دست راستم برای استفاده اش کمک بگیرم.
البته متخصصین همیشه به فکر ما بودن و ابزار هایی مناسب حال ما تولید کردن ولی خب ما نتونستیم جایی پیداشون کنیم. من نوعی توی دانشگاه هیچ وقت موفق نشدم صندلی چپ دست پیدا کنم :|
یادمه این موضوع چپ دست بودن رو به نیم کره های مغز هم ربط میدادن که توجه تون رو به این نقل قول جلب میکنم:
در مطالعهای در سال ۲۰۱۳، تصاویر سهبعدی مغز هزار نفر مورد بررسی قرار گرفت و با استفاده از اسکنر MRI، میزان فعالیت هردو نیمکره اندازهگیری شد. نتایج نشان میداد که هر انسان، از هردو نیمکره مغزی خود بهره میبرد و بخشی بر دیگری غالب نیست.
البته توجه داشته باشین ما در طول زندگی و فعالیتی که داریم به طور خواسته یا ناخواسته یکی از نیم کره های مغزمون رو قوی و اون یکی رو ضعیف میکنیم.
در انتها این روزُ به همه ی چپول ها تبریک میگم و آرزو میکنم با موفقیت هایی که تو زندگی به دست میارین خاص بشین نه این تفاوت.
به این نتیجه رسیدم توی برنامه نویسی دست رو هر چیزی بذاری(تکنولوژی، فریمورک و...) بازم پیدا میشن که بیان و یه عیبی روش بذارن :)
آیا واقعا جای عیب و ایراد گرفتن وجود داره؟ بله. حتما اینطور هست و اتفاقا کار آسونیه :)
مزایا و معایب توی حرفه ما همیشه کنار هم بودن و تصمیم گیری در مورد اینکه چه کسی از چه چیزی استفاده کنه به جمله ی "بستگی دارد به..." یا در کل "بستگی دارد ها" گره خورده.
موضوع دقیقا اینجا مشخص میشه. ممکن هست انتخاب یک شخص برای من نوعی و یا شخص دیگه ای سم باشه!
عمدتا 4 دلیل اصلی برای این موضوع وجود داره.
طرف مقابل با ایراد گرفتن و گاها مسخره کردن به دنبال بزرگ جلوه دادن خودشه. مثل سیگار که نوجوون ها با گذاشتنش گوشه ی لب حس بزرگی بهشون دست میده. توی برنامه نویسی هم همینطوره. مثلا میتونی بگی فلان زبان برنامه نویسی آشغاله تا بگن wow چه برنامه نویس خفنی و از این جور حرف ها. جالب اینجاست که اغلب نظراتشون پشتوانه و دلیل و مدرک نداره. اصلا دنبال اون موضوعی که در موردش ایراد میگیرن نرفتن و بیشتر حرف های دیگرانُ تکرار میکنن.
شاید بتونم با مورد اولی ها کنار بیام اما دومی نه. اینکه سلیقه ی خودت رو درست بدونی و بقیه رو غلط فاجعه است... یادمه یه مطلب در مورد استاندارد کدنویسی داخل یه فریمورک رو مطالعه میکردم که اولش به این جمله برخوردم:
هیچ قانون سختگیرانه ای برای شما وجود نداره...
همین برای من کافی بود تا تمام اون مقاله رو چند بار مطالعه کنم! درسته. قانونی وجود نداره. اگر با رعایت استاندارد از روش دیگه ای مساله رو حل کردن. متفاوت با اون چیزی که توی ذهن شما میچرخه اشتباه نیست فقط متفاوته و شاید هم درست تر باشه البته.
سوم. جبهه گرفتن.
گاها شخص با دیدن اینکه فرد یا افرادی مسیر دیگه ای رو برای خودشون انتخاب کردن. مسیری که نه به سلیقه و نه مورد علاقه شون بوده خودشون رو میبازن. به یکباره سمبلی شدین که باعث ناراحتیشون میشید و آینه ای جلوی روشون که ممکنه عیب هاشون رو به وسیله ی شما ببینن. سخت ترین راه تحقیق و بررسی و در صورت لزوم تغییر هست و راحت ترین را کوبیدن شما...
چهارم. اطلاعات کهنه.
یادمه با دو نفر در مورد اینکه فلان چیز به درد نمیخوره بحث میکردم. بحث که نبود، ازشون دلیل و سند معتبر میخواستم تا ادعاهاشون رو قبول کنم. اولی که معلوم شد اصلا در جای مناسبی موضوع رو مقایسه نمیکنه و دومی اطلاعاتی که میداد برای حدود 6 سال پیش بود!
نتیجه اینکه همیشه ایراد هست و اتفاقا خوبه که باشه اما دو چیز مهمه. ایراد گیرنده از نظر فنی و اخلاقی انسان بزرگی باشه و اینکه صحبت هاش همراه با پشتوانه معتبری ارائه بشه. این پشتوانه میتونه شامل سند، دلیل و مدرک و نهایتا تجربه باشه.
اما اگر به اون 4 دسته از توسعه دهندگان بالا برخوردین هدفونتون رو بذارید گوشتون و با هر چیزی که خوشحالتون میکنه کار کنید. از افرادی که این مسائل ساده رو درک نمیکنن نمیشه توقع ساکت شدن داشت.
هنگامی که موضوع کار با داده ها در application مطرح میشه احتمالا نیاز به یک ORM پیدا خواهید کرد. ORM یک لایه بین پایگاه داده و application شماست. که به وسیله اون عملیات CRUD یا به عبارت دیگه create, read, update, delete به آسونی انجام میپذیره. بیشتر از این به ORM نمیپردازم چون در حال حاضر اکثر فریمورک های مدرن ازش استفاده میکنن و بعید میدونم شما تا الان با اون کار نکرده باشید.
دو الگو پیاده سازی محبوب ORM ها Active Record و Data Mapper هست. در این مقاله تصمیم دارم به تفاوت بین این دو الگو بپردازم. مزایا و معایبشون چی هست و چطور میشه یکی از این الگو ها رو برای کار خودمون انتخاب کنیم.
ادامه...در مهندسی نرم افزار، design patterns(الگوهای طراحی) راه حلهای قابل استفاده برای مشکلاتی هستند که معمولاً در طراحی نرمافزار اتفاق می افتند.
طرح های از پیش ساخته شدهای که میتوانید برای حل مشکلات آنها را سفارشی کنید. شما نمیتوانید یک الگو را با جستجو در stackoverflow پیدا و در برنامه خود کپی کنید. الگو ها یک قطعه کد خاص نیستند، مفاهیم کلی برای حل مشکلات خاص هستند. شما باید با درک این مفاهیم آنها را در برنامه خود پیادهسازی کنید.
Refactoring مجموعهای از تکنیکهاست که به منظور اصلاح و بهبود کدهای قبلی بدون تغییر در عملکرد و رفتارشان جهت خوانایی، کارامدی و قابلیت نگهداری بیشتر انجام میشود.
در کتاب Refactoring اثر Martin Fowler نوشته شده: refactoring تکنیک مرتب/منظم سازی برای تجدید ساختار کد موجود است. تغییر ساختار داخلی کد بدون تغییر رفتار خارجی آن.
refactoring یک سرمایهگذاری و راه حلی برای مقابله با کد کثیف و بدهی فنی است که باعث کاهش هزینههای توسعه نرمافزار در آینده خواهد شد.