‏نمایش پست‌ها با برچسب C#. نمایش همه پست‌ها
‏نمایش پست‌ها با برچسب C#. نمایش همه پست‌ها

انتقال اطلاعات در ASP.Net

یکی از سوالات معمول درباره ASP.Net نحوه ارنتقال اطلاعات بین صفحات است. در ابتدا شاید این کار یکی از وظایف عادی و روزمره هر برنامه نویسی به نظر برسد، اما در ادامه خواهید دید که این بحث یکی از موارد مهم و عمیق در ASP.Net میباشد. راه های مختلفی برای این کار وجود دارد، و انتخاب بهترین راه حل در زمان مناسب نیاز به شناخت و تجربه زیادی دارد.
به طور کل انتقال و نگه داری اصلاعات در دو سطح مختلف انجام میشود.
1- سطح سرور
2- سطح کلاینت
از دسته اول میتوان به Application State، cache، Session State و context را نام برد و از گروه دوم Query String، View Stateو Cookie پرکاربرد ترین هستند.
در قسمت های بعدی شما با راه های مختلف و زمان کاربرد هر یک از گزینه های بالا آشنا خواهید شد.
Application State:
HttpApplicationState یکی از اشیایی است که از زمان asp کلاسیک امکان استفاده از آن را، برای کارهایی نظیر ذخیره سازی متغیرهای سراسری داریم. برای مثال اگر شما یک DataSet داشته باشید که در قسمت های مختلف برنامه نیاز به استفاده از آن پیدا کنید، به سادگی میتوانید این شی را در Application State ذخیره کنید و در صورت نیاز این شی را از آن قسمت بازیابی کنید.
بازیابی اطلاعات از Application State کار ساده ای بوده و بیش از یک خط کد نیاز ندارد. نمونه زیر نحوه این کار را به شما نمایش میدهد.

VB.NET
Dim ds As DataSet = CType(Application("MyDataSet"), DataSet)
 //C#
DataSet Source = (DataSet)(Application["MyDataSet"]);

تغییراتی که در اشیایی که در Application ذخیره شده اند میدهیم، به صورت خودکار مجددا در Application ذخیره نخواهد شد. به همین دلیل با هربار تغییر در شی خوانده شده از Application باید مراحل ذخیره سازی را مجددا تکرار کنیم تا تغییرات اعمال گردد.
همانطور که ممکن است از نام این شی حدس زده باشید. درسترسی به شی Application تنها در حوزه برنامه جاری امکان پذیر است. برای مثال اگر شما دو وب ساید مختلف روی سرور خود داشته باشید برنامه 2 امکان دستری به شی Application در برنامه 1 را نخواهد داشت.
Cache Object:
درباره Application State و کارایی آن شکی نیست. اما در این قسمت شما با شی دیگر آشنا خواهید شد که کارایی آن از بسیاری جهات شبیه به Application State است. این شی HttpCache نام دارد.
مانند HttpApplicationState شی HttpCache نیز محل مناسبی جهت ذخیره سازی اطلاعات عمومی و نسبتا پایدار برنامه میباشد.
با کمی توجه به نحوه ذخیره سازی و بازیابی اطلاعات در HttpCache متوجه خواهیم شد که این کار بسیار شبیه به شی application است. با این تفاوت که به علت اینکه مدیریت دسترسی همزمان در داخل این شی پیاده سازی شده است، دیگر نیازی به قفل کردن و باز کردن قفل در کار کردن با این شی نیست.
'VB.NET
Cache("MyGlobalValue") = TextBox1.Text 'Store
Dim s As String = Cache("MyGlobalValue").ToString 'Retrieve
 //C#
Cache["MyGlobalValue"] = TextBox1.Text; //Store
string s = Cache["MyGlobalValue"].ToString(); //Retrieve

شی HttpCache علی رغم شباهت هایی که با شی application دارد قابلیت هایی به آن افزوده است که کارایی و مقیاس پذیری این شی را به طور قابل توجهی افزایش داده است.
این شی تکنیک های ذخیره سازی هوشمندی را پیاده سازی کرده است. برای مثال در صورتی که حافظه برنامه رو به کاهش بگذارد، این شی به صورت خودکار، اشیایی ذخیره شده در خود را که به ندرت نیاز به دسترسی به آنها میباشد، حذف خواهد کرد. خوشبختانه امکان تعیین حق تقدم برای اشیای ذخیره شده در Cache به صورت دلخواه وجود دارد. به همین خاطر میتوانیم تعیین کنیم که اشیایی که برای ما از اهمیت بیشتری برخوردار هستند دیرتر از Cache خارج شوند. به کمک CacheItemRemovedCallback هنگامی که آیتمی از شی Cache حذف میشود با خبر شوید. در شی Cache شما این امکان را دارید تا تعیین کنید اشیا چگونه و برای چه مدت زمانی در Cache ذخیره شوند. برای مثال شما میتوانید تعیین کنید که یک شی که در Cache ذخیره شده است بعد از 1 ساعت منقضی شود و از Cache حذف گردد.
در مثال بعدی مشاهده خواهید کرد که چگونه یک شی در Cache ذخیره میشود. با این تفاوت که در این مثال ما زمانی 20 دقیقه ای برای Cache در نظر میگیریم و بعد از این مدت زمان شی ما از Cache حذف خواهد شد.


'VB.NET
Cache.Insert("MyGlobalValue", TextBox1.Text, _
Nothing, System.Web.Caching.Cache.NoAbsoluteExpiration, _
 New TimeSpan(0, 20, 0))
//C#
Cache.Insert("MyGlobalValue", TextBox1.Text,
null, System.Web.Caching.Cache.NoAbsoluteExpiration,
new TimeSpan(0, 20, 0));

به جز زمان، Cache میتواند به موارد دیگری نیز حساس باشد و با تغییر آن موارد، شی ذخیره شده در Cache منقضی شود. مثلا ممکن است داده های ذخیره شده از فایلی خوانده شده باشد. این امکان وجود دارد که Cache به آن فایل حساس باشد و با تغییر آن فایل Cache نیز منقضی شده و اصلاعات آن حذف شود. Cache میتواند حتی به یک Cache دیگر وابسته باشد و با تغییر Cache والد، Cache فرزند منقضی شود. شی CacheDependency کلید انجام موارد بالا است. در ضمن کلاس SqlCacheDependency نیز وجود دارد که به کمک آن میتوانیم یک سری اطلاعات ذخیره شده در cache را هنگامی که اطلاعات خاصی در بانک داده ما تغییر کرد، حذف کنیم.
مانند شی application حوزه دسترسی به cache نیز برنامه جاری میباشد.
Session State :
همانطور که مشاهده کردید، دو گزینه قبل محل مناسبی برای ذخیره سازی اصلاعات کلی و عمومی بودند، در مقابل Session محلی است برای نگه داری اصلاعات مخصوص یک کاربر. نحوه استفاده از این گزینه نیز بسیار ساده و آسان است.
'VB.NET
Session("UserName") = TextBox1.Text 'Store
Dim s As String = Session("UserName").ToString 'Retrieve
//C#
Session["UserName"] = TextBox1.Text; //Store
string s = Session["UserName"].ToString();//Retrieve

دسترسی به شی ذخیره شده در session تنها در برنامه جاری و تنها برای کاربر جاری میباشد. به گفته دیگر اگر دو کاربر وارد سایت شما شوند، و کد بالا در سایت شما وجود داشته باشد، نام کاربری هر یک از آنها از textbox خوانده شده و در شی Session ذخیره میشود. نام کاربری آنها کاملا جدا ذخیره میشود و آنها هرگز نام کاربری یکدیگر را مشاهده نخواهند کرد.
همانطور که مشاهده میکنید استفاده از session بسیار ساده است. اما در استفاده از از شی بسیار دقت کنید. زیرا این شی نیز مانند موارد قبلی از حافظه سرور جهت ذخیره سازی استفاده میکند و در صورت استفاده بیش از حد از این شی ممکن است با مشکل حافظه مواجه شوید. با این تفاوت که به خاطر وابستگی این شی به کاربران، سرعت کم شدن حافظه به وسیله این شی بسیار بیشتر از گزینه های قبلی است. فرض کنید در هرکدام از گزینه ها 10 متغیر را ذخیره کنید و سایت شما 100 بازدید کننده داشته باشد. برای application و cache در مجموع 20 متغیر ذخیره خواهد شد. اما برای session چون به کاربران وابستگی دارد 100 * 10 = 1000 متغیر ذخیره خواهد شد. خوشبختانه در Asp.net این امکان فراهم شده است تا تعیین کنیم Session در کجا ذخیره گردد. به طور پیش فرض روی حافظه سرور جاری میباشد. اما با انجام تنظیماتی در web.config میتوانیم تعیین کنیم که در Sql server یا در سرور دیگری که مخصوص مدیریت session ها است، این کار انجام شود.
Context:
یکی از راه هایی که به ندرت برای انتقال اطلاعات بین صفحات استفاده میشود، contextاست. به همراه هر صفحه که در asp.net درایم یک نمونه از شی context نیز وجود خواهد داشت. به خاطر اینکه شی صفحه مدت زمان خیلی کوتاهی در سرور ایجاد میشود و بعد از ارسال آن برای کاربر، شی صفحه از حافظه حذف میگردد، اشیایی که در شی Context ذخیره میگردد، مدت زمان کوتاهی عمر خواهند کرد. در بسیاری موارد این شی محل مناسبی برای ذخیره سازی اصلاعات میباشد به خاطر اینکه اطلاعات به سرعت و به طور خودکار از حافظه حذف میگرددند.
همانطور که این شی در طول حیات یک صفحه در دسترس است، این شی هنگام انتقال از صفحه ای به صفحه دیگر نیز در دسترس خواهد بود. در نمونه کد زیر داده در شی context در صفحه اول ذخیره میشود و بعد از انتقال به صفحه دوم به این داده ها دسترسی پیدا میکنیم.

'VB.NET
Context.Items("UserName") = TextBox1.Text 'Page1
Server.Transfer("Page2.aspx") 'Page1
Dim s As String = Context.Items("UserName").ToString 'Page2
//C#
Context.Items["UserName"] = TextBox1.Text; //Page1
Server.Transfer("Page2.aspx"); //Page1
string s = Context.Items["UserName"].ToString(); //Page2
به یاد داشته باشید که برای انتقال بین صفحات از Server.Transfer باید استفاده کنید. به خاطر اینکه اگر از Response.Redirect استفاده کنید، به واسطه رفت و برگشتی که بین سرور و کلاینت ایجاد میشود، شی contextاست مربوط به صفحه اول از بین خواهد رفت.
غیر از موارد بالا context در جاهای دیگری نیز میتواند کاربرد داشته باشد. برای مثال اگر شما در صفحه خود شی خاصی را استفاده کنید، در آن شی امکان استفاده از application یا session را ندارید. در این موارد به راحتی مورد دلخواه خود را از طریق context به شی دلخواه خود ارسال میکنید.
تا اینجا درباره نحوه انتقال اطلاعات در سمت سرور، و نقاط قوت و ضعف هر روش بحث کردیم. از این پس شیوه انتقال اطلاعات را در سمت کلاینت مورد بررسی قرار خواهیم داد.
ViewState
این شی برای نگه داری و انتقال اطلاعات در طی postbackهای مختلف در یک صفحه کاربرد دارد. در واقع شما نمیتوانید از این امکان برای انتقال اطلاعات از صفحه ای به صفحه دیگر استفاده کنید و صرفا جهت نگه داری اصلاعات در صفحه جاری کاربرد دارد.
نحوه کار با این امکان بسیار ساده است، با کمی دقت متوجه میشویم نحوه استفاده از این امکان بسیار شبیه به Session است.
'VB.NET
ViewState("PageValue") = TextBox1.Text 'Store
Dim s As String = ViewState("PageValue").ToString 'Retrieve
//C#
ViewState["PageValue"] = TextBox1.Text; //Store
string s = ViewState["PageValue"].ToString(); //Retrieve

در این روش به جای اینکه اطلاعات در سمت سرور و در حافظه سرور نگه داری شوند، اطلاعات کد گذاری شده و همراه html به سمت کاربر ارسال میگردد. در صورتی که بعد از بارگذاری صفحه ایتم view source را انتخاب کنید، مشاهده خواهید کرد که تگ زیر به html اضافه شده است که وظیفه آن نگه داری ViewState است.

<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE"
value="/wEPDwUKMTkwNjc4NTIwMWRkv1e5TcWOq4qnwyDuryos=" /> 


بعد از اینکه یک request به سمت سرور ارسال شد، سرور این مقدار به هم ریخته را خوانده مجددا از حالت کدگذاری شده خارج میکند و از مقادیر ذخیره شده در آن استفاده میکند.
از آنجا که این اصلاعات تنها کد گذاری شده اند، قابلیت دیکد کردن آن برای افرادی که قصد این کار را داشته باشند وجود دارد. پس در استفاده از این امکان باید دقت کنیم که، اطلاعات مهمی را در این حالت ذخیره سازی نمکنیم.
نکته قابل توجه دیگر اینکه، به دلیل انتقال این اصلاعات بین کلاینت و سرور، این روش از پهنای باند استفاده میکند، به همین دلیل باید دقت کافی داشته باشیم که داده های زیادی رد این حالت ارسال نشود.
QueryString
ارسال اطلاعات به وسیله query string یکی از روش های پر کاربرد و قدیمی در ارسال اطلاعات است. در این حالت مقداری که نیاز به ارسال آن داریم بعد از علامت سوال پشت سر URL قرار میگیرد.
استفاده از این اکان نیز بسیار ساده است. تنها کافی است، مقدار مورد نظر خود را بعد از URL اضافه کنید.
'VB.NET
Dim s as string = Server.UrlEncode(TextBox1.Text) 'Page1
Response.Redirect("Page2.aspx?UserName=" & s) 'Page1
Dim s2 As String = Request.QueryString("UserName") 'Page2

//C#
string s = Server.UrlEncode(TextBox1.Text); //Page1
Response.Redirect("Page2.aspx?UserName=" + s); //Page1
string s2 = Request.QueryString["UserName"]; //Page2

به خاطر نحوه نمایش این اطلاعات در Address bar امنیت انتقال اطلاعات در این روش بسیار پایین است و اگر در استفاده از این امکان نکات امنیتی را در نظر نگیریم، به سادگی در این روش مورد حمله قرار خواهیم گرفت.
در ضمن به خاطر ساختار متنی این روش، تنها اطلاعات ساده را به کمک این روش میتوانیم انقال دهیم.
Cookies:
کوکی ها، فایل های متنی کوچکی هستند (4096 بایت) که از سمت سرور ارسال میگردند و در کلاینت ذخیره میشوند. در هر بار درخواستی که به سرور ارسال میشود، تمام کوکی های مرتبط با درخواست به طور خودکار به سمت سرور ارسال میشوند و مجددا به سمت کلاینت باز میگردند.
نحوه استفاده از کوکی ها به شکل زیر میباشد:
'VB.NET
Response.Cookies("myval").Value = TextBox1.Text 'Store
Response.Cookies("myval").Value 'Retrieve
      
//C#
Response.Cookies["myval"].Value = TextBox1.Text; //Store
Response.Cookies["myval"].Value; //Retrieve

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

پ ن: این مطلب رو چند وقت پیش نوشته بودم، یکی از دوستان سوالی پرسید، گفتم شاید بد نباشه مطلب رو دوباره اینجا منتشر کنم.
» ادامه مطلب

Entity Framework و برنامه نویسی چند لایه

در صورتی که از علاقه مندان ORM ها و بخصوص Entity framework باشید، مطمئنا برنامه نویسی چند لایه یکی از دغدغه های ذهنی شما است، در این پست و چند پست آتی قصد داریم با هم به بررسی و پیاده سازی یک برنامه چند لایه که در آن از Entity Framework استفاده شده بپردازیم.
از امکاناتی که در نسخه 4 به Entity Framework اضافه شد، POCO بود. به کمک این امکان جدید، پیاده سازی برنامه های چند لایه بسیار ساده تر از نسخه پیشین این ORM شده است. در قسمت اول با هم این امکان جدید را بررسی میکنیم و در قسمت های آتی به نحوه پیاده سازی برنامه چندلایه میپردازیم.
قدم اول ایجاد پایگاه داده ای است که قصد کار کردن با آن را داریم. برای این کار یک دیتابیس با 2 جدول افراد و آدرس ها را ایجاد میکنیم.
CREATE TABLE Person
    (
      PersonId INT PRIMARY KEY
                   IDENTITY(1, 1) ,
      FirstName NVARCHAR(50) NOT NULL ,
      LastName NVARCHAR(50) NOT NULL,
    )
CREATE TABLE [Address]
    (
      AddressId INT PRIMARY KEY
                    IDENTITY(1, 1) ,
      City NVARCHAR(50) ,
      Street1 NVARCHAR(50) ,
      Street2 NVARCHAR(50) ,
      PostalCode NVARCHAR(50) ,
      PersonId INT NOT NULL
                   REFERENCES Person ( PersonId )
    )
بعد از ایجاد دیتابیس نوبت به ایجاد پروژه میرسد.
ابتدا یک سلوشن جدید از نوع Console application ایجاد کنید.
در مرحله بعد گزینه Add->New Item->ADO.NET Entity Data Model را انتخاب کنید و مراحل ایجاد Model را طی کنید. بعد از طی کردن مراحل باید مدل به شکل زیر باشد.
بر روی صفحه مدل راست کلیک کنید و از مدل Properties بگیرید، و مقدار خاصیت Code generation strategy را برابر با None قرار دهید.

سپس دو کلاس با نام های Address و Person ایجاد کنید و تمامی خاصیت هایی که در دو کلاسی که در مدل آمده به آن اضافه کنید. نام های خاصیت ها و جنس آنها باید با نام و جنس خاصیت های موجود در مدل یکسان باشد. برای Navigation Properties هم باید خاصیت ها را تعریف کنید. مانند دو کلاس پایین:

using  System;
using  System.Collections.Generic;
using  System.Linq;
using  System.Text;
namespace  YourNamespace
{
public  class  Person 
{
public  int  PersonId { get ; set ; }
public  string  FirstName { get ; set ; }
public  string  LastName { get ; set ; }
public  ICollection <Address> Addresses { get ; set ; }
}
}


using  System;
using  System.Collections.Generic;
using  System.Linq;
using  System.Text;
namespace  Chapter13SimplePOCO
{
public  class  Address 
{
public  int  AddressId { get ; set ; }
public  string  Street1 { get ; set ; }
public  string  Street2 { get ; set ; }
public  string  City { get ; set ; }
public  string  PostalCode { get ; set ; }
        #region  FKs and Reference properties/value objects
public  int  PersonId { get ; set ; }
public  Person Person { get ; set ; }
        #endregion 
}
}
تا اینجای کار ما کلاس های خود را ایجاد کرده ایم ولی این کلاس ها هیچ اطلاعی از چگونگی ذخیره شدن و خوانده شدن از دیتابیس در اختیار ندارند. برای این منظور کلاسی با نام Entities میسازیم و از ObjectContext ارث برسی میکنیم. و خاصیت ها و سازنده را مانند کد زیر به این کلاس اضافه میکنیم.

using  System;
using  System.Collections.Generic;
using  System.Linq;
using  System.Text;
using  System.Data.Objects;
namespace  TestEntityPoco
{
public  class  Entities  : ObjectContext 
{
private  ObjectSet <Person> _Pesons;
private  ObjectSet <Address > _addresses;
public  Entities()
: base ("name=CnnName" , "EntitiName" )
{
_Pesons = CreateObjectSet<Contact>();
_addresses = CreateObjectSet<Address >();
}
public  ObjectSet <Contact> Person
{
get 
{
return  _Pesons;
}
}
public  ObjectSet <Address > Addresses
{
get 
{
return  _addresses;
}
}
}
}
حال تمامی کاری که ما باید انجام میدادیم، به پایان رسیده است. کافی است از این کلاس ها استفاده کنیم.
static  void  Main(string [] args)
{
using  (Entities context = new  Entities())
{
var query = from c in  context.Person.Include("Addresses" ) select c;
var contactList = query.ToList();
int  contactCount = contactList.Count;
Person firstContact = contactList.Where(c => c.Addresses.Any()).First();
int  addressCount = firstContact.Addresses.Count;
}
}
کار ما در اینجا به پایان رسید. برای اطلاعات بیشتر میتوانید به فصل 13 از کتاب Oreilly Programming Entity Framework مراجعه کنید.
در کل مطالعه این کتاب به همه علاقه مندان توصیه میشود.D:
» ادامه مطلب

معرفی بخش های فایل مدل در Entity Framework

در صورتی که تا کنون با Entity Framework کار کرده باشید، قطعا دیده اید که فایلی با پسوند edmx برای شما ایجاد میشود که تقریبا تمامی کارهای استفاده از دیتا در این فایل پوشش داده میشود. با این اوصاف شاید بد نباشد با هم نگاهی به داخل این فایل
بیاندازیم و از وقایع پشت پرده با خبر شویم.
برای این کار روی یک فایل edmx راست کلیک کنید و گزینه Open with و سپس XML (Text) Editor را انخاب نمایید تا این فایل را به حالت XML مشاهده نمایید. در صورتی که روی علامت های منها کنار صفحه کلیک کنید تا قسمت های مختلف جمع شوند، فایل شما به شکل زیر خواهد بود و از 4 قسمت اصلی تشکیل شده است.


CSDL: The Conceptual Schema

در این قسمت ما میتوانیم مدل منطقی را مشاهده نماییم. یعنی تعریفی از Entity ها که در حقیقت کلاس هایی هستند که ما در دات نت با آنها سر ور کار داریم در این قسمت وجود دارد.

این قسمت از فایل خود از بخش های مختلفی تشکیل شده است. قسمت Entity Container که در حقیقت نگه دارنده لیست اشیا موجود در برنامه است و نام و نوع کلاس ها ما است. Entity Container خود شامل یک سری از Entity set ها است و هر Entity Set یکی از کلاس های ما است.

SSDL: The Store Schema
در این قسمت هم مشخصات دیتابیس ما نگه داری میشود. لیستی از جداول و ویو های داخل دیتابیس را در این قسمت میتوانیم مشاهده کنیم. در این قسمت نیز Entity Set ها وجود دارند که هر کدام خاصیتی دارند که معلوم میکند که از چه جنسی هستند.
C-S Mapping:
این قسمت هم از نامش پیداست، کار مپ کردن را برای ما انجام میدهد.یعنی در این قسمت میتوانیم رابطه بین Entity setهای بخش csdl و ssdl را معلوم کنیم. میتوانیم معلوم کنیم هر ستون از هر جدول به چه پراپرتی از چه کلاسی متصل باشد.
EF Designet:
آخرین قسمت هم که دقیقا به ساختار دیاگرام ما در ویژوال استودیو بر میگردد. اینکه کدام کلاس در چه ابعادی رسم شود و در چه موقعیتی از صفحه قرار گیرد.
در کل کار کردن با این قسمت ها بسیار ساده است و به سادگی با بررسی این فایل میتوانید از جزئیات آن با خبر شوید.
» ادامه مطلب

الگوی Factory method-الگو های سازنده

یکی دیگر از الگو های ساختاری که به ما در ایجاد یک شی از یک کلاس کمک میکند الگوی Factory method است. با استفاده از این متد ما میتوانیم تعیین کنیم که یک شی از روی کدام یک از Subclassهایی که همگی یک اینترفیس را پیاده سازی کرده اند باید ایجاد شود. اطلاعات مورد نیاز برای شناخت کلاس مورد نظر ممکن است به عنوان پارمتر به متد پاس داده شوند و یا از وضعیت کنونی برنامه به دست آیند.
برای مثال یک ماشین نام سازی را در نظر بگیرید. این ماشین میتواند انواع مختلفی از نان را برای شما آماده سازد. مثلا نان بربری، سنگک و باگت. فقط کافی است که مخزن آرد و آب را برای ساخته شدن خمیر پر کنید(interface مشترک بین تمامی Subclassها) سپس از به کمک دکمه های موجود روی ماشین انتخاب میکنید که کدام نوع نان برای شما آماده شود(پارامتر های ورودی و وضعیت کنونی برنامه) و بعد ماشین تشخیص میدهد که چه نوع نانی برای شما آماده و طبخ شود(Factory method).
حالا به سراغ پیاده سازی این الگو میرویم. به مثال زیر دقت کنید.

 class Program
    {
        static void Main(string[] args)
        {
            IBread barbari = cookingMachine.Cook(EnumBread.Barbari);
            IBread sangak = cookingMachine.Cook(EnumBread.Sangak);
            Console.WriteLine(barbari.GetBread());
            Console.WriteLine(sangak.GetBread());
        }
        public enum EnumBread
        {
            Barbari = 1,
            Sangak = 2
        }

        public class cookingMachine
        {
            public static IBread Cook(EnumBread breadType)
            {
                switch (breadType)
                {
                    case EnumBread.Barbari:
                        return new Barbari();
                    case EnumBread.Sangak:
                        return new Sangak();
                }
            }
        }

        public interface IBread
        {
            string GetBread();
        }
    
        public class Barbari : IBread
        {
            public string GetBread()
            {
                return "Barbari";
            }
        }
      
        public class Sangak : IBread
        {
            public string GetBread()
            {
                return "Sangak";
            }
        }
    }

در برنامه اصلی تعیین میکنیم که چه نوع نانی را میل داریم، و بعد ماشین پخت پز، نان مورد نظر رو برای ما به کمک پارامتر ورودی طبخ میکنه. نوش جان. صبحانه من هم آماده شد، تا سرد نشده برم صبحانه بخورم.
همین دیگه! تموم شد.
» ادامه مطلب

الگوهای ساختاری - Bridge

در نوشته  قبلی به شرح مختصری از الگوهای طراحی نرم افزار پرداختیم و  به بررسی نقش الگو ها در توسعه پرداخیتیم. در این قسمت یک الگوی دیگر را با هم بررسی خواهیم کرد و این بار از دسته الگو های Structural.
 این درسته از الگوها زمانی برای ما کاربرد دارند که بخواهیم دسته ای از کلاس ها و یا اشیا را با یکدیگر ترکیب کنیم تا یک ساختار بزگتر  و پیچیده تر دست پیدا کنیم و به یک کارکرد جدید برسیم یا اینکه یکی از قابلیت های موجود را حذف کنیم. الگوهای موجود در این گروه عبارتند از
• Decorator
• Proxy
• Bridge
• Composite
• Flyweight
• Adapter
• Façade
بعضی مواردی که این الگوها به ما کمک میکنند عبارتند از:
•اضافه یا کم کردن عملکرد یک کلاس
• کنترل دسترسی به یک شی
•کاهش سربار استفاده از اشیا بسیار کوچک که با تعداد زیادی از آنها سر و کار داریم.
•ایجاد یک شی بزرگ در زمان درخواست.
حالا که از نقش این گروه با خبر شدیم به سراغ الگوی مورد نظر برای امروز میرویم.
الگوی Bridge:
به کمک این الگو میتوان تعریف کلاس را از پیاده سازی آن جدا کرد. یکی از کاربردهای این الگو هنگامی است که نیاز به تغییر ورژن داشته باشیم که در آن قسمتی از برنامه قدیمی تغییر کرده اما میخواهیم برنامه قدیمی بدون مشکل کار کند. و در واقع برنامه با توجه به نسخه خود از پیاده سازی قدیمی یا جدید استفاده میکند.
برای روشن تر شودن موضوع مثالی می آوریم. همه با دستگاه های برقی  و الکتریکی کم و بیش سر و کار داریم. از زمان های بسیار دور، برای استفاده از وسایل آنها را به کمک دکمه روشن/خاموش ابتدا روشن میکردیم و بعد از پایان کار آنها را خاموش میکردیم. اما در گذشته این کار به کمک کلید های الکترو مکانیکی انجام میشد و امروزه به کمک کلید های الکترونیکی. این تغییر تکنولوژی از الکترومکانیکی به الکترونیکی سرعت، امنیت و سبکی را برای ما به همراه داشت ولی برای استفاده از این امکانات ما نیاز به یادگیری دانش جدید نداشتیم و کماکان با همان دکمه روشن/خاموش با دستگاه کار میکنیم. و این یعنی که تعریف دکمه روشن/خاموش که ما میبینیم از پیاده سازی آن که ما نمیبینیم کاملا جدا شده است.
پیاده سازی:
یکی از راه های متداول برای جدا کردن تعریف کلاس از پیاده سازی آن استفاده از ارث بری است. اما همانطور که میدانید در ارث بری رابطه تنگاتنگی بین والد و فرزند وجود دارد و برای تغییر هر یک نیاز به تغییر دیگیری است. پس این راه حل مشکل ما نیست. ما باید راه حلی داشته باشیم که این دو کاملا از هم جدا شوند و کاربر دچار سردرگمی نشود.
به مثال زیر دقت کنید. اگر ما Parent را در اختیار کاربر قرار دهیم و بعد از مدتی بخواهیم قابلیتی به کلاسهای ارث بری شده اضافه کنیم، برنامه مقصد ما دیگر به درستی کار نخواهد کرد زیرا با تغییر  Parent قسمتی که کاربر با آن کار میکرد نیز تغییر میکند.
public interface Parent
    {
        string GetClassName();
    }

    public class Child1 : Parent
    {
        public string GetClassName()
        {
            return "Class1";
        }
    }
    public class Child2 : Parent
    {
        public string GetClassName()
        {
            return "Class1";
        }
    }
حال به مثال زیر دقت کنید که جداسازی را به کمک Bridge انجام میدهیم:

public class Abstraction
    {
        IBridge bridg;
        public Abstraction(IBridge implementation)
        {
            bridg = implementation;
        }
        public string GetName()
        {
            return bridg.GetClassName();
        }
    }
    public interface IBridge
    {
        string GetClassName();
    }
    public class Implementation1:IBridge
    {
        public string GetClassName()
        {
            return "Implementation1";
        }
    }
    public class Implementation2 : IBridge
    {
        public string GetClassName()
        {
            return "Implementation2";
        }
    }
در کد بالا مشاهده میکنید که قسمت Abstract که در دست کاربر است کاملا از قسمتی که نیاز به تغییر و تعیریف مجدد دارد جدا گشته است و هر تغییری که در قسمت Bridge بدهیم روی قسمت کاربر تاثیری نمیگذارد.
همین دیگه! تموم شد.
» ادامه مطلب

الگوی طراحی نرم افزار - Singleton

الگوی طراحی نرم افزار اصلاحا به راه حل های استاندارد  و قابل استفاده مجدد ،برای حل مشکلات عمومی توسعه نرم افزار اطلاق میگردد. یک الگو  راه حل نهایی حل شده نیست که به سرعت بتوانیم به سراغ پیاده سازی آن بریم. بلکه شرحی است از نحوه حل مشکل که باید آنرا تکمیل کرد و در زبان برنامه نویسی مورد نظر بومی سازی و پیاده سازی نمود. استفاده از الگو های طراحی نرم افزار سرعت توسعه برنامه را بسیار زیاد میکند و چون از یک راه حل استاندارد استفاده شده است قابلیت توسعه و نگه داری بهتری نیز دارد. الگوهای طراحی تا سال 1994 شهرت چندانی نداشتند. اما بعد از اینکه کتاب Design Patterns: Elements of Reusable Object-Oriented Software توسط آقایان  Erich Gamma، Richard Helm,
Ralph Johnsonو John Vlissidesانتشار یافت، شهرت و محبوبیت الگوهای طراحی به سرعت زیاد شد. در این کتاب 23 الگو در 3 دسته شرح داده شده بود. این گروه ها عبارتند از  الگوهای سازنده یا creational الگوهای ساختاری یا
structural و الگوهای عملکرد یا behavioral.
امروز میخواهیم کار خود را بایک الگوی بسیار ساده از  دسته  Creational شروع کنیم. الگوی ساده، زیبا و پر کاربرد Singleton.
در زمانی که نیاز دارید که از یک کلاس تنها یک شی ایجاد شود و مطمئن باشید که نمونه دیگری از این شی وجود ندارد، و تمام قسمت های مختلف برنامه شما تنها از این شی استفاده میکنند میتوانید به الگوی Singleton اعتماد کنید.
اما پیاده سازی این الگو در زبان


public sealed class Singleton
{
    private Singleton() { }
    static readonly Singleton instance = new Singleton();
    public static Singleton Instance
    {
        get { return instance; }
    }
}
در این کلاس، سازنده کلاس به صورت خصوصی علامت گذاری شده است. در نتیجه امکان ایجاد یک شی از کلاس به کمک New وجود ندارد. حالا که جلوی ایجاد شی را برای برنامه نویس بستیم، باید به طریقی امکان ایجاد یک شی را از این کلاس ایجاد کنیم.
برای این منظور یک خاصیت خصوصی و فقط خواندنی به صورت استاتیک به این کلاس اضافه میکنیم که از جنس همین کلاس است. خصوصی است برای اینکه امکان تغییر آن به وسیله برنامه نویس وجود نداشته باشد. فقط خواندنی است تا فقط یک بار بتوان به آن مقدار داد. و استاتیک است تا بین تمامی نمونه های ایجاد شده از این کلاس مشترک باشد.
حالا این کلاس را به کمک متد UniqueInstance در اختیار استفاده کننده ها میگذاریم.
در قسمت زیر راه پیاده سازی دیگری برای شما به نمایش گذاشته شده که تحلیل آن به عهده خود شما است.

public sealed class Singleton
{
    private Singleton() { }
    static Singleton instance;
    public static Singleton Instance
    {
        get
        {
            if (instance == null)
                instance = new Singleton();
            return instance;
        }
    }
}

» ادامه مطلب