PDA

نسخه کامل مشاهده نسخه کامل : Ruby on Railsپدیده ای در توسعه نرم افزارهای تحت Web



ab.mahmoodi
03-07-2008, 08:43
Ruby on Railsپدیده ای در توسعه نرم افزارهای تحت Web


Ruby on Rails یک محیط کاری (Framework) است که طراحی، توسعه و نگهداری نرم افزارهای تحت web را آسان کرده است. Rails در طول چندین ماه از یک ابزار ناشناحته تبدیل به یک ابزار شناخته شده جهانی شد. این ابزار (Framework) جایزه های مختلفی را برنده شده و مهمتر اینکه به عنوان یکی از ابزارهای طراحی و توسعه Web 2.0 انتخاب شده است به طوریکه شرکتهای چند ملیتی مختلفی، از Rails برای تولید نرم افزارهای تحت Web استفاده میکنند.

چرا؟ به نظر میرسد علتهای مختلفی وجود دارد.
اول اینکه به نظر میرسید تعداد زیادی از توسعه دهنده ها وجود داشته باشند که از ابزارهای موجود برای توسعه نرم افزارهای تحت Web نا امیدند. و به نظر نمیرسید که اهمیت داشته باشد که آنها از Java، PHP و یا .NET استفاده میکنند. و ناگهان Rails متولد شده و کارها بسیار آسان شد.
ما در مورد توسعه دهندگان واقعی صحبت میکنیم که نویسندگان Web Site های بزرگ هستند. بنابراین این توسعه دهندگان شروع به توسعه نرم افزارهای خود با Rails کرده و فهمیدند که آن فقط یک ابزار برای توسعه نرم افزارهای Web نیست. برای مثال تمام نرم افزارهای توسعه داده شده با Rails با استفاده از معماری MVC(Model - View - Controller) پیاده سازی میشود. توسعه گرهای Java مثل Tapestry و Struts از سیستم MVC استفاده میکند اما در Rails بسیار فراتر است:
هنگامیکه شما نرم افزاری را در Rails توسعه میدهید برای هر بخش از کد محلی وجود دارد و همه بخشهای نرم افزار با یک روش استاندارد در رابطه هستند.
برنامه نویسان حرفه ای تست های نرم افزار خود را مینویسند اما در Rails نرم افزارها از واحدهای تست به صورت داخلی پشتیبانی میکنند. همانطور که شما نرم افزار را توسعه میدهید، Rails به صورت خودکار واحدهای تست را برای بخشهای توسعه داده شده ایجاد میکند. محیط کار، عملیات تست را آسان میکنند. نرم افزارهای Rails در محیط Ruby که یک محیط پیشرفته است با زبان Object Oriented نوشته میشود. Ruby مختصر و کوتاه و بدون پیچیدگی میباشد. شما میتوانید عقاید خود را به صورت طبیعی و روشن در کدهای Ruby بیان نمایید. و این باعث میشود برنامه هایی تولید شوند که نوشتن آنها آسان بوده و همینطور خواندن آن نیز ماه ها بعد آسان میباشد.
Rails به صورت محدود Ruby را به کار گرفته و به روشهای جدیدی آنرا گسترش می دهد به طوریکه کار را برای برنامه نویس آسان میکند. این باعث میشود برنامه ما کوتا هتر و خوانا تر شود. آن همچنین ما را قادر می سازد که کارهایی مثل ایجاد فایلهای تنظیم (Configuration files) را به صورت کد نویسی در داخل برنامه انجام دهیم. که البته این کارها به صورت طبیعی در خارج از برنامه انجام میگردد. و این باعث میشود دیدن رخدادها بسیار آسان گردد. کدی که در پایین آمده است یک Model Class را نشان میدهد:


class Project < ActiveRecord::Base
belongs_to: portfolio
has_one: project_manager
has_many: milestones
has_many: deliverables, :through => :milestones
validates_presence_of :name, :description
validates_acceptance_of :non_disclosure_agreement
validates_uniqueness_of :short_name
end
Rails بر اساس دو عقیده کلیدی پیاده سازی شده است DRY و قراردادها در مقابل تنظیمات. DRY (Don't Repeat Yourself) یعنی اینکه هر بخش از دانش در یک سیستم باید فقط در یک مکان قرار داده شود. Rails از قدرت Ruby برای قرارگیری در این موقعیت استفاده میکند. شما میگویید که چه چیزی برای گفتن در یک مکان نیاز خواهید داشت - یک مکان اغلب به وسیله قراردادهای MVC پیشنهاد میشود - و سپس در آنجا قرار میگیرید. برای برنامه نویسانی که از محیطهای دیگر برای توسعه نرم افزارهای Web استفاده میکنند، به طوریکه تغییر کوچکی در DB باعث میشود تقریبا نیمی از کدهای نوشته شده دچار تغییرات شوند، این امکانات در Rails همه چیز را آشکار میکند.
قراردادها به جای تنظیمات یعنی اینکه شما میتوانید با کمترین حجم کدنویسی یک نرم افزار را با Rails توسعه دهید برخلاف توسعه گر Java به وسیله فایلهای تنظیم XML. اگر شما نیاز داشته باشید، باطل کردن (override) قراردادها توسط Rails نیز آسان شده است.
کسانیکه با Rails شروع به کار میکند متوجه چیز دیگری نیز میشوند و آن اینکه Rails یک فن آوری کاملا جدید بوده و بنابراین امکانات جدید توسعه نرم افزارهای تحت Web در آن دیده شده است. همچنین Rails امکان استفاده از فن آوری AJAX و RESTful را به صورت داخلی فراهم میکند. قرار دادن نسخه نهایی روی هاست در اینترنت نیز کار ساده ای بوده و با استفاده از دستوراتی این کار امکان پذیر میباشد.





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


معماری نرم افزارهای Rails


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



Models، View و Controllers
در سال 1979 Trygve Reenskaug با ساختار جدیدی در توسعه نرم افزارهای کاربردی ظهور کرد. در طرح او برنامه های کاربردی به سه قسمت شکسته میشدند: Models، Views و Controllers.
Model مسول نگهداری حالت(State) نرم افزار است. گاهی اوقات این حالت بسیار زودگذر بوده و به مقداری ارتباط بین کاربر و برنامه ختم میشود. گاهی اوقات این حالت پایدار بوده و خارج از برنامه نگهداری میشود، اغلب در یک پایگاه داده.
یک Model فراتر از داده هاست به طوریکه تمام قوانین تجاری کد نویسی را به آن داده ها اعمال میکند، برای مثال اگر تخفیف کمتر از 20$ نباید به سفارشات اعمال شود، Model آنرا به عنوان یک شرط اعمال میکند. بنابراین با پیاده سازی قوانین تجاری در Model ما مطمئن میشویم که هیچ چیز دیگری نمیتواند نرم افزار ما را دچار خرابی در داده ها کند. در اینجا Model هم بعنوان نگهبان و هم به عنوان منبع ذخیره عمل میکند.


View مسولیت ایجا رابط کاربر (User Interface) را براساس داده های موجود در Model دارد. برای مثال یک فروشگاه اینترنتی را در نظر بگیرید که شامل لیستی از محصولات برای نمایش در صفحه میباشد، این لیست از طریق model قابل دسترس خواهد بود اما این view است که آن لیست را از model تحویل گرفته و با شکل و قالبی خاص برای کاربر به نمایش در می آورد. اگر چه ممکن است View داده های ورودی را برای کاربر با روشهای گوناگون به نمایش بگذارد اما View هرگز خودش به اداره داده های ورودی نمی پردازد. زمانیکه داده ها به نمایش در می آیند کار View انجام شده است، اگر چه امکان دارد View های دیگری برای اهداف دیگر به همان Model دسترسی داشته باشند.



file:///F:/DOCUME%7E1/Internet/LOCALS%7E1/Temp/msohtmlclip1/01/clip_image002.gif




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


Controller برای هماهنگی برنامه مورد استفاده قرار میگیرد. Controller ها رویدادها را از دنیای خارج (مثل ورورد داده ها توسط user) دریافت نموده، با Model ارتباط برقرار کرده و View مورد نظر را برای کاربر به نمایش در می آورد.
معماری MVC به عنوان یک انتخاب زیرکانه در نرم افزارهای GUI مورد استفاده قرار میگیرد و باعث میشود توسعه، پیاده سازی و نگهداری نرم افزار بسیار ساده تر گردد. هر نوع فکر و عقیده و یا عملیات فقط در یک محل شناخته شده اظهار میگردد. (به عبارت دیگر هر بخش از نرم افزار - در نرم افزارهایی که براساس اصول درست مهندسی نرم افزار طراحی شده اند - در جایگاه مخصوص به خودش بایستی قرار گیرد). استفاده از MVC شبیه به ساختن یک آسمانخراش به وسیله تیرهای آهنین میباشد.


در دنیای نرم افزار معمولا همیشه به آینده نگاه میشود و از گذشته خبری نیست. توسعه دهندگان نرم افزارهای تحت Web معمولا بخش های رابط کاربر، دسترسی به پایگاه داده، منطق تجاری (Business Logic) و اداره کردن رویدادها را در هم آمیخته و باعث به وجود آمدن خیل عظیمی از کدها در یک محل شده که مدیریت آنها بسیار مشکل است در حالیکه معماری MVC از سالها پیش در Webobjects، Java Server Faces و Struts مورد استفاده قرار می گرفته است.

file:///F:/DOCUME%7E1/Internet/LOCALS%7E1/Temp/msohtmlclip1/01/clip_image004.gif

شکل -2


Rails نیز یک محیط براساس معماری MVC میباشد. Rails ساختاری را برای برنامه شما ایجاد کرده و باعث میشود شما بخشهای Model، View و Controller را به صورت جداگانه توسعه دهید و رابطه آنها را طوری ایجاد میکند که نرم افزار شما قابل اجرا باشد. یکی از امکانات جالب Rails این است با استفاده از پیش فرضهای هوشمند ارتباط فوق را بدون نیاز به هیچگونه تنظیماتی ایجاد میکند. در یک برنامه کاربردی Rails، درخواستهای ورودی اول به یک مسیریاب (Router) ارسال میشود، که خارج از نرم افزار انجام وظیفه میکند، این درخواست ارسال شده چگونه تجزیه و تحلیل میشود. سرانجام این مرحله متد ویژه ای (که در rails به آن action میگویند) را تعریف میکند که این متد در جایی به نام controller قرار دارد. که ممکن است با model ارتباط برقرار کرده و یا اینکه action های دیگر را درخواست نماید. سرانجام action اطلاعات را برای view آماده نموده که نمایی برای کاربر به نمایش در می آورد.
در شکل 2 نشان میدهد که Rails چگونه یک درخواست ورودی را مدیریت میکند، در این مثال نرم افزار یک محصول را نمایش داده و کاربر روی دکمه "اضافه به سبد خرید" کلیک میکند، این دکمه با [ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ] ([ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ]) ارتباط دارد به طوریکه "add_to_cart" یک action بوده و 123یک شناسه معتبر برای محصول مورد نظر به شمار میرود. بخش مسیریابی (Routing) درخواست ورودی را دریافت نموده و فورا آنرا تحلیل میکند در این مثال اولین بخش مسیر وارد شده (store) به عنوان controller و دومین بخش آن (add_to_cart) به عنوان نام یک action شناخته میشود وبخش آخر آن (123) به عنوان شناسه محصول شناسایی میگردد.
متد add_to_cart درخواست کاربر را مدیریت میکند. در این مثال آن سبد خرید مشتری را پیدا کرده و از model اطلاعات مربوط به کالای 123 درخواست میکند سپس از سبد خرید میخواهد که این کالا را به لیست خود اضافه کند.
حالا که سبد خرید شامل محصول جدید میشود، میتوان آنرا برای مشتری نمایش داد. Controller به مرتب کردن چیزها می پردازد و view به cart object دسترسی پیدا کرده و کد مربوطه را درخواست میکند.



رکورد فعال (Active Record): پشتیبانی از Model
به طور کلی ما می خواهیم نرم افزاری که توسعه می دهیم داده ها را در یک پایگاه داده رابطه ای ذخیره و نگهداری کند. سیستمهای ورود سفارشات، اطلاعات مربوط به سفارشات، کالاها و اطلاعات مشتری ها را در جداول موجود در پایگاه داده ذخیره میکند. حتی نرم افزارهایی که با متن های غیر ساخت یافته (مثل وبلاگها و سایتهای خبری) سروکار دارند اینگونه اطلاعات را در پایگاه داده ذخیره می کنند. اگر چه این موضوع از لحاظ ظاهری خوب است اما ترکیب یک پایگاه داده رابطه ای با برنامه نویسی شی گرا (Object Oriented) کار مشکلی است.



برنامه نویسی متمرکز شده روی پایگاه داده
گروهی از برنامه نویسان از زبانهایی مثل C و Delphi استفاده میکنند در این زبانها برای دسترسی به پایگاه داده از دستورات SQL در درون کد برنامه (Embedded) استفاده کرده و یا توسط پیش پردازنده (Preprocessor) دستورات به شکل فراخوانی های سطح پایین تبدیل کرده که در برنامه قابل استفاده میباشد، برای مثال در اینجا کدی وجود دارد که ترکیب برنامه نویسی عادی را با برنامه نویسی پایگاه داده نشان میدهد:



EXEC SQL BEGIN DECLARE SECTION;

int id;

float amount;

EXEC SQL END DECLARE SECTION;


EXEC SQL DECLARE c1 AS CURSOR FOR select id, amount from orders;


while (1) {

float tax;

EXEC SQL WHENEVER NOT FOUND DO break;

EXEC SQL FETCH c1 INTO :id, :amount;

tax = calc_sales_tax(amount)

EXEC SQL UPDATE orders set tax = :tax where id = :id;

}

EXEC SQL CLOSE c1;
EXEC SQL COMMIT WORK;

این سبک از برنامه نویسی در زبانهایی مثل Perl و PHP عادی است و همچنین در Ruby هم وجود دارد. برای مثال ما میتوانیم از کتابخانه DBI متعلق به ruby برای تولید کدهای اینچنینی استفاده نماییم:




def update_sales_tax

update = @db.prepare("update orders set tax=? where id=?" )

@db.select_all("select id, amount from orders" ) do |id, amount|

tax = calc_sales_tax(amount)

update.execute(tax, id)

end
end


این روش، یک روش مشخص بوده و حقیقتا به طور گسترده استفاده میگردد و به نظر میرسد برای نرم افزارهای کوچک روش خوبی است اما مشکی که وجود دارد این است که درهم آمیختن کدهای تجاری و پایگاه داده ها باعث میشود که توسعه و نگهداری نرم افزار را در آینده بسیار مشکل شود.
فرض کنید بعد از مدتها شما مجبور میشوید یک ستون به یکی از جداول پایگاه داده خود اضافه کنید. چه اتفاقی می افتد؟ باعث میشود شما مجبور شوید کل کدهای نرم افزار خود را جستجو کرده و شروع به اصلاحاتی کنید و اگر خوش شانس با مشکلات دیگر روبرو نمیشوید.
در برنامه نویسی حرفه ای این گونه مشکلات با استفاده از Encapsulation تا حدود زیادی حل میشود. ما هر بخش از کد حود را در یک Class قرار داده و در موقع لارم به Class مورد نظر مراجعه کرده و تغییرات لازم را به وجود می آوریم.
با گسترش دادن این موضوع به برنامه نویسی پایگاه داده باعث میشود به این نتیجه برسیم که کدهای دسترسی به پایگاه داده ها را در یک Class قرار داده و از متدهای آن برای اهداف مورد نظر استفاده نماییم. خوب در این حالت ما به طور مستقیم با پایگاه داده رابطه نداشته و در مواقع لارم تغییرات را در Class مربوطه ایجاد میکنیم. البته این روش در پیاده سازی بسیار مشکل تر از تئوری آن است. در عمل هر کدام از کلاسها یا اشیا باید یک یا چند جدول پایگاه داده ها آدرس دهی شده و با آنها ارتباط مستقیمی برقرار نماید که کار بسیار پیچیده ای خواهد بود. در Rails این کار توسط ORM انجام میگردد.



Object Relational Mapping
کتابخانه ORM جداول پایگاه داده را با کلاسها مرتبط میکند. اگر پایگاه داده ای جدولی با نام orders داشته باشد متقابلا برنامه ما کلاسی با نام Order خواهد داشت. رکوردهای موجود در این جدول با اشیا (object) ی آن کلاس در رابطه هستند. یک سفارش (order) به خصوص به عنوان شیئی از کلاس Order نمایش داده میشود. درون آن object صفات (Attribute) برای نوشتن اطلاعات مربوط به هر ستون (Column) مورد استفاده قرار میگیرد. شی Order ما متدهایی دارد که برای نوشتن و خواندن مقادیر مورد استفاده قرار میگیرد.
در مجموع کلاسهای Rails جداول پایگاه داده را در خود بسته بندی کرده و مجموعه ای از متدها در سطح کلاس را به وجود آورده که با استفاده از آنها عملیات مربوط به جداول پایگاه داده قابل انجام است. برای مثال اگر بخواهیم سفارش (order) به خصوصی با یک شناسه (ID) ویژه پیدا کنیم با استفاده از متدی که آن سفارش را برمیگرداند پیاده سازی میشود:
order = Order.find(1) puts
puts "Order #{order.customer_id}, amount=#{order.amount}"



گاهی اوقات این متدها مجموعه ای از اشیا را برمیگرداند:
Order.find(:all, :conditions => "name='dave'" ).each do |order|
puts order.amount
end


در نهایت اشیا متناظر با رکورهای جدول متدهایی دارند که روی آن رکورد عملیات انجام میدهند. شاید پر استفاده ترین آنها متد Save باشد متدی که رکورد را در پایگاه داده ذخیره میکند:
Order.find(:all, :conditions => "name='dave'" ).each do |order|
order.discount = 0.5
order.save
end


بنابراین لایه ORM جداول را به کلاسها، رکوردها را به اشیا و ستونها (Fields) را به صفات (Attribute) آن object مربوط میکند. متدهای کلاس برای انجام عملیات روی جداول و متدهای دیگر برای انجام عملیات روی رکوردها استفاده میگردد.

ادامه دارد...
منبع:

Agile Web Development with Rails (Second Edition)



By: Dave Thomas, David Heinemeier Hansson


ترجمه و تحقیق :
ابوالفضل محمودی
msd.soft@gmail.com


برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید

Mohammad
10-07-2008, 14:52
ممنونم آقای محمودی...
این کار جای تقدیر داره.امیدوارم همواره موفق باشید.