Restangular چیست؟
// Restangular returns promises Restangular.all('users').getList() // GET: /users .then(function(users) { // returns a list of users $scope.user = users[0]; // first Restangular obj in list: { id: 123 } }) // Later in the code... // Restangular objects are self-aware and know how to make their own RESTful requests $scope.user.getList('cars'); // GET: /users/123/cars // You can also use your own custom methods on Restangular objects $scope.user.sendMessage(); // POST: /users/123/sendMessage // Chain methods together to easily build complex requests $scope.user.one('messages', 123).one('from', 123).getList('unread'); // GET: /users/123/messages/123/from/123/unread
وابستگی ها
شروع پروژه
// Add Restangular as a dependency to your app angular.module('your-app', ['restangular']); // Inject Restangular into your controller angular.module('your-app').controller('MainCtrl', function($scope, Restangular) { // ... });
برخی از متدهای RestAngular
نام متد | پارامترهای ارسالی | توضیحات |
one | route, id | این متد یک RestAngular object ایجاد میکند که از آدرسی که در route قرار داده شده با id مشخص دریافت میشود. |
all | route | این متد یک RestAngular object که لیستی از المنت هایی را که در آدرس route قرار دارد، دریافت مینماید. |
oneUrl | route, url | این متد یک RestAngular object ایجاد میکند که یک المنت از url خاصی را بازگشت میدهد. مانند: Restangular.oneUrl( 'googlers' , 'http://www.google.com/1' ).get(); |
allUrl | route, url | این متد مانند متد قبل است با این تفاوت که یک مجموعه را بازگشت میدهد. |
copy | formElement | این متد یک کپی از المنتهای یک فرم را ایجاد میکند که ما میتوانیم آنها را تغییر دهیم. |
restangularizeElement | parent,element, route, queryParams | یک المنت جدید را به صورت Restangularize تغییر میدهد. |
restangularizeCollection | parent, element, route, queryParams | یک کالکشن Collection را به صورت Restangularize تغییر میدهد. |
عدم اجرا در هاست
مقدمه
در سازمان ها، دادهها و اطلاعات معمولاً به دو شکل در سیستمها پیاده سازی میگردد:
• سیستمهای عملیاتی OLTP:
این سیستمها باعث میگردند تا چرخ کسب و کار بگردد. وجود این سیستمها سبب میشود تا دادههای مربوط به کسب و کار، به بانک اطلاعاتی وارد شوند. این سیستمها عموماً:
o به دلیل کوتاهی عملیات دارای سرعت قابل توجهی میباشند.
o محیطی جهت ورود دادهها میباشند.
o معمولاً اپراتورها، استفاده کنندههای آن هستند.
• سیستمهای اطلاعاتی OLAP ، DW/BI، DSS :
این سیستمها باعث میگردند تا چرخش کسب و کار را بنگرید. فلسفه بکارگیری این سیستمها در سازمان این است که اطلاعات مورد نیاز مدیران، از درون دادههای سیستمهای عملیاتی موجود، استخراج گردد. این سیستمها عموماً:
سیستمهای عملیاتی در جامعه ما سابقه بیشتری داشته و متخصصین فناوری اطلاعات عموماً با طراحی و تولید چنین سیستم هایی آشنایی کافی دارند. متاسفانه جایگاه سیستمهای اطلاعاتی در جامعه ما کمتر شناخته شده و متخصصین فناوری اطلاعات بندرت با مفاهیم و نحوه پیاده سازی آن آشنایی دارند.o به دلیل آنالیز حجم انبوهی از داده ها، معمولاً کندتر از سیستمهای عملیاتی میباشند.
o محیطی جهت تولید گزارشات تحلیلی و آماری میباشند.
o معمولاً مدیران و تصمیم گیرندگان سازمان ها، استفاده کنندگان آن میباشند.
این نکته حائز اهمیت است که سیستمهای اطلاعاتی یک سیستم یا محصول نیستند که بتوان آنها را خریداری کرد. بلکه یک راهبرد (Solution, Approach) هستند و در حقیقت هر راهبردی مربوط به یک نوع کسب و کار (Business) و یا سازمان میباشد و نمیتوان فرمول واحدی را برای حتی سازمانهای مشابه، ارائه نمود.
گارتنر در ابتدای سال 2011 گزارشی را منتشر کرده که نشان میدهد بازار BI با 9.7 % رشد، ارزشی بالغ بر 10.8 بیلیون دلار داشته، ولی متاسفانه پروژههای آن به طور متوسط با 75% شکست مواجه شده است. در حالیکه 4 سال پیش، این رقم حدود 50% بود. این موسسه BI را پنجمین اولویت مدیران IT ذکر کرده است.
مفاهیم و مباحث مربوط به Data Warehouse به اواسط دهه 1980 برمی گردد، به زمانی که IBM تحقیقاتی را در این زمینه شروع کرد و نتیجه آنرا «Information Warehouse» نامید و هنوز هم در برخی منابع از این واژه بجای Data Warehouse استفاده میشود. از این پس برای راحتی از اختصار DW بجای Data Warehouse استفاده میشود. انبارهای داده جهت رفع نیاز رو به رشد مدیریت دادهها و اطلاعات سازمانی که توسط پایگاههای داده سیستمهای عملیاتی غیر ممکن بود، ساخته شدند.
انبار داده به مجموعه ای از دادهها گفته میشود که از منابع مختلف اطلاعاتی سازمان جمع آوری، دسته بندی و ذخیره میشود. در واقع یک انبار داده مخزن اصلی کلیه دادههای حال و گذشته یک سازمان میباشد که برای همیشه جهت انجام عملیات گزارش گیری و آنالیز در دسترس مدیران میباشد. انبارههای داده حاوی داده هایی هستند که به مرور زمان از سیستمهای عملیاتی آنلاین سازمان، استخراج میشوند. بنابراین سوابق کلیه اطلاعات و یا بخش عظیمی از آنها را میتوان در انباره دادهها مشاهده نمود.
از آنجائیکه انجام عملیات آماری و گزارشات پیچیده دارای بار کاری بسیار سنگینی برای سرورهای پایگاه داده میباشند، وجود انبار داده سبب میگردد که این گونه عملیات تاثیری بر فعالیت برنامههای کاربردی سازمان نداشته باشد.
همانگونه که پایگاه داده سیستمهای عملیاتی سازمان (برنامههای کاربردی) به گونه ای طراحی میشوند که انجام تغییر، حذف و اضافه داده به سرعت صورت پذیرد، در مقابل انبار دادهها دارای معماری ویژه ای میباشند که موجب تسریع انجام عملیات آماری و گزارش گیری میشود. در حقیقت میتوان اینگونه بیان نمود که انباره داده یک مخزن فعال و هوشمند از اطلاعات است که قادر است اطلاعات را از محیطهای گوناگون جمع آوری و مدیریت کرده و نهایتا پخش نماید و در صورت لزوم نیز سیاستهای تجاری را روی آنها اجرا نماید.
Bill Inmon:
او را پدر DW مینامند، از دیدگاه او DW هسته مرکزی چیزی است که او آنرا CIF اختصار (Corporate Information Factory) مینامد، که پایه و اساس BI بر مبنای آن قرار دارد. وی از طرفداران Top-Down Design میباشد که معتقد است در زمان طراحی باید با دیدی سازمانی، CIF را مدل سازی، ولی بصورت دپارتمانی پیاده سازی کرد (Think Globally, Implement Locally). در این نوع طراحی از DW به Data Mart خواهیم رسید.
Ralph Kimball Ph.D:
به نظر وی DW چیزی نیست جز یک کپی از دادههای عملیاتی که به طرز خاصی برای گزارشات و تحلیلهای آماری، آماده و ساختمند شده است. به بیان دیگر DW سیستمی است جهت استخراج، پالایش، تطبیق و تحویل اطلاعات منابع داده ای به یک بانک اطلاعاتی Dimensional و اجرای Query و گزارشات آماری و تحلیلی برای اهداف تصمیم گیری و استراتژیک سازمان.
وی معرفی کننده یکی از اساسیترین مفاهیم طراحی یعنی Dimensional Modeling است؛ ماحصل چنین ایده ای، اساس شکل گیری مدلی است که امروزه کارشناسان آنرا به نام Cube میشناسند. وی از طرفداران Bottom-Up Design است که در این نگرش از Data Mart به DW میرسیم. این روش به نظر عملیتر از روشی میباشد که به یکباره DW جامع و کامل برای اهداف سازمانی طراحی و پیاده سازی گردد.
تعریف انبار داده:
W.H.Inmon پدر DW آنرا چنین تعریف میکند:
o انبار داده به طور فیزیکی، کاملاً جدا از سایر سیستمهای عملیاتی است.
o دادههای DW مجموعه ای Aggregated و Atomic از دادههای تراکنشهای سیستمهای عملیاتی است که سوای کاربرد آنها در سیستمهای عملیاتی، برای مقاصد مدیریتی نیز استفاده خواهد شد.
به بیان دیگر DW راهبردی است که دسترسی آسان به اطلاعات درست (Right Information)، در زمانی درست (Right Time) ، به کاربران درست (Right Users)، را فراهم میآورد تا «تصمیم گیری سازمانی» قابل انجام باشد. DW صرفاً یک محصول نرم افزاری و یا سخت افزاری نیست که بتوان آنرا خریداری نمود بلکه فراتر از آن و در حقیقت یک محیط پردازشی میباشد که کاربران میتوانند از درون آن اطلاعات مورد نیاز خود را بیابند.
DW اطلاعات خود را از سایر بانکهای اطلاعاتی از نوع OLTP و یا سایر DWهای لایه پایینتر و به صورت دسته ای (Batch) و یا انبوه (Bulk Loading) جمع آوری میکند. یک DW به صورت سنتی باید شامل دادههای Historic سازمان باشد و میتوان اینگونه بیان نمود که در DW هرچه دادههای قدیمیتری موجود باشد، اعتبار تحلیلهای آماری سیستم افزایش خواهد یافت.
دادههای سیستم عملیاتی را نمیتوان بلافاصله درون بانک اطلاعاتی DW لود نمود، چنین داده هایی باید آماده سازی، پالایش و همگون گردند تا شرایط لود در DW را داشته باشند. حداقل کاری که انتظار داریم یک DW در مورد دادهها برای ما برآورده سازد شامل موارد زیر است:
o استخراج دادهها از منابع مختلف (مبدإ)با هر با اجرای پروسه فوق یکی از سه مورد زیر، بسته به نیاز طراحی و محدودیتهای تکنولوژی رخ خواهد داد:
o تبدیل دادهها به فرمتی یکسان
o لود دادهها به جداول مربوطه (مقصد)
o تمام دادهها در DW با دادههای جدید جایگزین خواهند گردید(Full Load, Initial Load, Full Refresh).
o دادههای جدید به دادههای موجود اضافه خواهند گردید (Incremental Load (Inserted data.
o نسخه جدیدی از دادههای کنونی به سیستم اضافه خواهند گردید (Incremental Load (Updated data.
ویژگیهای دادههای درون DW
دادههای DW از نگاه Inmon دارای 4 ویژگی اصلی زیر هستند:
o فقط خواندنی (Non-Volatile):
هیچ رکوردی و یا داده ای Update نخواهد شد و صرفاً رکوردهایی که محتوای مقادیر جدید دادهها هستند، به سیستم اضافه خواهند شد.
o موضوع گرا (Subject-Oriented):
منظور از «موضوع» پایههای اساسی یک کسب و کار هستند، به شکلی که با حذف یکی از این پایه ها، شاید ماهیت آن کسب و کار از ریشه دگرگون شود. برای مثال موضوعاتی چون «مشتری» و یا «بیمه نامه» برای شرکتهای بیمه.
o جامع (Integrated):
باید تمامی کدهایی که در سیستمهای عملیاتی وجود دارند و معانی یکسانی دارند، برای مثال کد جنسیت، در DW به یک روش ذخیره و نمایش داده شوند.
o زمانگرا (Time Variant):
هر رکورد باید حاوی فیلد و یا کلیدی باشد که نمایانگر این باشد که این رکورد در چه زمانی ایجاد، استخراج و ذخیره شده است. از آنجا که دادههای درون سیستمهای عملیاتی آخرین و به روزترین داده هر سیستم میباشد، نیازی به وجود چنین عنصری در سیستمهای OLTP احساس نمیگردد، ولی چون در DW تمام دادههای نسخ قدیمی دادههای سیستمهای عملیاتی موجود میباشد، باید حتماً مشخص گردد که هر داده ای در سیستمهای عملیاتی در چه زمانی، چه مقادیری داشته است. این عنصر زمانی کمک میکند تا بتوانیم:
منبع: کتاب آقای خشایار جام سحر با عنوان بانک داده تجمیعیo گذشته را آنالیز کنیم.
o اطلاعات مربوط به حال حاضر را بدست آوریم.
o آینده را پیش بینی کنیم.
Inmon
Continuous & Discrete Dimension Management
Define data management via dates in your data
Continuous time
When is a record activeDiscrete time
Start and end dates
A point in time
Snapshot
Kimball
Slowly Changing Dimension Management
Define data management via versioning
Type I
Change record as requiredType II
No History
Manage all changesType III
History is recorded
Some history is parallel
Limit to defined history
Kimball | Inmon |
Business-Process-Oriented Stresses Dimensional Model, Not E-R | Subject-Oriented Integrated Non-Volatile Time-Variant |
Bottom-Up and Evolutionary | Top-Down |
Integration Achieved via Conformed Dimensions | Integration Achieved via an Assumed Enterprise Data Model |
Star Schemas Enforce Query Semantics | Characterizes Data marts as Aggregates |
Kimball | Inmon | |
Bottom-up | Top-down | Overall approach |
Data marts model a business process;enterprise is achieved with conformed dims | Enterprise-wide DW feeds departmental DBs | Architectural structure |
Fairly simple | Quite complex | Complexity of method |
Process oriented | Subject or data driven | Data orientation |
Dimensional modeling; departs from traditional relational modeling | Traditional ERDs and DIS | Tools |
High | Low | End user accessibility |
Slowly Changing | Continuous & Discrete | Timeframe |
Dimension keys | Timestamps | Methods |
(در مورد نوشتن ویرایش محصول هم حق با شماست،متاسفانه بیشتر خریداران به طراحی جلد و جدید بودن کتاب توجه میکنند تا محتوای آن!کتابهای بسیاری هستند که باید گفت افتضا ترجمه شدند ولی فروش بدی نداشتند!)
شاید مهمترین اصل در سیستمهای توزیع شده، تقسیم وظایف در سخت افزارهای جداگانه و نحوه مدیریت ارتباط بین این وظایف باشد. مدیریتی که بدون آن، زمانیکه تعداد وظایف سیستم شما زیاد میشود، سیستم را با مشکلات جدی روبرو میکند. به احتمال زیاد شما نیز تاکنون با چنین مشکلاتی مواجه شدهاید، آن هم زمانیکه تعداد Applicationهای سیستمهایتان زیاد میشود و به تدریج وابستگیها و ارتباطات بین آنها نیز افزایش پیدا کرده و بدلیل اینکه شما از قبل زیرساختی برای مدیریت این ارتباطات ایجاد نکردهاید، کم کم کنترل این ارتباطات از دست شما خارج شدهاست. به همین دلیل من نیز میخواهم پیاده سازی سیستمهای توزیع شده را از نحوه مدیریت ارتباطات و وابستگیهای قسمتهای مختلف یک سیستم آغاز کنم تا بتوانیم از ابتدای ایجاد سیستم توزیع شده، زیرساخت درستی نیز برای مدیریت وابستگیها و ارتباطات قسمتهای مختلف آن داشته باشیم. پس بیایید با ارائه مثالی که به احتمال زیاد شما هم تابحال با آن روبرو شدهاید، با هم ببینیم که چگونه داشتن یک روش واحد و انعطاف پذیر برای مدیریت ارتباط بین سیستمهای مختلف میتواند به ما در تقسیم بندی وظایف، یکپارچگی سیستم، بالا بردن کارآیی و مدیریت بهتر کل سیستم کمک کند.
فرض
کنید ما چندین سیستم بزرگ مرتبط یا غیر مرتبط به هم داریم که هر کدامشان از چندین
زیر سیستم تشکیل شدهاند. ارتباط و وابستگی این سیستمها به این صورت است که یا از سیستمهای دیگر سرویسهایی را دریافت میکنند، یا دادههای مورد استفاده در آنها توسط سیستمهای دیگر تولید میشوند و آنها در بازه زمانی مشخصی این دادهها را در سیستمهای خودشان بروزرسانی میکنند.
همانطور که میبینید کل سیستم ما از همکاری تعدادی سیستم بزرگ تشکیل شدهاست که هرکدام از این سیستمهای بزرگ نیز از همکاری دو نوع زیر سیستم تشکیل شدهاند. نوع اول این زیرسیستمها که با عبارت Sub System مشخص شدهاند، زیر سیستمهایی هستند که تنها در همان سیستم استفاده میشوند و نوع دوم که با عبارت Common Sub System مشخص شدهاند و ما نیز زیاد با آنها روبرو میشویم، زیرسیستمهایی هستند که بصورت مشترک بین دو یا چند سیستم بزرگ مورد استفاده قرار میگیرند. بعنوان مثال میتوان زیرسیستم ارسال پیامک، ارسال ایمیل، مدیریت Log، زیر سیستم پرداخت و هر نوع زیرسیستم دیگری را که در سیستمهای مختلف بصورت مشترک استفاده میشود، نام برد.
به احتمال زیاد همه کسانیکه در سیستمهای رو به رشد و بزرگ کار کردهاند خوب میدانند که با بزرگتر شدن سیستمها و افزایش تعداد سیستمهای مرتبط و وابسته به هم، در صورت نبود یک روش واحد و انعطاف پذیر برای مدیریت ارتباط بین سیستمهای مختلف، چه مشکلاتی برای کل سیستم بوجود میآید. مشکلاتیکه در ابتدای شروع سیستم به هیچ وجه به چشم نمیآمدند، اما با توسعه و رشد سیستم، برایمان جدی میشوند.
بطور مثال زمانیکه اطلاعات پایه سیستم شما توسط یک یا چند سیستم تولید میشوند و سایر سیستمها بخاطر پایین نیامدن کارآیی سیستم خودشان مجبورند دادههای سیستم پایه را در سیستم خودشان Replicate کنند، شما چه روشی را برای بروز رسانی دادههای سایر سیستمها ارائه میدهید؟ شاید سادهترین و اولین روشی که به ذهنمان برسد، ایجاد یک Job باشد که با اجرا شدن در بازه زمانی مشخصی (مثلا شبانه) عملیات بروزرسانی را انجام دهد. این روش دو مشکل اساسی دارد: اول اینکه بصورت RealTime نیست. یعنی از زمانیکه داده وارد سیستم پایه میشود، تا زمانیکه Job اجرا شود، سیستمهای دیگر نمیتوانند از داده جدید استفاده کنند و دوم اینکه با اضافه شدن به تعداد سیستمهای وابسته شما مجبورید یا یک Job جدید را برای آن پیاده سازی کنید، یا قبلی را تغییر دهید. شاید شما با پیاده سازی چند سرویس در سیستمهای پایه و وابسته بتوانید مشکل RealTime نبودن بروز رسانی داده را حل کنید، اما این روش نیز بدون مشکل نیست. شاید اولین مشکل این روش این باشد، در صورتیکه در زمان فراخوانی، یکی از طرفین در دسترس نباشد، دادهها بروز رسانی نشوند و حل این مشکل پیچیدگی زیادی را برای شما بوجود بیاورد و دومین مشکل این است که در این روش نیز مانند روش قبل، با اضافه شدن به تعداد سیستمهای وابسته شما مجبورید یا سرویسهای جدیدی را برای این کار ایجاد کنید، یا سرویسهای قبلی را تغییر دهید. تکرار این روال باعث میشود شما پس از مدتی با انبوهی از سرویسهای مختلف رو برو شوید که مدیریت آنها برای شما بسیار دشوار است.
یکی دیگر از مشکلاتیکه ممکن است بوجود بیاید این است که با بزرگتر شدن و افزایش تعداد سیستمها، تعداد زیر سیستمهای تکراری نیز افزایش پیدا میکند که این خود ممکن است باعث شود یکپارچگی سیستم ما از بین برود. بنظر شما بهتر نبود زیرسیستمهای تکراری را اینقدر در سیستمهای مختلف تکرار نکنیم و با درنظر گرفتن آنها بعنوان یک یا چند زیرسیستم مستقل، کارآیی، یکپارچگی و مدیریت کل سیستم را افزایش دهیم؟
وجود مشکلات فوق و سایر مشکلاتی که ممکن است با بزرگتر شدن سیستم و افزایش تعداد آنها بوجود بیایند (که باتوجه به تجربه شما بنظرم نیازی به ذکر آنها نیست) با مرور زمان پیچیدگیهای بسیار زیای را در سیستم ما بوجود میآورد که شاید حل کردن آن امکان پذیر نباشد یا حداقل نیاز به صرف زمان و هزینه زیادی داشته باشد. پس شاید بهتر باشد در ابتدای پیاده سازی سیستم، زیرساخت درستی را برای ارتباط بین سیستمهای مختلف ایجاد کنیم.
اما چگونه میتوانیم این مجموعه سیستم را با هم ادغام کنیم و برای همه آنها یک هدف را مشخص کنیم و به آنها اجازه بدهیم با استفاده از یک روش واحد، انعطاف پذیر و کم هزینه، با یکدیگر در ارتباط باشند؟
باید بگویم که این مشکل با استفاده از Message Broker حل میشود .
یک Message Broker یک کامپوننت فیزیکی است که ارتباطات بین سیستمهای مختلف را مدیریت میکند و درواقع برای حل مشکلات مرتبط با نحوه مدیریت ارتباطات و وابستگیهای بین سیستمهای مختلف طراحی شده است. با استفاده از Message Broker بجای اینکه سیستمهای مختلف بصورت مستقیم با یکدیگر در ارتباط باشند، تنها با Message Broker در ارتباط اند و در اینجا Message Broker نقش یک Interface را بصورتی ایفا میکند که وظیفه آن به حداقل رساندن وابستگیهای مستقیم بین سیستمهای مختلف است. همچنین نحوه ارتباط قسمتهای مختلف هم به این صورت است که یک سیستم با ارائه مشخصات گیرنده یا گیرندگان، یک Message را برای Message Broker ارسال میکند و سپس Message Broker با روشها و الگوریتمهایی که در اختیار دارد و با جستجو در بین سیستمهایی که با آن مشخصات در آن ثبت شدهاند، Message را برای آنها ارسال میکند.
ارتباط بین Application ها تنها شامل ارسال کننده و Message broker و گیرندههای مشخص شدهاست و سایر سیستمها در آن دخیل نیستند. همچنین بدلیل اینکه Message Brokerها از یک صف انتقال اطلاعات استفاده میکنند، احتمال از دست رفتن Messageها به حداقل ممکن میرسد. یعنی زمانیکه یک سیستم، Messageی را برای Message Broker ارسال میکند، Message Broker تا زمانیکه دریافت کنندگان Message، آن را دریافت نکنند، آن Message را از صف انتقال حذف نمیکند. پس زمانیکه یک ارسال کننده Messageی را برای Message Broker ارسال میکند، حتی در صورتیکه دریافت کننده یا دریافت کنندگان در دسترس نیز نباشند، Message Broker این قابلیت را دارد تا زمانیکه دوباره دریافت کنندگان در دسترس باشند، Messageها را نگهداری کند. زیرا از دیدگاه کنترل جریان، Message Brokerها محدودیتی در تعداد سیستمهای متصل به خودشان و زمان اتصال آنها ندارند. یعنی Message Brokerها این قابلیت را دارند حتی در زمان اجرا نیز سیستمهای جدید را بپذیرند. بطور خلاصه Message Brokerها مدیریت همکاری بین سیستمهای مختلف را بر عهده دارند. قرار دادن Message Brokerها بین ارسال کنندگان و دریافت کنندگان، انعطاف پذیری را در ارتباط بین سیستمهای مختلف افزایش میدهد و با کمترین میزان تغییر در ارسال کنندگان و گیرندگان میتوانید قابلیتهای جدیدی را به سیستم اضافه کنید.
با این روش شما میتوانید با کمترین هزینه برای سیستمهای درگیر، تغییرات سیستمهای پایه را در سیستمهای وابسته اعمال کنید؛ آن هم بصورتیکه با افزایش تعداد سیستمهای وابسته، نیازی به تغییر در سیستم پایه و سایر سیستمها نباشد. همچنین با این روش شما به راحتی و کمترین هزینه میتوانید تمامی زیرسیستمهای خود ازجمله زیرسیستمهای مشترک را بصورت یک زیرسیستم مستقل پیاده سازی کنید و با این کار یکپارچگی کل سیستم خود را افزایش دهید. کارآیی آنها را بالا ببرید و با مستقل شدن آنها مدیریت آنها را برای خودتان سادهتر کنید.
انواع مختلفی از Message Brokerها وجود دارند که هر کدام از آنها مزایا و معایب خاص خودشان را دارند و به دلیل اینکه من در سری مقالات سیستمهای توزیع شده سعی دارم شما را با مبانی پیاده سازی آنها آشنا کنم، تنها یکی از آنها را مورد بررسی قرار میدهم و مقایسه و تصمیم گیری در مورد اینکه کدامیک از آنها کارآیی بیشتری را برای شما دارد، بر عهده خودتان میگذارم. من در اینجا شناخته شدهترین Message Brokerهایی را که در دسترس هستند و شما میتوانید از آنها استفاده کنید، به شما معرفی میکنم.
لیست Message brokerها:
در فصل بعد من سعی میکنم شما را با Rabbitmq که از معروفترین، پایدارترین و قابل اعتمادترین Message Brokerهایی که شخصا چندین سیستم را با استفاده از آن پیاده سازی کردهام، آشنا کنم و ببینیم که چگونه این ابزار میتواند به ما در رفع مشکلاتیکه در نحوه مدیریت و سازماندهی سیستمهای مختلف بوجود میآیند، کمک کند.
البته این نکته را نیز باید ذکر کنم که همانطور که میبینید همیشه دلیل استفاده کردن از سیستمهای توزیع شده، بالابردن کارآیی نیست. ما میتوانیم برای پیاده سازی سیستمهای توزیع شده دلایل و اهداف دیگری نیز داشته باشیم. همانطور که مشاهده کردید ما نهتنها از Message Brokerها میتوانیم در سیستمهایی که واقعا تمام اجزایشان بصورت توزیع شده پیاده سازی شدهاند، استفاده کنیم، بلکه میتوانیم از آنها برای مدیریت وابستگیها و ارتباطات بین سیستمهای فعلی که داریم نیز استفاده کنیم و درواقع بصورت واقعی و فنی برای همه آنها هدف واحدی را تعریف کنیم. فعلا هدف من این است که با هم ببینیم چگونه میتوانیم وظایف مختلف سیستم را در سخت افزارهای مختلف، تقسیم کنیم و ارتباطات آنها را مدیریت کنیم. در فصلهای بعد میبینیم که برای رسیدن به اهداف دیگر سیستمهای توزیع شده از چه روشها و ابزارهای دیگری میتوان استفاده کرد.
آشنایی با AOP IL Weaving
در دنیای دات نت، ابزارهای چندی امکان انجام IL Weaving را فراهم ساختهاند که تعدادی از آنها به قرار ذیل هستند:
- PostSharp
- LOOM.NET
- Wicca
و ...
در بین اینها، PostSharp معروفترین فریم ورک AOP بوده و در ادامه از آن استفاده خواهیم کرد.
پیشنیاز ادامه بحث
ابتدا یک پروژه کنسول جدید را آغاز کرده و سپس در خط فرمان پاور شل نوگت در VS.NET دستور ذیل را اجرا کنید:
PM> Install-Package PostSharp
مراحل ایجاد یک Aspect برای پروسه IL Code Weaving
ابتدا یک کلاس پایه مشتق شده از کلاسی ویژه موجود در یکی از فریم ورکهای AOP باید تعریف شود. مرحله بعد، کار اتصال این Aspect میباشد که توسط پردازشگر ثانویه IL Code Weaving انجام میشود.
در ادامه قصد داریم همان مثال LoggingInterceptor قسمت دوم این سری را با استفاده از IL Code Weaving پیاده سازی کنیم.
using System; namespace AOP03 { public class MyType { public void DoSomething(string data, int i) { Console.WriteLine("DoSomething({0}, {1});", data, i); } } class Program { static void Main(string[] args) { new MyType().DoSomething("Test", 1); } } }
using System; using PostSharp.Aspects; namespace AOP03 { [Serializable] public class LoggingAspect : OnMethodBoundaryAspect { public override void OnEntry(MethodExecutionArgs args) { Console.WriteLine("On Entry"); } public override void OnExit(MethodExecutionArgs args) { Console.WriteLine("On Exit"); } public override void OnSuccess(MethodExecutionArgs args) { Console.WriteLine("On Success"); } public override void OnException(MethodExecutionArgs args) { Console.WriteLine("On Exception"); } } }
اکنون اگر برنامه را اجرا کنیم، اتفاق خاصی رخ نداده و همان خروجی معمول متد DoSomething در کنسول نمایش داده خواهد شد. بنابراین در مرحله بعد نیاز است تا این Aspect را به کدهای برنامه متصل کنیم.
کلاس OnMethodBoundaryAspect در کتابخانه PostSharp، از کلاس MulticastAttribute مشتق میشود. بنابراین LoggingAspect ایی را که ایجاد کردهایم نیز میتوان به صورت یک ویژگی به متدهای مورد نظر خود افزود:
public class MyType { [LoggingAspect] public void DoSomething(string data, int i) { Console.WriteLine("DoSomething({0}, {1});", data, i); } }
On Entry DoSomething(Test, 1); On Success On Exit
public void DoSomething(string data, int i) { <>z__Aspects.a0.OnEntry(null); try { Console.WriteLine("DoSomething({0}, {1});", data, i); <>z__Aspects.a0.OnSuccess(null); } catch (Exception) { <>z__Aspects.a0.OnException(null); throw; } finally { <>z__Aspects.a0.OnExit(null); } }
خوب! این یک روش اتصال Aspects به برنامه است. اما اگر همانند Interceptors بخواهیم Aspect تعریف شده را سراسری اعمال کنیم چکار باید کرد (بدون نیاز به قرار دادن ویژگی بر روی تک تک متدها)؟
برای اینکار ابتدا نیاز است میدان عملکرد Aspect تعریف شده را توسط ویژگی MulticastAttributeUsage محدود کنیم تا برای مثال به خواص اعمال نشوند:
[Serializable] [MulticastAttributeUsage(MulticastTargets.Method, TargetMemberAttributes = MulticastAttributes.Instance)] public class LoggingAspect : OnMethodBoundaryAspect
[assembly: LoggingAspect(AttributeTargetTypes = "AOP03.*")]
مزیت روش IL Code Weaving نسبت به Interceptors، کارآیی و سرعت بالاتر است. از این جهت که کدهایی که قرار است اجرا شوند، پیشتر در اسمبلی برنامه قرار گرفتهاند و نیازی نیست تا در زمان اجرا، کدی به برنامه به صورت پویا تزریق گردد.
در پروژهی iOS، در فایل AppDelegate.cs، بعد از Forms.Init، کد زیر را کپی کنید:
SfListViewRenderer.Init();
همین کد را در MainPage.xaml.cs در پروژه UWP، قبل از LoadApplication قرار دهید. نیازی به انجام کاری در Android نیست.
سپس Product Key این محصول را به دست آورده و در پروژه XamApp، فولدر Views در فایل SyncfusionLicense قرار دهید.
حال برای نمایش لیستی از محصولات، ابتدا کلاس Product را ایجاد میکنیم. چه در زمانیکه یک Rest api را در سمت سرور فراخوانی میکنیم و چه زمانیکه با دیتابیس بر روی گوشی یعنی Sqlite کار میکنیم، در نهایت لیستی از یک کلاس را داریم (در اینجا Product).
public class Product : Bindable { public int Id { get; set; } public string Name { get; set; } public bool IsActive { get; set; } public decimal Price { get; set; } }
در یک View Model جدید با نام ProductsViewModel، در OnNavigatedToAsync، دیتا را از سرور یا دیتابیس، بر روی گوشی دریافت میکنیم؛ اما در این مثال، برای راحتی بیشتر یک List را New میکنیم:
public class ProductsViewModel : BitViewModelBase { public List<Product> Products { get; set; } public async override Task OnNavigatedToAsync(INavigationParameters parameters) { Products = new List<Product> // getting products from server or sqlite database { new Product { Id = 1, IsActive = true, Name = "Product1" , Price = 12.2m /* m => decimal */ }, new Product { Id = 2, IsActive = false, Name = "Product2" , Price = 14 }, new Product { Id = 3, IsActive = true, Name = "Product3" , Price = 11 }, }; await base.OnNavigatedToAsync(parameters); } }
حال نوبت به دادن یک Template میرسد. مثلا فرض کنید میخواهیم نام را درون یک Label نمایش دهیم و بر اساس فعال یا غیر فعال بودن Product، یک Checkbox را تغییر داده، تیک بزنیم یا نزنیم و در نهایت نمایش قیمت را در یک Label دیگر خواهیم داشت.
<sfListView:SfListView ItemsSource="{Binding Products}"> <sfListView:SfListView.ItemTemplate> <DataTemplate> <FlexLayout x:DataType="model:Product" Direction="Row"> <Label FlexLayout.Basis="50%" Text="{Binding Name}" VerticalTextAlignment="Center" /> <bitControls:BitCheckbox InputTransparent="True" FlexLayout.Basis="25%" IsChecked="{Binding IsActive}" /> <Label FlexLayout.Basis="25%" Text="{Binding Price}" VerticalTextAlignment="Center" /> </FlexLayout> </DataTemplate> </sfListView:SfListView.ItemTemplate> </sfListView:SfListView>
همانطور که میبینید، در DataTemplate از Flex Layout استفاده شده است. Flex Layout در کنار Grid, Stack, Relative, Absolute و سایر Layoutهای Xamarin Forms در پروژه قابلیت استفاده دارد و مزیتهای خاص خود را دارد.
این Data Template توسط List View، حداکثر سه بار ساخته میشود؛ چون View Model در لیست مثال خود، سه Product دارد. خود List View تکنیکهای Virtualization و Cell Reuse را بدون نیاز به هیچ کد اضافهای هندل میکند و Performance خوبی دارد. در View مربوطه یعنی ProductsView.xaml، هر Binding ای (مثل Binding Products) به View Model اشاره میکند، اما درون Data Template، هر Binding به Product ای اشاره میکند که آن ردیف List View، دارد نمایشاش میدهد. برای همین x:DataType را روی Flex Layout درون Data Template به Product وصل کردهایم. در این صورت اگر بنویسیم Binding N_ame، به ما خطا داده میشود که کلاس Product هیچ Property با نام N_ame ندارد که خطای درستی است.
روی BitCheckbox مقدار InputTransparent را برابر با True دادهایم که باعث میشود کلیک روی Checkbox عملا در نظر گرفته نشود. این منطقی است، زیرا عوض کردن مقدار Checkbox در این مثال ما ذخیره نمیشود و کاربرد نمایشی دارد و فقط باعث گیج شدن کاربر میشود.
کنترل BitCheckbox از مجموعه کنترلهای Bit است که اخیرا با BitDatePicker آن آشنا شدهاید. برای آشنایی با نحوه افزودن این کنترلها به یک پروژه، به مستندات Bit Framework مراجعه کنید. خود Syncfusion نیز Checkbox دارد.
حال فرض کنید که قرار است دکمهای برای هر ردیف List View داشته باشیم که با زدن روی آن، اطلاعات Product به سرور ارسال شود و جزئیات بیشتری دریافت و در قالب یک Alert نمایش داده شود. برای این کار، ابتدا به Data Template که Flex Layout است، یک دکمه اضافه میکنیم. سپس Command آن دکمه را به View Model بایند میکنیم. در آن Command البته احتیاج داریم بدانیم درخواست نمایش جزئیات بیشتر، برای کدام Product داده شده. این مهم با Command Parameter شدنی است.
برای پیاده سازی این مثال، در سمت View Model داریم:
public BitDelegateCommand<Product> ShowProductDetailsCommand { get; set; }public IUserDialogs UserDialogs { get; set; } async Task ShowProductDetails(Product product) { string productDetail = $"Product: {product.Name}'s more info: ..."; // get more info from server. await UserDialogs.AlertAsync(productDetail, "Product Detail"); }
کامند ShowProductDetailCommand یک پارامتر را از جنس Product میگیرد و آن Product ای است که روی دکمه آن کلیک شدهاست. با Clone کردن آخرین نسخه XamApp و درخواست نمایش صفحهی Products در App.xaml.cs به صورت زیر و اجرای برنامه، میتوانید درک بهتری از عملکرد آن داشته باشید:
await NavigationService.NavigateAsync("/Nav/Products", animated: false);
سپس در View مربوطه داریم:
...<Button Command="{Binding ShowProductDetailsCommand}" CommandParameter="{Binding .}" Text="Detail..." /> </FlexLayout> </DataTemplate>
CommandParameter اگر برابر با Binding Id میبود، به Command در سمت View Model، بجای کل Product، فقط Id آن ارسال میشد. ولی Show Product Detail Command منتظر یک Product کامل است، نه فقط Id آن. با نوشتن
CommandParameter="{Binding .}"
کل Product با کلیک روی دکمه به Command ارسال میشود.
اکنون اگر پروژه را Build کنید، خطایی را از x:DataType خواهید گرفت که منطقی است. اگر Binding Name و Binding Price دو Property با نامهای Name و Price را از کلاس Product جستجو میکنند، پس قاعدتا ShowProductDetailCommand نیز در همان کلاس مدل، یعنی Product جستجو میشود! ولی میدانیم که این Command در View Model ما یعنی ProductsViewModel است. برای حل این مشکل، به جای Binding از bit:ViewModelBinding استفاده میکنیم:
Command="{bit:ViewModelBinding ShowProductDetailsCommand}"
در این صورت، بجای جستجو کردن ShowProductDetailCommand در کلاس Product، این را در ProductsViewModel جستجو میکند که منجر به خروجی درست میشود.
این List View دارای امکاناتی چون Infinite loading، Pull to refresh و Grouping-Sorting-Filtering و ... است که میتوانید از روی مستندات خوب Syncfusion، آنها را راه اندازی کنید و اگر به مشکلی برخوردید نیز اینجا بپرسید. همچنین نگاهی به لیست 129 کنترل دیگر بیاندازید و ببینید که در برنامههای خود از کدام یک از آنها میتوانید استفاده کنید.