مقدمه:
استفاده مجدد از کدها (Code-Reusability) و جداسازی منطق برنامه از محتوا، از موضوعات هميشگی برنامه نويسی وب هستند. با استفاده از Template Engineها و فريم ورکهای بر پايه MVC، به خوبی می توان منطق (Logic) و محتوا (Content) را از هم جدا کرد. با وجود اين، استفاده مجدد از کد، بخصوص برای کسانی که با واسطهای کاربری (UI) سر و کار دارند معضلی است که حتی برنامه نويسان باتجربه هم با آن دست به گريبان هستند. علت اين امر فقدان الگویی است که امکان هندل کردن المنتهای وب مرتبط با UI را به طریقه شی گرا فراهم کند. برای مثال، برنامه نویسان برای بازيابی ورودی کاربر در يک فيلد متنی از يک فرم وب، در سمت سرويس دهنده (Server) معمولا از آرايه های POST_$ يا GET_$ استفاده می کنند که نام فيلد متنی در سمت سرويس گيرنده (Client) تبديل به یک شاخص (Index) در اين آرايه ها می شود. برای تشخيص اينکه آيا دکمه Submit کليک شده يا نه، معمولا نام دکمه Submit که به صورت شاخص در آرايه های سراسری ذکر شده، ظاهر میشود، بررسی شده و يا اينکه از Set بودن یا نبودن يک متغير پنهانی فرم به Submit شدن فرم پی میبریم. برای استفاده مجدد از چنين کدی، میبایست آنرا در جاهای مختلف Cut و Paste کنيم که از اين نظر مستعد خطاست و تمام تلاش ما را برای جداسازی منطق از محتوا ناکام میگذارد. بر اين اساس، فريم ورک PRADO برای حل مشکل کدنويسی های تکراری و سطح پايين در توسعه برنامه های وب مبتنی بر PHP ، توسعه پيدا کرد. نام PRADO مخفف PHP Rapid application Development Object-oriented میباشد و وب سایت رسمی آن xisc است.
PRADO يک فريم ورک Component-base و Event-driven (رخدادگرا) برای برنامه نويسی وب با PHP 5 است. يک Component يک واحد نرم افزاری است که تمام مشخصات و رفتارهای مربوطه را در خود دارا بوده و با تغييرات جزئی میتوان آن را مورد استفاده مجدد قرار داد. PRADO قراردادی جهت نوشتن کامپوننتها وضع کرده است و کامپوننتهای پايه ای برای المنتهای وب پر استفاده نظير فيلد ورودی متن، Checkbox، ليست Drop-down و ... از قبل پياده سازی شده است. کامپوننتهای جديد را می توان با وراثت يا ترکيب کامپوننتهای موجود، توسعه داد. در PRADO برخلاف عادتهای برنامه نويسی گذشته بايد به صورت Event-driven کدينگ کنيد، بدين ترتيب که رفتارهای هر کامپوننت را به خودش واگذار میکنیم (یعنی هر کامپوننت Event های خود را هندل کند) که مسلما این رفتارها قابل بسط و تعمیم میباشند.
PRADO يک فريم ورک Component-base و Event-driven (رخدادگرا) برای برنامه نويسی وب با PHP 5 است. در PRADO برای دسترسی به ورودی کاربر در يک فيلد متنی از عبارت textbox->Text$ استفاده میکنيم که textbox$ به کامپوننتی ارجاع میکند که نمايانگر يک فيلد متنی است و Text يک مشخصه (Property) از کامپوننت است که مقدار ورودی کاربر را در خود نگه میدارد. برای پاسخ به فشردن دکمه Submit (که یک رخداد یا Event از طرف کاربر است) بايد يک تابع گرداننده رخداد (Event Handler) برای رخداد onClick کامپوننت دکمه نوشته شود. (دکمه Submit خود یک کامپوننت است) وقتی دکمه کلیک میشود، اين تابع گرداننده رخداد به طور اتوماتيک توسط فريم ورک فراخوانی میشود. بطور خلاصه، توسعه برنامه های وب با PRADO در اصل شامل نمونه گیری از انواع کامپوننتهای از قبل ساخته شده و مورد نياز برنامه، پيکربندی آنها با مقداردهی مشخصه های آنها و پاسخ دهی به رخدادهای مرتبط با آنها توسط توابع گرداننده وقفه و نهايتا ترکيب آنها برای انجام وظايف برنامه است.
نيازمندی ها و نصب
PRADO يک پروژه کد باز است که مجوز بهره برداری (Licence) از آن مطابق BSD است. اجرای PRADO مستلزم PHP 5 همراه با اکستنشن SimpleXML است و تحت سرويس دهنده های وب آپاچی و IIS تست شده و بخوبی کار میکند. خوشبختانه مستندسازی API آن بطور کامل انجام شده و مثالها و خودآموزهای خوبی برای آن نوشته شده است. در این سلسله مقالات، ابتدا به معرفی مفاهيم پايه PRADO میپردازم و يک مثال Form Validation را بطور مفصل توضيح میدهم تا بخوبی کاربرد آن را متوجه شوید. سپس نحوه نوشتن کامپوننتهای Reusable را با استفاده از روشهای Inheritance و Composition نشان میدهم. برای درک بهتر مطالب بعدی نگاهی اجمالی به مفاهيم OO بياندازيد. 
مفاهيم پايه
يک کامپوننت يک آبجکت است که خصيصه هايی برای آن تعريف میشود که به کمک آنها میتواند با ساير کامپوننتها ارتباط برقرار کند. خصایص کامپوننت ها در فايلهايی تعريف میشوند که اصطلاحا Component Specification File گفته میشود. اين خصيصه ها مانند Member Variableها یا Propertyهای یک آبجکت هستند که البته از طريق متدهای getter (برای خواندن مقدار آنها) و setter (برای ست کردن مقدر آنها) در دسترس هستند. برای مثال، خواندن مقدار خصيصه Text از کامپوننت TTesxtBox منجر به فراخوانی متد ()getText و نوشتن اين مقدار توسط متد ()setText صورت میپذيرد. Eventها خصيصه های ويژه ای هستند که نام متدها را بعنوان مقدار خود میپذيرند. الحاق (ست کردن) يک متد به يک Event باعث میشود در صورت بروز رخداد، اين متد فراخوانی شود. برای مثال رخداد OnClick کامپوننت TButton موقعی رخ میدهد که فريم ورک تشخيص دهد دکمه Submit متناظر کليک شده است (با بررسی داده های ورودی). حال متدی که به اين رخداد الحاق شده باشد، بصورت اتوماتيک توسط فريم ورک فراخوانی می شود تا اين رخداد را هندل کند. بدین ترتیب برنامه نويسی Event-driven اين امکان را به ما میدهد تا رفتارهای يک کامپوننت را براساس نيازهای جديد و پيش بينی نشده به راحتی تغيير دهيم. يک کامپوننت مشتق گرفته شده (فرزند) تمام خصايص کلاس والد خود را به ارث میبرد.
يک کنترل، کامپوننتی است که علاوه بر دارا بودن خصيصه های مرتبط، يک واسط کاربری يا UI هم دارد. کنترلهای ساده نظير کنترلهایی که المنتهای وب پر استفاده را نمايش میدهند، اغلب UI خود را در کد تعريف میکنند. UI کنترلها میتواند تنها از یک متن ثابت تشکيل شود يا از Templateها برای تعیین قالب UI خود استفاده کند.
يک Page (صفحه) کنترلی است که منطق Page Controller را اجرا میکند. PRADO الگوی طراحی Page Controller را به علاوه نمونه ضعیفی از Front Controller را که Application ناميده میشود، بکار میبرد. هر درخواست صفحه (Page Request) توسط Front Controller دريافت میشود که وظيفه آن ارسال اين Request يا درخواست به Page Controller مربوطه است. حال Page Controller داده های ورودی را از Request استخراج کرده و action خواسته شده را از مدل فراخوانی میکند و در نهايت View مناسب برای نمايش را تعيين می کند. (در مقالات بعدی راجع به MVC بیشتر صحبت میکنم)
يک ماجول (Module) کامپوننتی است که مجموعه Page هايی که برای يک هدف مشترک به کار گرفته میشوند را در یک گروه قرار می دهد. اين ماجول در واقع مخزن اصلی منطق و داده ميان صفحات موجود در یک گروه است.
کامپوننتها به يکديگر از طريق رابطه والد فرزندی مرتبط می شوند. هر کامپوننت حداکثر يک والد و يک ID دارد که به طور منحصر به فرد آن کامپوننت را در ميان کامپوننتهای هم نيای خود مشخص میکند. يک Page بالاترين کاپوننت است که هيچ والدی ندارد. از اين رو يک کامپوننت را می توان بصورت يک درخت قلمداد کرد که ريشه آن Page و مثلا سه گره درخت کامپوننتهای فرزند آن هستند. رابطه والد فرزندی بسيار اهميت دارد زیرا امکان آدرس دهی منحصر به فرد هر کامپوننتی را در درخت ميسر میسازد. برای مثال فرض کنيد کامپوننت HomePage والد کامپوننت Menu باشد که خود والد کامپوننت MenuItem است. بنابراين MenuItem را بصورت منحصر به فرد ميتوان به اين طريق آدرس دهی کرد: ابتدا HomePage بعد Menu و سپس MenuItem. در کد PHP اين رابطه را اينطور می نويسيم:
$homePage->Menu->MenuItem که homePage$ به کامپوننت HomePage اشاره میکند. با استفاده از توالی ID کامپوننتها می توان به Property های یک کامپوننت نیز دسترسی داشت. در مثال فوق، عبارت:
$homePage->Menu->MenuItem->Caption به خصيصه Caption کامپوننت MenuItem اشاره میکند.
مفهموم دیگر Postback است که دات نت کاران عزيز با آن کاملا آشنايی دارند يعنی فرم به همان صفحه ای که حاوی فرم است Submit میشود که برای اينکار ما در PHP يا مقدار خصيصه action فرم را "" قرار می دهيم (که شخصا توصیه نمی کنم) يا مقدار PHP_SELF را به جای آن قرار می دهيم و معمولا PHP کاران به جای اصطلاح Postback می گويند فرم Self Submit است يعنی روی خودش Submit ميشود. اگر ما یک صفحه را در پنجره مرورگر مشاهده کنیم، Postback مانند یک User actionای است که منجر به پاسخ از طرف صفحه میشود. در واقع فرآیند فعل و انفعالات کاربر با Web Application را می توان ترتیبی از Postbackها همراه با انتقال پیمایش به صفحه دیگر دانست. هر Postback منجر به برخی بروزرسانی ها در وضعیت صفحه می شود.
Viewstate وضعیت صفحه را در طی ترتیبی از Postbackها نگه میدارد.
برای مثال فرض کنيد کاربر بخواهد اطلاعات حساب کاربری خود را از طریق صفحه Profile بروز کند. کاربر باید مواظب باشد هر دفعه که یک قلم داده را بروز کرد، تغییرات را ذخیره کند. از آنجا که پروتکل HTTP، بی وضعيت (Stateless) است، داده هايی که قبلا کاربر وارد کرده به شرط اينکه سمت سرويس دهنده داده ها را در بانک يا فايلی ذخيره نکنيم، از بين خواهد رفت. Viewstate مکانيزمی است که امکان ذخيره داده ها در طی چندين Postback متوالی به يک صفحه را فراهم می کند. مفهوم Viewstate با Session تفاوت می کند زيرا داده های Session ميان درخواستهايی به چندين صفحه متفاوت ثابت هستند حال آنکه داده های Viewsate تنها به يک صفحه متعلق هستند.
در مطلب بعدی يک مثال Form Validation با PRADO می نويسيم.
بنده را از نظرات سازنده خود مطلع کنيد. 
|