Download the code for this tutorial

 

Download this tutorial in PDF format

 

کش کردن داده ها :

 

در مقاله قبلی ما یاد گرفتیم که چگونه در لایه presentation بتوانیم اطلاعات را کش کنیم. در این مقاله ما یاد خواهیم گرفت که چگونه می توان یک لایه برای کش کردن داده ها به برنامه هایمان اضافه نماییم.

 

مقدمه :

 

همانطور که در مقاله گذشته نشان داده شد، کش کردن داده ها بوسیله ObjectDataSource تنها با تنظیم کردن مجموعه ای از property ها قابل پیاده سازی است.  متاسفانه این کنترل کش کردن داده ها را در لایه presentation انجام می دهد ، و طبق صحبت هایی که در مقاله اول از این سری مقالات صحبت شد، در توسعه نرم افزار و انعطلف پذیری آن خوب عمل نمی کند و بهتر است که لایه جدیدی برای این منظور در نظر گرفته شود.

برای مثال لایه Business Logic ، قوانین تجاری را از صفحات ASP.NET  جدا می کند ، در حالی که لایه Data Access جزئیات دسترسی به داده ها را جدا می کند. این جداسازی ها بسیارخوب هستند زیرا باعث افزایش خوانایی ، نگهداری ، انعطاف پذیری برنامه ها در مقابل تغییرات می شود. سیاست جدا سازی لایه presentation از caching نیز به خاطر همین دلایل است.

در این مقاله ما به معماری قبلیمان لایه جدیدی بنام Caching Layer  ( یا به طور خلاصه CL ( که تمامی عملیات کش کردن اطلاعات را مدیریت می کند ، اضافه خواهیم کرد. این لایه شامل کلاسی بنام ProductsCL که شرایط مورد نیاز برای دسترسی به اطلاعات product را بوسیله متدهایی همچونGetProduct(), GetProductsByCategoryID(categoryID) فراهم می کند . این متدها در ابتدا تلاش می کنند که اطلاعات را از cache استخراج کنند . اگر cache  خالی باشد، متدهای مناسبی را از لایه ProductBLL فراخوانی خواهند کرد. در نهایت متدهای کلاس ProductBLL دادهای استخراج شده را قبل از برگرداندن ، کش خواهند کزد.

همانطور که شکل 1 نشان می دهد ، CL (Cache Layer) مابین لایه های Presentation و Business Logic قرار می گیرد.


 

 

گام 1 : تولید کلاس های Caching Layer

 

در این مقاله ما یک لایه کش بسیار ساده که تنها شامل کلاس ProductBL است را تولید خواهیم کرد. ایجاد یک لایه کش کامل برای تمام پروژه ممکن است شامل ایجاد کلاس های CategoriesCL, EmployeedCL و SuppliersCL و همچنین تولید متدی در کلاس های این لایه برای دسترسی به داده باشد . همچون لایه های BLL و DAL ، این لایه نیز بهتر است که به عنوان یک Class Library Project جدا باشد. ما دراین جا آن را در پوشه App_Code بصورت یک کلاس پیاده سازی خواهیم کرد.

برای اینکه جدا بودن کلاس های CL را از دیگر کلاس های DAL و BLL  مشخص تر باشد ، اجازه دهید تا یک زیر پوشه بنام CL  در App_Code بصورت زیر ایجاد کنیم و در نهایت در آن کلاسی بنام ProductsCL.cs قرار می دهیم.

 

 

 

این کلاس باید شامل مجوعه متدهایی مشابه در کلاس Business Logic Layer یعنی ProductBLL باشد. ما متدهای GetProducts() و GetProductsByCategoryID(categoryID) را در گام 3 و یک متد UpdateProduct در گام 4 ایجاد خواهیم کرد. شما می توانید دیگر متدهای ProductsCL و کلاس های CategoriesCL, EmployeesCL و SuppliersCL را خودتان ایجاد نمایید.

 

 

گام دوم : خواندن و نوشتن در داخل کش

 

داده کش شده می تواند بصورت برنامه نویسی از داخل کدهای یک صفحه و یا از دیگر کلاس های یک پروژه ASP.NET  مورد دسترسی قرار گیرد. برای خواندن یا نوشتن از داده های کش شده از داخل کد صفحه می توان از الگوی زیر استفاده کرد :

 

 

 

متد insert کلاس Cache چند حالت overload شده دارد. دو حالت Cache[“Key”]=Value و Cache.Insert(Key, Value) برای اضافه کردن یک آیتم به کش با استفاده از یک کلید تعیین شده و بدون تعیین زمان expire بکار می روند. معمولا ، ما در مورد کش ها تمایل داریم که یک زمانی را برای expire  شدن ( براساس dependency و یا براساس زمان) در نظر بگیریم که دو حالت بعدی متد Insert این شرایط را فراهم می کنند.

متدهایی که در لایه کش بکار می روند ابتدا چک می کنند که آیا داده درخواست شده در داخل کش وجود دارد یا خیر. اگر داده درخواست شده در کش موجود نباشد، متد مناسبی را از لایه BLL فراخوانی میکند. سپس مقدار بدست آمده کش می شود و در نهایت آن را به خروجی ارسال می کند. نمودار sequence این فرایند بشرح زیر می باشد:

 

 

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

 

نمودار sequence نشان داده شده در بالا در کلاس های CL با استفاده از الگوی زیر کامل می شود :

 

 

 

در این جا، Type ، نوع داده ذخیره شده در کش است . اگر یک آیتم با کلید مشخصی کش نشده باشد، مقدار آن برابر null خواهد بود و مقدار آن باید از متد مناسبی از لایه BLL استخراج و به کش اضافه شود. حتما مطمئن باشید که که از الگوی بالا در زمان استفاده از کش ها استفاده کنید.

 

نکته : کش داده thread-safe است ، بنابراین شما نیازی به همزمان سازی (Synchronize) دسترسی داده برای خواندن و نوشتن ندارید . در هر حال ، اگر شما نیاز دارید که چند عملیات را بصورت همزمان بر روی داده ها در کش ، بصورت اتومیک انجام دهید ، باید از یک سری از روش ها همچون پیاده سازی قفل ها استفاده نمایید . برای اطلاعات بیشتر به Synchronizing Access to the ASP.NET Cache مراجعه نمایید.

 

یک آیتم را شما می توانید بصورت برنامه نویسی از کش با استفاده از متد Remove بصورت زیر حذف نمایید:

 

 

 

 

گام 3 : بازیابی اطلاعات محصولات از کلاس ProductsCL

 

در این مقاله ما دو متد برای استخراج داده های بدست آمده از کلاس ProductCL بنام های:  GetProducts() و GetProductsByCategoryID(categoryID) پیاده سازی خواهیم کرد. هدف از متد GetProduct() بازیابی تمامی محصولات است ، در حالیکه GetProductByCategoryID(categoryID) تمامی محصولات مربوط به یک گروه خاص را بر می گرداند.

 

کدهای زیر قسمتی از متدهای داخل کلاس ProductCL را نشان می دهد:




 

در ابتدا بهتر است که به صفت های DataObject و DataObjectMethodAttribute که به کلاس ها و متدها اضافه شده است توجه کنید . این صفت ها اطلاعاتی را برای ObjectDataSource فراهم می کند که نشان دهنده این مطلب است که باید چه کلاس ها و متدهایی در ویزارد های مربوط به تنظیم DataSource ظاهر شود. از آنجایی که این می خواهیم در آینده از متدها و کلاس های CL در آینده در داخل objectDataSource های لایه presentation استفاده شود ، از این صفت ها استفاده کرده ایم.

در متدهای GetProducts() و GetProductsByCategoryID(categoryID) داده ای که از متد GetCacheItem(key) بدست می آید در یک متغیر محلی ذخیره می شود. متد GetCacheItem(key) ، که به زودی از آن استفاده خواهیم کرد ، یک آیتم مشخص براساس کلید پاس داده شده به آن را بر می گرداند. اگر داده ای براساس کلید مشخص شده پیدا نشود ، آن را از متد مناسبی از کلاس ProductBLL  بازیابی و با استفاده از متد AddCacheItem(key, Value) داده بدست آمده را به کش اضافه می کند .

 

 

 

GetCacheItem(key) از پارامتر فراهم شده برایش مستقیما استفاده نمی کند ، اما بجای آن از متد GetCacheKey(key) ، که کلیدی با پیشوند ProductsCache- را فراهم می کند ، استفاده می کند.

 

از کد مربوط به یک صفحه ASP.NET داده کش شده را می توان با استفاده از ویژگی Cache مربوط به صفحه بصورت Cache[“key”] = value ، همانطور که در گام دوم توضیح داده شده است می توان استفاده کزد. از کلاسی داخل معماری ما ، داده کش شده را نیز با استفاده از HttpRuntime.Cache یا HttpContext.Current.Cache  مورد دسترسی قرار داد.

 

نکته: اگر شما با استفاده از Class Library Projects برنامه تان را پیاده سازی کرده باشید ، برای استفاده از کلاس های HttpRuntime و HttpContext نیاز دارید که System.Web را به پروژه تان اضافه کنید.

 

اگر آیتم مورد نظر در کش پیدا نشود ، متدهای کلاس ProductsCL داده را از لایه BLL بدست می آورد و آنرا با استفاده از متد AddCacheItem(key, value) به کش اضافه می کند. برای اضافه کردن value به کش ، می توان از کد زیر استفاده کرد ، که پس از 60 ثانیه از بین می رود :

 

 

 

DateTime.Now.AddSeconds(CacheDuration) زمان از بین رفتن کش را تعیین می کند که برابر 60 ثانیه است و System.Web.Caching.Cache.NoSlidingExpiration مشخص می کند که هیچ sliding expiration وجود ندارد . زمانیکه از این حالت متد Insert برای اضافه کردن کشی استفاده می کنید ، تنها می توانید از یکی از این دو (absolute و sliding expiry) حالت استفاده کنید. اگر شما سعی کنید که از هر دو حالت absolute time و time span استفاده کنید ، متد Insert  یک خطای زمان اجرا (Exception) ArgumentException  ایجاد می کند .

 

 

گام 4 : غیر معتبر کردن کش در زمان ویرایش داده ها

 

در بین متدهای بازیابی داده ، در لایه کش نیاز است که متدهای مشابهی را همچون لایه BLL برای اضافه و حذف داده فراهم کنید . متدهای ویرایش داده در لایه CL نیازی به ویرایش داده کش شده ندارد ، اما بجای آن متدهای مناسبی را برای ویرایش از لایه BLL  فراخوانی می کند و سپس کش را نامعتبر می کند .

متد  UpdateProduct نشان داده شده در زیر نحوه پیاده سازی متدهای ویرایش داده را در لایه CL را نشان می دهد :

 

 

 

در این مثال متد مناسب آن از لایه BLL فراخوانی می شود، اما قبل از return کردن نتیجه باید کش را غیر معتبر کرد . متاسفانه ، غیر معتبر کردن داده کار راحتی نیست ، زیرا متدهای GetProducts() و GetProductsByCategoryID(categoryID) از کلاس ProductsCL هر کدام آیتم هایی با کلید های مختلف را اضافه می کنند و متد GetProductsByCategoryID(categoryID)  به ازای هر categoryID یک کش مختلف اضافه می کند .

در زمان غیر معتبر کردن کش ، ما نیاز داریم تمامی آیتم هایی که ممکن است بوسیله کلاس ProductsCL اضافه شده است را باید حذف کنیم. برای تکمیل این کار نیاز است که این آیتم ها را با یک dependency در زمان اضافه کردن کردن کش بوسیله متد AddCacheItem(key, value) مرتبط سازیم. بطور کلی ، یک cache dependency می تواند آیتم دیگری در کش باشد یا یک فایل در سیستم فایل و یا داده ای از یک Microsoft SQL Server database . زمانی که آن وابستگی تغییر کند و یا از کش برداشته شود ، آیتم های کش شده متناسب با آن بصورت خودکار از کش حذف می شوند. در اینجا ، ما می خواهیم که آیتم اضافه دیگری را به کش اضافه کنیم که به عنوان یک cache dependency در تمام آیتم های اضافه شده بوسیله کلاس ProductsCL عمل می کند. به این ترتیب، تمامی این آیتم ها را می توان با حذف cache dependency ، از بین برد.

 

اجازه دهید که متد AddCacheItem(key, value) را با تغییرات گفته شده بصورت زیر بروز کنیم :

 

 

MasterCacheKeyArray یک آرایه رشته ای است که یک مقدار رشته ProductsCache را نگه می دارد. در ابتدا ، یک آیتم کش به کش ها اضافه می شود و تاریخ و زمان اخیر سیستم به آن انتساب داده می شود . اگر این آیتم وجود داشته باشد ، بروز رسانی می شود. سپس، یک cache dependency  ایجاد می شود. سازنده کلاس CacheDependency چند حالت overloaddependencies مشخص می کند. که در اینجا ما نمی خواهیم از این حالت استفاده کنیم ، بنابراین مقدار آن را برابر null قرار داده ایم . پارامتر دوم مجموعه ای از شده دارد، متدی که در اینجا استفاده می شود احتیاج به دو آرایه رشته ای به عنوان پارامتر ورودی دارد . اولین آن مجموعه از فایل ها را به عنوان

 کلیدهای کش را برای استفاده به عنوان dependencies مشخص می کند. در اینجا تنها یک مورد را مشخص می کنیم که همان MasterCacheKeyArray است. در نهایت CacheDependency  به متد Insert پاس داده می شود.

با استفاده  از تغییرات اعمال شده بر روی متد AddCacheItem(key, value)، نامعتبر کردن کش به آسانی حذف dependency خواهد بود .

 

 

گام 5 : فراخوانی متدهای لایه کش از لایه Presentation

برای نشان دادن کار با لایه کش ، تغییراتی را که در کلاس ProductsCL داده اید را ذخیره کنید و سپس صفحه FromTheArchitecture.aspx را از پوشه Caching باز کنید و یک GridView  به آن اضافه کنید. سپس یک ObjectDataSource جدید برای آن ایجاد نمایید. در اولین مرحله از ویزارد تنظیم این کنترل، شما باید کلاس ProductsCL را به صورت زیر انتخاب نمایید .

 

 

پس از انتخاب این کلاس ، دکمه Next را کلیک کنید . سپس همانطور که در زیر نشان داده شده است باید متدهای مناسبی را برای Select  و Update انتخاب نمایید و در نهایت دکمه Finish را کلیک نمایید.

 

 

 

نکته : لایه کشی که در برنامه همراه این مقاله آمده است کامل نیست. به عبارتی تنها شامل یک کلاس ProductsCL، که تنها شامل چند متد است و تنها یکی از صفحات ASP.NET از این برنامه از لایه کش استفاده می کند (~/Caching/FromTheArchitecture.aspx) و مابقی بصورت مستقیم از لایه BLL استفاده می کنند. اگر شما می خواهید که از لایه CL در پرورتان استفاده نماییید، باید برای تمامی فراخوانی ها از لایه Presentation در داخل لایه CL پاسخ داده شوند.

 

خلاصه :

در حالیکه کش را می توان در لایه Presentation بوسیله کنترل هایی همچون SqlDataSource و ObjectDataSource اعمال کرد ، بهتر است که تمام عملیات مربوط به کش را بصورت لایه ای کاملا جدا در معماریمان قرار دهیم. در این مقاله ما یک لایه کش در بین Presentation Layer و Business Logic Layer ایجاد کردیم.

 

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

 

در مقاله بعدی ما از این روش برای کش کردن استفاده خواهیم کرد و همچنین خواهیم دید که چگونه می توان مقادیر static را در زمان راه اندازی برنامه در کش ذخیره کرد.

 

شاد باشید !

 

پاییز 86

این آدرس ایمیل توسط spambots حفاظت می شود. برای دیدن شما نیاز به جاوا اسکریپت دارید