چطوری یه برنامه گسترش پذیر طراحی کنیم؟!

چطوری یه برنامه گسترش پذیر طراحی کنیم؟!

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

بریم سراغ منطق هایی که باید در نظر بگیرم.

منطق اول» گسترش عمودی

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

 

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

مثلا در بخش نوشتن یک پست جدید در وبلاگ سایتم نیاز دارم تا نام کاربری که لاگین کرده است را داشته باشم. درحالتی که احراز هویت کاربران بخش مجزایی برای خودش دارد من تنها کافیست که یک مسیری را صدا بزنم تا بخش احراز هویت کاربران در جواب به من نام کاربری، کاربر لاگین شده را برگرداند.

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

 

منطق دوم» گسترش افقی

گسترش افقی زمانی نیاز میشود که ما با درخواست های زیاد و یا هزینه بر از نظر زمان یا منابع طرفیم. در لایه ی طراحی باید ما به این فکر کنیم که ممکن است نیاز شود از برنامه ی ما و یا بخشی از آن نمونه هایی ساخته شود و پشت سر یک Load Balancer قرار بگیرد تا درخواست ها را بین چند نمونه از برنامه ی ما توضیع کند.

 

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

برای مثال من Web Application ای نوشته ام که قرار است پاسخ تعداد زیادی Mobile Application را بدهد در ابتدا با 1000 کاربر که برنامه ی من را روی موبایلشان نصب کرده اند طرف هستم. و هر کاربر در دقیقه قرار است مثلا یک بار یک درخواستی را به سمت سرور من ارسال کند که من ابتدا باید تشخیص بدهم که آیا این کاربر برای دیدن امکانات برنامه ی من شارژ کافی دارد یا خیر. و بعد در صورت مثبت بودن نتیجه امکانات برنامه را به او نمایش دهم و در غیر اینصورت پیام خطایی را برایش چاپ کنم.

حالا فرض کنید که برنامه ی شما موفق بود و توسط 1000000000 کاربر نصب و مورد استفاده قرار گرفت. در این صورت باید چه کرد؟! همانطور که حدس زدید حالا سرور برای پردازش ورودی کاربران به مشکل میخورد و درخواست ها یا با خطاهای 500 مواجه میشوند و یا به کندی پاسخ داده میشوند.

اینجاست که گسترش افقی به کارم میآید و میتوانم با نمونه سازی از روی بخش ورودی برنامه ام (همان بخشی که شارژ کاربر را در هر درخواست قرار بود بررسی کند) و قرار دادن یک Load Balancer جلوی آن ها به ازای هر n درخواستی که بهم میرسد یک نمونه ی دیگر اضافه کنم تا نه خطایی رخ بدهد و نه کندی در پاسخ به کاربران.

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

 

منطق سوم» گسترش عمقی

گسترش عمقی یعنی اینکه ما در زمان طراحی برنامه داده های بخش های مختلف برنامه را به گونه ای تفکیک و دسته بندی کنیم که در زمان نیاز بتوانی آنها را برروی سرورهای مختلف یا منابع مختلف قرار بدهیم. با این کار در لایه ی دیتابیس تفکیک خوبی اتفاق می افتد که باعث میشود بتوانیم هرچه بهتر تکنیک های Database Scaling را پیاده سازی کنیم و یا امنیت داده ها را حفظ کنیم.

 

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

 

عالمِ عاملِ عاشق باشید.

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