متاسفانه نظام آموزشی کشور ما در مدرسه و دانشگاه (به جزء دانشگاه‌ها و مدارس خاص) جوری بوده که یادگیری هر موضوعی رو به دو بخش کاملا متفاوت تئوری و عملی تقسیم کرده. در ذهن بیشتر افراد، یادگیری تئوری یه روش خسته‌کننده و بی فایده هست اما یادگیری عملی روشی جذاب و مفید به حساب میاد. این شکاف توی کارهایی مثل برنامه‌نویسی خیلی عمیق‌تره! خیلی از افراد فقط آموزش‌هایی رو مطالعه میکنند که توی هر پاراگراف حداقل یه خط کد بهشون یاد بده وگرنه خوندن اون آموزش یا کتاب رو بی‌ارزش و وقت تلف کردن میدونن.

این طرز تفکر باعث میشه که بیشتر افراد برای یادگیری برنامه‌نویسی روش پروژه محور رو انتخاب کنند. این انتخاب به خودی خود مشکلی نداره ولی مشکل اونجاست که بنظر من درک درستی از یادگیری پروژه محور ندارند. معمولا یادگیری پروژه محورشون شبیه فرآیند زیر هست:

۱- تعریف پروژه: بیشتر افراد در شروع کار، توانایی تعریف پروژه برای خودشون رو ندارند. در نتیجه با پرس و جو از بقیه یه پروژه مناسب پیدا میکنند.

۲- انجام پروژه: درصد کمی از افراد پیاده‌سازی پروژه رو با سرچ عبارت‌هایی شبیه How blah blah شروع می‌کنند و بعد هر تیکه کدی که پیدا میکنند رو داخل پروژه کپی میکنند. بقیه از همون فردی که پروژه رو براشون تعریف کرده، اینقدر سوال میپرسند تا ذره ذره یه سری نمونه کد ازش بگیرند و عینا داخل پروژه کپی کنند.

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

تا پروژه کامل بشه، مراحل ۲ و ۳ بینهایت بار تکرار میشه. اینجوری یاد گرفتن برنامه‌نویسی به شدت اتلاف انرژی و وقت داره. چون کسی که پروژه رو ساخته چیز زیادی رو یاد نگرفته، حتی اگر قرار باشه دوباره یه پروژه مشابه انجام بده، سر هر تفاوت پروژه‌ی جدید با قبلی، دوباره باید بارها مرحله‌ی ۲ و۳ رو تکرار کنه. تازه نکته‌ی مهم اینه به سازنده‌ی همچین پروژه‌ای نباید برنامه‌نویس گفت. چون در اینصورت همه افراد دنیا هم معمار میشدن، چون به هر کسی چهارتا آجر و یه کیسه سیمان (معادل کدهای آماده توی برنامه‌نویسی) بدی، بالاخره با سعی و خطا میتونه یه خونه برای خودش بسازه ولی این فرد هم معمار حساب نمیشه!! فقط یه سرپناه موقت برای خودش ساخته که احتمالا در آینده‌ای نزدیک خراب میشه.

باز تاکید میکنم یادگیری پروژه محور بد نیست، مزایای خودشو داره ولی به شرطی که درست انجام بشه. از دید من تفاوت یادگیری پروژه محور با حالت معمولی (گام به گام) در اینه که بجای خوندن فصل‌های یه کتاب آموزش برنامه‌نویسی بصورت فصل به فصل، موضوعاتی که برای ساخت پروژه نیازه رو خوند. این روش با اون فرآیند ۳ مرحله‌ای که بالاتر گفتم خیلی فرق داره. فرض کنید قراره برنامه‌ای به اسم X برای نمایش نقشه در اندروید ساخته بشه، باید بجای اینکه دنبال نمونه کد نمایش نقشه گشت، توی داکیومنت‌های رسمی اندروید سر فصل‌های مرتبط با نقشه‌اش رو خوند یا مثلا به کتاب‌های رفرنس مثل busy coder رجوع کرد و فصل پیاده‌سازی نقشه‌ی اون رو نگاه کرد. حالا بعد از آشنا شدن با مفاهیم مربوط به نقشه، از روی نمونه مثال‌های موجود در اینترنت، کد برنامه X نوشته بشه.

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

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

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

در همین راستا امروز یک کتاب میخوندم، آزمایش جالبی رو تعریف کرده بود. آزمایش اینطوری بوده که افراد شرکت‌کننده‌ در کلاس سفالگری رو به دو گروه A و B تقسیم کرده بودند. استاد کلاس به گروه A میگه که تا آخر ترم فقط یکبار فرصت دارند که یک سفال رو تحویل بدن و نمره‌ی پایانیشون رو بگیرن، و به گروه B میگه نمره‌ی پایانیشون براساس وزن همه سفال‌هایی که تا آخر ترم تحویل میدن محاسبه میشه (یعنی مهم نیست که خوشگله یا زشت، فقط وزنش مهمه).

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

برخلاف گروه B، افراد گروه A بجای اینکه بخوان تلاش کنند و سفال بسازن، کل ترم رو درگیر مسائل تئوری بودن که چطور میشه بهترین سفال ممکن رو ساخت! در نهایت چون شبیه افراد گروه B نتونستن ساخت سفال رو خیلی تمرین کنن، نتونستن سفال عالی که در ذهنشون بوده رو در واقعیت بسازن.

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

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

۱- تولید محتوا: مهمترین مشکلی که هس اینه شرکت‌ها هیچ محتوایی تولید نمی‌کنند! مثلا شرکت کافه بازار یا ایکس با این همه نیروی خوب و پروژه‌هایی که روش کار میکنه، میتونه با تولید کلی محتوای عالی (آموزشی، اشتراک گذاشتن تجارب، اوپن‌سورس کردن پروژه‌ها) به افزایش تخصص برنامه‌نویس‌های ایرانی کمک بکنه که در آینده هم از همینا نیرو جذب میکنه. برای مقایسه میتونید به بلاگ‌های فنی شرکت‌های خارجی برید.

۲- جذب کارآموز: تقریبا از هر ۵ تا درخواست استخدام حدود ۴تاشون نیروی کار متخصص میخوان، و از هر ۵ نفر جویای کار، حدود ۳ نفر دنبال کارآموزی هستند. در نتیجه خیلیا همین اول راه گیر می‌کنند و با اینکه علاقه دارن ولی جایی رو برای رشد کردن پیدا نمی‌کنند. تازه بماند که بعضی از شرکت‌ها هم نمیدونن کارآموز چیه! فکر می‌کنند کل قضیه اینه که یکی رو استخدام کنند که چیزی بلد نیس و بهش فشار بیارن تا یه پروژه‌ی سخت رو به تنهایی تموم کنه. بعد تازه پیش خودشون حس می‌کنند کلی به اون برنامه‌نویس لطف می‌کنند و خودشونم از سرمایه‌گذاری که در جذب کارآموز کردن به سود رسیدن. البته این ایده معمولا نتیجه برعکس میده، یعنی نه تنها اون برنامه‌نویس دانش عمیقی یاد نمیگیره، حتی اون پروژه رو هم که زده، احتمالا باید از اول نوشت.

 

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

پ.ن۲: قطعا منظورم ۱۰۰درصد شرکت‌ها نیست، بعضی شرکت‌ها به این موارد اهمیت میدن. البته بیشتر به مورد ۲ اهمیت میدن، کمتر شرکتی رو دیدم که درگیر مورد ۱ باشه.

پ.ن۳: من متخصص منابع انسانی نیستم، بیشتر به عنوان یه برنامه‌نویس که خودش دوست داره تخصص بیشتری داشته باشه نظرمو نوشتم.

خیلی وقت بود که دوست داشتم روی اپ‌های ماژولار کار کنم، این دوست داشتن مقدمه‌ی یه هفته‌ای مطالعه و تست بود که در نهایت خروجیش تبدیل به ریپوی AndroidModularization توی گیت‌هاب شد. در کنار هدف اصلی (اپ ماژولار) یه هدف فرعی هم داشتم که یه نمونه کد authentication با قابلیت رفرش شدن توکن برای وب‌سرویس moviesapi.ir درست کنم. اگر بخوام خلاصش کنم میشه این پروژه یه اپ ماژولار هست که از قابلیت‌های وب‌سرویس moviesapi.ir استفاده میکنه.

توی توسعه این پروژه از کتابخونه‌هایی مثل Rxjava ,Dagger2 ,Retrofit, Room , Databinding و … استفاده شده ولی تمرکز اصلی روی ساخت اپ ماژولار با استفاده از Dagger2 بوده. یعنی اگر میخواید RxJava یاد بگیرید، توی این پروژه نباید دنبال Best Practiceهاش باشید.

ادامه …

روزی که جنریتور “حلما” رو درست کردم، تصمیم گرفتم Open Sourceش کنم. چون اولین بار بود که میخواستم اینکارو بکنم، هیچ ایده‌ای نداشتم که از کجا باید شروع کرد یا باید به چه نکاتی توجه کنم. به همین دلیل، پیش یکی از بهترین دوستام به اسم گوگل!! رفتم تا مثل همیشه کمکم کنه، توی گوگل با کلیدواژه‌های start، open source و how جستجو کردم. بیشتر مقاله‌هایی که آورد رو خوندم، یه تعدادیشون نکته‌های خیلی خوب داشتند، این نکته‌هارو توی Evernote نوشتم تا سرفرصت تبدیلشون کنم به این مقاله‌ای که الان میخونید. ادامه …

هر موقع در مورد اینکه توی شرکت‌های خوب خارجی TDD کار میکنند صحبت میشد، پیش خودم میگفتم که خب توی ایران با توجه به ددلاین‌های پروژه، اخلاق کارفرما و … نمیشه مثل اونا بود وگرنه منم حتما TDD کار میکردم. برای خودم تست ننوشتن رو همینجوری توجیه میکردم تا اینکه تصمیم گرفتم یه پروژه که فرصت زیاد داشت رو بصورت TDD انجام بدم. همیشه فکرمیکردم Unit Testing خیلی راحته و اگر توی تست نوشتن بخوام جاییش گیر کنم قسمت Integration Testing و End to End Testing هست. ولی همون اول کار تا شروع به Unit Test نوشتن کردم، برام کلی سوال جورواجور پیش اومد! مثلا چطوری باید تست‌هارو نامگذاری کرد؟ چطوری میشه متدهایی که نیاز دارند با پارامترهای زیاد تست بشن رو تست کرد؟ حتما باید برای تست نوشتن از mockito استفاده کرد یا نه؟ ادامه …

میخواستم وقتی رسپبری‌پای خریدم، از کارهای جالبی که باهاش میکنم توی کانال و بلاگم بنویسم! ولی خب متاسفانه خیلی فرصت نمیشه سراغش برم، این تعطیلات چند روزه باعث شد تا بعد مدت‌ها سعی کنم کارهایی که میخواستم باهاش انجام بدم رو عملی کنم. مهمترین کارم این بود که بجای وصل کردن لپ‌تاپ به تلویزیون از رسپبری‌پای برای دیدن سریال یا ویدئوهای یوتیوب استفاده کنم. یه روزی درگیر این بودم که یه فیلم FullHD رو روی رسپبری‌پای با زیرنویس فارسی اجرا کنم که آخرشم نشد. (البته میخواستم اینکار رو روی Raspbian انجام بدم، OMXPlayer فیلمو خیلی خوب پخش میکرد ولی با زیرنویس فارسی مشکل داشت)

به این فکرمیکردم که چیکار کنم، یادم افتاد تلویزیون یه بخشی داره که مستقیم به یوتیوب وصل میشه ولی خب اینترنت ایران اون رو باز نمیکنه. درواقع اگر من بتونم یه شبکه‌ای داشته باشم که این قضیه دسترسی رو حل کنه! نه تنها میتونم با همون تلویزیون ویدئوهای یوتیوب رو ببینم، هرجایی که مشکلاتی از قبیل تحریم و دسترسی داشتم (مثل کنسول PS4 یا بیلد کردن پروژه‌های اندروید) با وصل شدن به این شبکه حل میشه!

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

تقریبا یکسال پیش بود که پست کوتاهی در مورد “منابع الهام بخش برای ساخت UI اپ موبایل” نوشتم و تعدادی سایت رو معرفی کردم ولی یه مشکلی وجود داشت، اونم این بود که همه‌ی UIها با زبان انگلیسی درست شده بودند و معمولا وقتی همین UI‌ها رو با زبان فارسی درست می‌کنید، درصد زیادی از زیباییشون از دست میدن. برای حل این مشکل با بچه‌های هارمس تصمیم گرفتیم خودمون زمان بذاریم و از اپ‌های اندرویدی معروف ایرانی اسکرین‌شات تهیه کنیم تا در اختیار همه‌ی برنامه‌نویسان و طراحان فارسی‌زبان بذاریم. خروجی این تصمیم، سایت UI Screenshots شده که در ادامه بیشتر در موردش توضیح دادم. ادامه …

چند وقت پیش یه AMA (فکرکنم معادل فارسیش میشه “از هرچیزی بپرس”) توی reddit بود که تیم توسعه‌دهنده‌ی دگر سوالاتی که ازشون پرسیده شده رو جواب دادن. دیشب وقت کردم بخونمش و نکاتی که بنظرم جالب رو بود رو در ادامه نوشتم. البته اگر میخواید خودتون همه‌ی سوال‌ و جواب‌هارو بخونید، میتونید به لینک زیر برید.

لینک AMA تیم دگر توی reddit ادامه …

اگر یادتون باشه آخرین نمونه پروژه‌ای که توی گیت‌هاب گذاشتم (SingleAcitvityPattern) با زبان کاتلین نوشته شده بود. هدف اصلیم از این پروژه پیاده‌سازی الگوی Single Activity با استفاده از فرگمنت‌ها و هدف فرعیم آشنایی بیشتر با کاتلین بود. قبلا در مورد هدف اصلی یه پست بلاگ نوشتم و الان میخوام در رابطه با هدف فرعی صحبت کنم. استفاده از کاتلین زمان بیشتری ازم گرفت ولی در عوض با نکات مختلفی آشنا شدم که در ادامه براتون تعریف میکنم.

 

ترکیب کاتلین و Dagger

دیروز چندساعتی درگیر این بودم که چطوری توی پروژه‌ میتونم NavigationManager رو از طریق Dagger به فرگمنت‌ها اینجکت کنم. با توجه به ایده‌ای که در مورد NavigationManager داشتم، میشه توی یه پروژه چندتا NavigationManager داشت که هرکدوم مدیریت تعدادی از فرگمنت‌هارو به عهده داشته‌ باشه (اگر پست قبلی بلاگمو در مورد این پروژه خوندید و ایده‌مو در رابطه با NavigationManager متوجه نشدید، دلیلش اینه توضیحش توی متن سخته! شاید بعدا یه ویدیو برای توضیحش درست کردم)، این ایده استفاده از Dagger برای اینجکت کردنو خیلی سخت کرده بود. البته توی این چند ساعت، درگیر دو تا مشکل دیگه هم داشتم.

اولین مشکل این بود که وقتی Dagger رو به پروژه اضافه کردم، موقع اجرا خطای NoClassDefFoundError میداد!!! آخرش بعد از کلی تلاش و سرچ کردن، فهمیدم مشکل از من نیست! مشکل از Dagger هست و نسخه جدید ۲٫۱۴٫۱ رو فقط به خاطر حل این مشکل ریلیز کردن.😑

مشکل دوم این بود که وقتی میخواستم بصورت همزمان دو انوتیشن @inject و یه qualifire به اسم @PerFragment رو برای یه فیلد استفاده کنم، برنامه کرش میکرد!! بعد از کلی دیباگ کردن و بررسی سورس‌های جنریت شده‌ی Dagger، متوجه شدم qualifireیی که میذارم اصلا اثر نمیکنه، انگار وجود نداره!! در نهایت با سرچ کردن، فهمیدم اگر میخوام همچین کاری رو توی کاتلین بکنم، باید از یه انوتیشن به اسم @field استفاده کنم. وقتی کد رو به شکل زیر تغییر دادم، برنامه درست شد.

این نکته رو از یه issue توی ریپوی Dagger یاد گرفتم. کلا داخل این issue در مورد Best Practiceهای استفاده از Dagger توی کاتلین صحبت میکنن. نکته‌های جالبی داخلش هست.

https://github.com/google/dagger/issues/900

 

تفاوت onCreateView با onViewCreated

همون شبی که پروژه رو توی گیت‌هاب گذاشتم، شایان پوروطن لطف کرد و ۲ ۳ ساعتی در مورد جزییات پیاده‌سازی پروژه صحبت کردیم. جدای همه نکته‌هایی که ازش یاد گرفتم، یه نکته جالب و ساده هم یادم داد. قضیه این بود که من غر میزدم چرا نمیتونیم داخل متد onCreateView فرگمنت از قابلیت static layout imports کاتلین استفاده کنیم و مجبوریم بجاش کدمون رو توی متد onViewCreated بنویسم، اینجا بود که شایان بهم گفت خب درستش همینه و نه اونکاری که من تا الان میکردم😀

تا اون لحظه، هرچی سورس و مثال دیده بودم، همشون توی onCreateView کار findview رو انجام داده بودن و این باعث شده بود که فکرکنم راه درستش اینه!!! درصورتی که اشتباه بود. البته خیلی کم پیش میاد که این اشتباه باعث باگ بشه ولی بهرحال امکانش هست. دلیل اشتباه بودنش اینه که اگر layout پیچیده باشه، احتمال داره بعضی از viewها هنوز توی onCreateView ساخته نشده باشند!! برای اطمینان بیشتر باید هرکاری با view دارید، توی onViewCreated انجام بدید.

 

کشف ریپوهای کاتلینی-اندرویدی

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

اولی android-ktx که extensionهای کاربردی اندروید هست.

https://github.com/android/android-ktx

دومی kotlin-guides که راهنمای استفاده از کاتلین در پروژه‌های اندروید هست.

https://github.com/android/kotlin-guides