مبحث AOP (قسمت اول)
با سلام
در این پست می خواهم به مبحث AOP بپردازم . این مبحث رو می خواهم از پایه شروع کنم و تا مرحله پیاده سازی اون در دات نت پیش برم . ابتدا من یک مقاله از (ماهنامه شبکه ) که در مورد همین موضوع است رو می زارم ،البته با یکسری تغییرات :
Aspect-Oriented
Programming نیز، که در واقع در
ادامه مدل OOP عرضه شد، یک الگو برنامهنویسی است که در ادامه
به معرفی آن میپردازیم. AOP؛ تولد یک مفهوم · برنامهنویس باید از
وجود چنین کلاسهایی که برای هماهنگ کردن این Cross-cutting Concernها ساخته شده است، خبر داشته باشد. ·
باید
Specification دقیق آن کلاس را بداند
تا بتواند از آن استفاده کند. ·
باید بداند دستور مربوط به فراخوانی روشهای آن کلاس را کجای کد
اصلی قرار دهد. Quantification یا تعیین عناصر: Obliviousness یا فراموشکاری: تعریف Filman-Friedman AOP در عمل برای پاسخ دادن به این
پرسش، ابتدا باید ببینید AOP
چگونه اجرا میشود. برای نوشتن یک پروژه به صورت AOPشما ابتدا هر دو بخش کد
خود را (اعم از روند کاری اصلی برنامه و کدهای مربوط به Aspectها) به صورت جداگانه در
یک زبان شیءگرا مینویسید و سپس موجودی به نام Aspect Weaver آن
دو بخش را با یکدیگر ترکیب کرده و کد نهایی را میسازد. جداسازی کد اصلی و کد Concernها (کد اصلی نیازی به
اطلاع از بخش Concernها ندارد) به افزایش قابلیت استفاده دوباره (Reusability) و
قابلیت نگهداری (Maintainability) پروژه کمک شایانی میکند. شکل 1 نحوه کار Weaverها را نشان میدهد. دو
نمونه بارز از ابزارهایی که میتوان با استفاده از آنها برنامههای Aspect-Oriented نوشت AspectJ و AspectWerkz هستند. AspectJ یک
Extension است که برای زبان جاوا
در زیراکس پارک و توسط گروه بهوجود آورنده AOP نوشته شدهاست. این Extension به دو صورت تنها و
تعبیه شده در Eclipse IDE عرضه میشود. AspectJ پتانسیل پشتیبانی از
مدلRT Weaver را نیزدارد، اما برای بهره بردن از تواناییهای آن باید از آن بهصورت
یک Compile-time Weaver استفاده کرد (هماکنون به صورت Compile-time و loadtime عرضه میشود. Aspect Weaver ! در حقیقت Aspect Weaver کد
اصلی و کد Aspectها را بهعنوان ورودی میگیرد و محصول نهایی را
تولید میکند. توجه به این موضوع ضروری است که نگاه کلی به Weaverها مانند یک کامپایلر
نیست، زیرا قرار نیست که تمام کارهای پیچیدهای را که یک کامپایلر انجام میدهد. Weaver نیز در مورد ترکیب دو
بخش کد انجام دهد. در حقیقت، همانطور که خود کیزالس هم اشاره می کند، وظیفه Weaverها فقط Integration ) مجتمعسازی
) است. تکنیکهای اولیه
Weaving به دو دسته عمده تقسیم
میشوند: Compile Time CT))
Run-Time RT Weaver)). همانطور که از نامشان
پیدا است، تمام کارهای مربوط به ترکیب کد را در زمان کامپایل انجام میدهند و در
حقیقت کد نهایی که اجرا میشود، محصول کامل است. در مقابل RTها اینکار را در زمان
اجرا انجام میدهند و ایجاد ارتباط را تا آن وقت به تأخیر میاندازند. Weaverهای CT با توجه به این که تمام
فرآیند ایجاد ارتباط را در ابتدای کار و هنگام کامپایل انجام میدهند بسیار سریعتر
از RTها عمل میکنند، اما در مقابل RTها هم این مزیت را
دارند که در صورت تغییر کد
Aspectها نیازی به انجام
دوباره عملیات Weaving نیست و برخلاف CTها در Run-Time Weaver تغییرات
در کد بدون نیاز به هیچ کاری سریع منعکس میشوند. همانطور که در بالا ذکر
کردیم، تکنیکهای
Weaving دیگری نیز وجود دارند
که در واقع فضای بین
Compile-time و Run-time قرار میگیرند. این دو
تکنیک Weaving را
(post-compile time (binary و Load-time مینامند. Binary Weaving در
حقیقت عملیات Weaving را روی byte code انجام میدهد (پس از
کامپایل). Load time Weaving نیز یک نوع binary Weaving است.
با این تفاوت که عملیات
Weaving را تا زمانی که یک کلاس
به Class loader معرفی نشده است، به تأخیر میاندازد. (این
توانایی میتواند برخی از نقصهای مدل Compile-time را برطرف کند، زیرا شما
میتوانید بدون کامپایل کردن دوباره کد اصلی خود (Aspect ،(Business Logicهایی
به برنامه اضافه کرده و سپس آنها را به پروژه اصلی لینک دهید). در حقیقت، در
این مدل تا جایی که ممکن است عملیات
Weaving به تأخیر میافتد و تا
مرحله Load شدن کلاسهای موردنیاز هیچ ترکیبی انجام نمیشود. AspectJ محیطی ساده و بسیار کارا دارد و هماکنون محبوبترین
ابزار برنامهنویسی
Aspect-Oriented است. نسخههای جدیدتر AspectJ بهطور کامل با محیط
توسعه Eclipse هماهنگی دارند و میتوان از تمام امکانات Eclipse در مورد Aspectها نیز سود برد. توجه به این نکته ضروری
است که AspectJ تغییراتی در Syntax زبان به وجود میآورد
که این موضوع میتواند باعث بروز مشکلاتی شود )Eclipse با توجه به اضافه کردن Keywordهای مربوط به برنامهنویسی AOP این مشکل را ندارد(. این مشکلات باعث شدند
تا ابزارهای دیگری به وجود آیند که به این تغییرات گرامری در زبان برنامهنویسی
نیازی نداشته باشند. یک نمونه مشهور از این زبانها AspectWerkz است. AspectWerkz در حال حاضر از هر سه
مدل Compile-time ،Load-time و Run
time استفاده میکند. خصوصیت
بارز AspectWerkz این است که Syntax زبان را تغییر نمیدهد
و در حقیقت تغییرات را با استفاده از
Annotation انجام میدهد که به یک
ساختار زبانی جدید نیازی ندارد. در حال حاضر، دو پروژه AspectJ و AspectWerkz با یکدیگر ترکیب شدهاند
تا بتوانیم از قابلیتهای هر دو به صورت همزمان استفاده کنیم.
شاید قبلاً نام AOP سرنام (Aspect Oriented
Programming) را شنیده باشید. بسیاری
از ما اولین بار که این نام را شنیدیم با تصور این که AOP نیز یکی از آن الگوهایی
است که هر چند سال یکبار برای جایگزینی برنامهنویسی شیءگرا مطرح میشوند، بیتفاوت
آن را کنار گذاشتیم. اما داستان AOP، طولانیتر از این حرفها است. زمان آن رسیده که کمی خاک شیوه
برنامهنویسی خود را بگیرید. مکاشفات جذابی وجود دارد... .
بسیاری از افراد معتقدند، علوم کامپیوتر آن
قدرها هم که بهنظر می آید، سریع پیشرفت نمیکند. آنها معتقدند، در بسیاری از شاخهها
کار تقریباً تمام شدهاست و کارهای جدید فقط در حد پیشرفتهای جزئی انجام میگیرد.
در حقیقت، بعضی از موضوعهای مطرح شده توسط این گروه بدبین، تا حدودی به واقعیت
نزدیک است. بسیاری از پایههای علوم کامپیوتر شکل گرفته است و به نظر میآید
تغییر آنها، دستکم به این زودیها امکانپذیر نیست. در بعضی از شاخهها یک
فناوری آنچنان جای پایش را محکم کردهاست که حتی تصور وجود روشی دیگر کمی سخت
به نظر میرسد.
اما کامپیوتریها مردم جالبی هستند. شاید آنها
خیلی پرکار نباشند، اما همیشه ایدههای جدید و خلاقانه راهی برای نفوذ به درون
دنیایشان پیدا میکنند. شاید در بسیاری از زمینهها، کار شما به مطالعه کارهای
کلاسیک انجام شده محدود شود، اما همیشه جادههای جدیدی وجود دارد.
گریگور کیزالس (Gregor Kiczales)،
بیشتر وقت خود را در آزمایشگاه پارک
(PARC) که مبدأ شروع بسیاری از
خلاقیتهای بزرگ حوزه علوم کامپیوتر بوده، گذرانده است. محیط صنعتی - آکادمیک
آزمایشگاه علاوه بر دلمشغولیهای آکادمیک، کیزالس را به مسائل و مشکلات حوزه
نرمافزار در دنیای واقعی آشنا ساخته است. در حقیقت، یکی از همین مشکلات (Cross-cutting Concern) بود که منجر به ارائه مدل AOP توسط این پروفسور
دانشگاه UBC و همکارانش در زیراکس پارک شد. مدلی که به
تحرکات زیادی در حوزه نرمافزار منجر شد تا جایی که Daniel Sabbah ،
معاون بخش استراتژیهای نرمافزاری شرکت IBM درباره آن میگوید: «زمان توسعه نرمافزارها به وسیله مفهوم Aspect-Oriented فرا رسیدهاست. صنعت نرمافزار به آن نیاز دارد
و IBM در
حال حاضر از آن استفاده میکند.
اولین ارائه رسمی از این موضوع به سال 1997 برمیگردد.
البته، اطلاعات تاریخی درباره AOP
بسیار اندک است و ما از روند کار چیز زیادی نمیدانیم.
کیزالس خود در پاسخ به پرسش نگارنده پیرامون تاریخچه و روند شکلگیری AOP میگوید: «متأسفانه هیچ
تاریخ مدونی برای AOP
وجود ندارد.» در این مقاله سعی کردهایم معرفی
مناسبی از این الگو جدید برنامهنویسی ارائه دهیم.
چرا از الگو استفاده میکنیم؟
توماس کوهن، الگو را اینگونه تعریف میکند: «الگو
در نتیجه فعالیتهای اجتماعی ظاهر میشود که در آن مردم ایدههایشان را توسعه میدهند
و قواعد و مثالهایی میسازند که این ایدهها را بیان کند.1» این شاید یکی از
رسمیترین تعریفهایی باشد که در سراسر عمرتان برای الگو میشنوید. اما این جمله
زیبا برای یک برنامهنویس چه معنایی دارد؟
کامپیوترهای اولیه توسط کدهای باینری برنامهریزی
میشدند و برنامهنویس، با ارسال دنبالهای از صفر و یک ها به پردازنده مرکزی بهطور
مستقیم برای آن کامپیوتر برنامهنویسی میکرد. با گذشت زمان، زبانهایی با سطوح
بالاتر عرضه شدند. اسمبلی، C و جاوا نمونهای از زبانهای نسلهای مختلف
هستند. با معرفی هر نسل، نحوه نوشتن برنامه و نگرش به مفاهیم نیز در آن تغییر مییافت.
ارائه شیوههای جدید تولید نرمافزار به امید ایجاد راههای بهتر برای طراحی و
پیادهسازی یک برنامه، هنوز نیز ادامه دارد. روش پایهای برنامهنویسی را که در
بالا بیان شد، الگو برنامهنویسی مینامند. در حقیقت، الگوها چهارچوب کلی
معماری یک برنامه و نحوه ارتباط اجزای آن با یکدیگر را مشخص میکنند. با ذکر
مثالهایی از الگوهای مختلف، مفهوم را روشنتر میکنیم.
شاید برنامهنویسی رویهای (Procedural Programming) اولین الگو مطرحشده برای زبانهای برنامهنویسی است. در این الگو،
اعمال، مرحله به مرحله توسط فراخوانی رویههایی که برای انجام کارهای مختلف
نوشته میشوند، انجام میگیرند. این مدل با مشخص کردن ترتیبی برای فراخوانی رویهها
یکییکی آنها را اجرا میکند و با اتمام کار هر کدام رویه بعدی اجرا میشود. در
حقیقت، برنامهنویسی رویهای، ادامه ایده کلیتری بهنام برنامهنویسی امری (Imperative Programming) است. بهطور ساده استراتژی این مدل برنامهنویسی به این صورت است
که تعدادی دستور وجود دارند که باید توسط کامپیوتر اجرا شوند. زبانهای امری
دقیقاً مانند اسمشان عمل میکنند: اول این کار را انجام بده، بعد آن را و... .
برنامهنویسی شیءگرا نیز در بیشتر مواقع مثالی
از مدل امری است، زیرا در آنجا نیز روش کار برنامه عموماً به صورت اجرای سلسلهای
از دستورها است. اگرچه معمولاً برنامهنویسی شیءگرا به صورت یک مدل جداگانه مورد
بررسی قرار میگیرد. در مقابل مدل برنامهنویسی امری، مدل اعلانی (Declarative) قرار
دارد. در این مدل تمرکز روی ماهیت چیزها است نه نحوه کارکرد آنها. در مدل
اعلانی آنچه اهمیت دارد، توصیف این است که یک جزء برنامه چگونه است، نه اینکه
چگونه ساخته میشود. اگر برنامه خود را به دو قسمت منطق و کنترل تقسیم کنید، در
مدل اعلانی شما منطق برنامه خود را در اختیار میگیرید و نگران آنچه در بخش کنترل
اتفاق میافتد، نیستید. مثال بارز اینگونه زبانها، HTML است. با توجه به نزدیک
بودن ساختار مدل اعلانی به ساختار ریاضیات، اثبات درستی یک برنامه در این مدل
راحتتر انجام میگیرد. به همین دلیل، مدل اعلانی در نوشتن برنامههایی که باید
درستی آنها به صورت یک حکم ریاضی ثابت شود، کاربرد فراوانی دارد. عموماً زبانهای
مدل امری در محیطهای کاری از محبوبیت بیشتری برخوردارند، اما نمیتوان از تأثیر
مدل اعلانی در ساخت برنامههای علمی (به خصوص ریاضی) به سادگی گذشت. این معرفی
بسیار کوتاه از الگوها فقط برای این بود که بدانیم آنها واقعاً یکی نیستند! هر
الگو، یک سبک برنامهنویسی و از آن مهمتر یک سبک نگرش را به دنبال دارد که میتواند
تعاریف و اصول یک برنامهنویس را دگرگون سازد. الگوها قطعاً به وجود نیامدهاند
که معجزه کنند، بلکه قرار است کار را برای برنامهنویسان راحتتر سازند.
وقتی OOP جوابگو نیست...
سناریوی زیر را در نظر بگیرید: فرض کنید شما
مسئول طراحی وبسایت برای یک شرکت فروش آنلاین لباس شدهاید. این سایت، مانند
بیشتر سایتهای دنیا دو بخش دارد: بخش نخست برای مشتریان که میتوانند در آن
اجناس را مشاهده کنند و آنها را بخرند. بخش دوم نیز برای انجام کارهای اداری
خود شرکت است که فقط کارمندان خاصی به آن دسترسی دارند. بهعنوان مثال، اضافه
کردن اقلامی به فروشگاه آنلاین یا بررسی کردن حساب بعضی از مشتریها. شما و گروه
برنامهنویسی با تلاشی قابل ستایش سایتی بسیار جامع و زیبا طراحی میکنید و آن
را به شرکت ارائه میدهید. اما روزی که برای دریافت حقالزحمه خود میروید،
متوجه میشوید که همه از دست شما عصبانی هستند. کارمندان نمیتوانند البسه جدید
را وارد فهرست فروشگاه کنند، کاربران سایت در حال افزایش اعتبار حساب کاربری خود
به صورت دستی هستند! ایمیل کاربران با فرمت اشتباه ذخیره شده است، پیگیری فروش
روزهای قبل در مواردی دچار مشکل میشود و... . مشکل چیست؟
با افزایش پیچیدگی در یک برنامه نحوه کنترل شما
روی روند رشد آن نیز دشوارتر میشود. با این که ممکن است در بسیاری از قسمتهای
برنامه کارهایی شبیه به هم انجام دهید، اما جا انداختن یکی از این کارها در هر
یک از قسمتها میتواند کارایی کل برنامه شما را زیر سؤال ببرد. به مثال امنیت
سایت فروش لباس باز میگردیم. شما متوجه میشوید با توجه به پیچیده شدن معماری
سایت، بسیاری از کارهای ضروری را از قلم انداختهاید. در بسیاری از جاها فراموش
شده که قبل از فراخوانی روشهای امن
(Secure) هویت کاربر مشخص شود تا
فرد غیرمسئول نتواند به اطلاعات محرمانه دسترسی داشته باشد. در بسیاری از قسمتها
ورودیهای اشتباهی که کاربران به صورت دستی به سیستم میدهند، تأیید اعتبار (Validate) نمیشوند و این باعث
بروز سردرگمی در سیستم میشود. در ضمن در بعضی از روشها با توجه به زیاد بودن
کارهای حاشیهای (مانند ثبت کردن عملیات یک سیستم (Logging)،
تراکنشهای پایگاهداده و مدیریت خطاها فراخوانی روشهای بعضی کارها از قلم
افتادهاست. در نتیجه سایت کاملاً کارایی خود را از دست داده و عملاً به یک
سیستم خراب تبدیل شدهاست. از تمام این موارد بدتر اینکه مشکلات شما به اینجا
ختم نمیشود. وقتی درصدد اصلاح کدها بربیایید، میبینید اینکار خیلی دشوارتر از
آن است که تصور میکردید، زیرا کد هر قسمت آمیختهای از روند کاری اصلی برنامه (Business Logic) و
کارهای حاشیهای مانند بررسی کردن امنیت و Logging و ... است. جداسازی کد
به صورتی که بتوانیم بخشهای مختلف را مورد بررسی قرار دهیم، کار بسیار مشکلی
است و اینکار شما و گروه طراحی را دشوارتر از قبل میکند.
مشکل سایت قسمت بالا مشکل تمام سیستمهای شیءگرا
است. به کارهای مذکور که برای تمام قسمتهای سایت یکسان هستند، Cross-Cutting Concern گفته میشود. در حقیقت، Cross-Cutting
Concern ،نگرانی هایی هستند که
در چندین قسمت سیستم مورد توجه قرار میگیرند بهعنوان نمونه، در مثال بالا
بررسی امنیت و تراکنشهای پایگاهداده و عملیات Logging))
این نگرانی ها معمولاً نمیتوانند در یک ماجول
بهطور کامل کپسوله شوند. همانطور که در مثال مذکور میبینید، باید چندین
فراخوانی هر کدام از آنها را در سیستمهای امنیتی بالا قرار دهیم تا بتوانند آنها
را به قسمت برقراری امنیت متصل کنند.
Cross-Cutting Concern جایی است که دیگر مدل
شیءگرا جواب کارآمدی به ما نمیدهد.
در 1997 گریگور کیزالس و گروهش در زیراکس پارک
مفهومی را معرفی کردند که
Aspect Oriented Programming یا به اختصار AOP نامیده میشود. نام
اولیه این پروژه تجزیه و سرهم کردن
(Decomposition & Weaving) بود،
اما بعدها به AOP تغییر نام داد. کیزالس درباره این موضوع میگوید:
«این نظر یکی از اعضای گروه بود که به درستی اشاره کرد تلفظ این نام بسیار سخت
است و در ضمن به نظر کمی زیادی
Nerdy است.
AOP، در حقیقت بهعنوان یک
مکمل برای برنامهنویسی شیءگرا عرضه شد تا ضعفهایی را که در قسمت قبل به اختصار
به آن اشاره کردیم پوشش دهد. کار اصلی AOP کار کردن با Cross-Cutting Concern ها است. اما بیایید دقیقتر به مفهوم AOP بپردازیم. شما برای
نوشتن یک برنامه علاوه بر منطق کاری برنامه خود (که جریان اصلی برنامه است)،
باید بهطور همزمان نگران بسیاری از کارهای حاشیهای دیگر نیز باشید. سؤالهایی
از قبیل: «اگر یک قسمت از برنامه مطابق پیشبینی کار نکرد، چه کنم؟» یا «چگونه
امنیت را به برنامهام تزریق کنم؟» یا حتی «چگونه مدیریت حافظه را انجام دهم؟»،
سؤالاتی هستند که هر برنامهنویس در طول یک پروژه بارها از خود میپرسد. اما
چگونه باید با این
Concern ها (نگرانی ها) کنار
آمد؟ شاید به ذهن همه ما این فکر خطور کرده باشد که چه خوب بود اگر کارهای حاشیهای
و کد اصلی در دو فرآیند کاملاً جدا تولید میشدند تا علاوه بر افزایش Modularization،
بتوانیم نگرانیهای خود را تقسیم کنیم. در حقیقت این ایده، فکر اصلی پشت سر AOP است. البته انجام
کارهای حاشیهای در پشت صحنه ایدهای قدیمیتر از AOP است. بهعنوان مثال، میتوانید
انجام مدیریت حافظه و
Garbage Collection توسط JVM در زبان جاوا را در نظر
بگیرید. شما میتوانید کد خود را بدون نگرانی درباره مسائل مربوط به دو مورد
ذکرشده در بالا بنویسید، زیرا جاوا خود با آنها کنار میآید. انجام جداگانه کد
و کارها باعث افزایش
modularization میشود و همه برنامهنویسان
میدانند که این افزایش میتواند چهقدر دنیا را زیبا کند!
جان هانت میگوید: «من هنوز میتوانم خودم را
جلوی سورس کد یک برنامه تصور کنم در حالیکه سعی میکنم منطق کاری پایهای آن را
از بقیه چیزهای دور و برش مجزا سازم.» شاید شما هم در غم او شریک باشید. درک
سازوکار اصلی کارکرد یک برنامه، موضوع بسیار مهمی است که معمولاً بسیار سخت
انجام میگیرد. زیرا تمام کد اصلی برنامه با جزئیات حاشیهای (البته نه لزوماً
از نوع پیشپا افتاده) مخلوط شده است که علاوه بر مشغول ساختن ذهن کدنویس و کند
کردن فرآیند عیبیابی، باعث میشود تا درک روند کاری اصلی کد نیز برای کسی که
سعی در فهم آن دارد، بسیار مشکل شود. اما راه حل گروه کیزالس برای این موضوع چه
بود؟ چیزی که آنها عرضه کردند میتوانست Cross-Cutting Concernها را به صورت یک ماجول جداگانه مورد بحث قرار دهد. ماجولی که
علاوه بر عملیات اصلی که باید انجام دهد، در برگیرنده شرط اجرای این Concernها نیز است. بگذارید با
ذکر یک مثال موضوع را مشخص کنیم. به همان بحث امنیت باز میگردیم. در مدل شیءگرا
راهحل ما ساختن یک کلاس (یا یک روش در یک کلاس) برای بررسی بحث دسترسی کاربر
موردنظر بود. پس از ساخت یک ماجول برای بررسی، با اضافه کردن عبارتهای فراخوانی
آن در قسمتهای مختلف برنامه، کار را تکمیل میکنیم. در حقیقت، روند کاری در مدل
شیءگرا در دو جا دنبال میشود. یکی کلاس یا روشی که برای بحث امنیت نوشتهایم،
یکی هم مکانهای فراخوانی آن از کد اصلی برنامه.
اما راهحل AOP متفاوت است. در AOP دو مکان قبلی (ماجول
امنیت و مکان فراخوانی) تقریباً با یکدیگر ترکیب میشوند. به این ترتیب که شما
کد مربوط به Concern (در مثال ما چک کردن امنیت) را در یک ماجول جداگانه قرار میدهید
و سپس در همان ماجول شرطهای فراخوانی این کد را ذکر میکنید (بهعنوان مثال،
درباره بحث موردنظر ما باید بررسی هویت در مواردی انجام شود که یک روش امن
فراخوانی میشود). به این ترتیب، تمام روند کاری Cross-cutting Concernها از سازوکار اصلی برنامه مجزا میشوند. کاملاً مشخص است که این
جدایی میتواند چه مزیتهایی را برای سیستم به ارمغان بیاورد. بهعنوان مثال، میتوان
این دو بخش کد (کد اصلی و
Cross-cutting Concernها) را به دو گروه
مختلف برنامهنویسی واگذار کرد یا حتی درباره خود Cross-cutting Concernها میتوان هر بخش را به خبره آن کار سپرد. مثلاً بخش بررسی کردن
امنیت به متخصصان امنیت یا بخش تراکنشهای پایگاهداده به متخصصان آن.
شاید باز هم اصرار کنید که تمام این کارها با
مدل شیءگرا نیز قابل دسترس بود (بحث کاملتری درباره این مقایسه در بخش آخر
مقاله آمده است). البته درست میگویید! اما توجه داشته باشید که در یک مدل شیءگرا
برنامهنویس باید از نکات زیر آگاهی داشته باشد:
در تمام این سه مرحله امکان رخ دادن خطا وجود
دارد. به خصوص در قسمت آخر که فراموشی برنامهنویس برای فراخوانی تمام روشهای
لازم از شایع ترین اشتباهها است. اما با استفاده از AOP، با
توجه به جدا شدن دغدغههای برنامهنویسان این دو بخش چنین مشکلاتی اصولاً مطرح
نمیشوند (البته مشکلات دیگری مطرح میشوند که چند نمونه از آنها در قسمت آخر
مقاله مطرح میشود). با استفاده از AOP
میتوانیم بدون تغییر کد اصلی، Concernهایی به آن اضافه کنیم که رفتارهای سیستم را تقویت کند. در بخش بعد
به بررسی مفاهیم اصلی AOP
میپردازیم.
این یک AOP است...
چه چیزی مُهر AOP را روی یک سیستم میزند؟
مسلماً معیار طراحی یک سیستم براساس AOP، این نیست که سازنده آن اینگونه بگوید. این موضوع که آیا یک
پروژه از AOP استفاده میکند یا خیر، به مکانیزم کاری آن
پروژه و ماهیت نیازهای آن بستگی دارد. بهعنوان مثال، کل عملیات مربوط به پرینت
کردن یک سند را در نظر بگیرید. شما ممکن است در قسمتهای مختلفی از برنامه خود
عملیات پرینت کردن را نیاز داشته باشید. به این ترتیب، باید بارها روشهای مربوط
به آن را فراخوانی کنید. ممکن است با توجه به این تعاریف شما پرینت را به صورت
یک Concern در نظر بگیرید. اما آیا این طراحی یک طراحی
منطقی است؟ در تعریف
Concernهایی که در AOP مورد توجه قرار میگیرند
یک نکته فرعی وجود دارد و آن این است: این Concernها معمولاً به صورت یک
ماجول جداگانه (در مدل های قبل از AOP
)دستهبندی نمیشوند.
این تعریف جواب سؤال بالا را مشخص میکند. در مثال بالا روشهای مربوط به عملیات
پرینت کردن برای برنامهنویس کاملاً مشخص است و مطرح کردن این نکته که او ممکن
است فراموش کند که آنها را فراخوانی کند تا حدودی خندهدار به نظر میآید. پس
چندان منطقی نیست که پرینت کردن را به وسیله AOP پیادهسازی کنیم. عدم
استفاده از AOP در مثال بالا بدیهی بود، اما ایده پشت این مطلب
را مشخص میکند. AOP باید در مواردی به کار گرفته شود که به آن نیاز
است. وقتی مکانیزمی که وجود AOP
را میطلبد، موجود نیست میتوانیم خیلی راحت از الگو
های دیگر استفاده کنیم. پس باید قبل از استفاده از AOP نیازهای یک سیستم را
کاملاً تحلیل کنیم تا لزوم یا عدم لزوم به کارگیری آن را مشخص سازیم. در ادبیات AOP،
تعاریفی رسمیتر از مفاهیم اولیه آن وجود دارد که موارد استفاده AOP را روشنتر میکند.
Quantification ایدهای است که در آن
یک برنامهنویس میتواند با نوشتن یک سری عبارت در قالب یک واحد و به صورت مجزا
از بقیه سیستم، بسیاری از جاهای غیرمحلی برنامه را تحتتأثیر قرار دهد. درباره AspectهاQuantification میتواند به این صورت معنی شود که توانایی Aspectها برای اثرگذاری در
نقاط مختلف یک برنامه است.
Obliviousness بیانگر این ایده است که
یک برنامه اطلاعی از این که یک
Aspect کی و کجا اجرا میشود،
ندارد. نتیجه اینکه شما نمیتوانید با نگاه کردن به کد بگویید کدام Aspect اجرا میشود و این باعث
ارتقای مفهوم جداسازی میشود.
دو مفهوم ذکر شده در بالا (تعیین عناصر و فراموشکاری)
از دیدگاه تعریف
Filman-Friedman دو مفهوم لازمالاجرا
در زمینه طراحی برنامههای
Aspect Oriented هستند. در حقیقت، با
توجه به این تعریف هر طراحی باید شامل هر دو ایده بهطور کامل باشد. هرچند خیلیها
این دو تعریف را بسیار سختگیرانه میدانند، زیرا برنامههای بسیاری با طراحی AOP وجود دارند که تنها به
خاطر جلوگیری از اختلاط دو کد، یکی از آنها Aspect محسوب میشود که این
طراحی لزوماً نقاط مختلف برنامه را مورد هدف قرار نمیدهد (مثال رعایت نشدن
تعیین عناصر). همچنین در بعضی مواقع، برنامهنویسان AOP محل فراخوانی Aspect را با علامتی خاص مشخص
میسازند (مثال رعایت نشدن فراموشکاری)
دو اصطلاح Tangling و Scattering
● پراکندگی: (Scattering) پیادهسازی
یک Concern، پراکنده شده است هر گاه کد آن بین چند ماجول پخش شده باشد.
● پیچش: (Tangling) پیادهسازی یک Concern،
پیچیده شدهاست هر گاه کد آن با کد یک Concern دیگر مخلوط شده باشد.
پراکندگی و پیچش در Aspect Oriented بهعنوان
علائم یک Cross-Cutting Concern
در نظر گرفته میشوند. در حقیقت عموماً Concernهایی که چنین خصوصیاتی
را در پیادهسازیهای غیر AOP
داشته باشند، مورد بحث قرار میگیرند.
باید اعتراف کرد که با وجود ارزشمند بودن
توضیحات و تئوریهای برنامهنویسی، تا وقتی که آنها را در عمل، به وسیله برنامهنویسی
مورد آزمایش قرار ندهیم، در حقیقت کار خاصی انجام ندادهایم. در ادامه سعی میکنیم
مفاهیم مطرح شده را به همراه کد آن مورد بررسی قرار دهیم تا علاوه بر معرفی و
تعریف مفاهیم موجود در AOP، با نحوه به کارگیری آنان نیز آشنا شویم، اما قبل از هر چیز
باید به این سؤال پاسخ دهیم که کجا میتوانیم AOPبنویسیم؟