<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>نوشته های آزاده خرسندنیا</title>
        <link>https://virgool.io/feed/@az.khorsandnia</link>
        <description>برنامه نویس</description>
        <language>fa</language>
        <pubDate>2026-06-16 12:56:23</pubDate>
        <image>
            <url>https://files.virgool.io/upload/users/421471/avatar/c770u9.jpeg?height=120&amp;width=120</url>
            <title>آزاده خرسندنیا</title>
            <link>https://virgool.io/@az.khorsandnia</link>
        </image>

                    <item>
                <title>دیزاین پترن ها(قسمت چهارم)</title>
                <link>https://virgool.io/@az.khorsandnia/%D8%AF%DB%8C%D8%B2%D8%A7%DB%8C%D9%86-%D9%BE%D8%AA%D8%B1%D9%86-%D9%87%D8%A7%D9%82%D8%B3%D9%85%D8%AA-%DA%86%D9%87%D8%A7%D8%B1%D9%85-qdahds8pg2jm</link>
                <description>توی این قسمت به معرفی یک الگوی ساده می پردازیم.الگوی Singleton از دسته الگوهای ایجادی.خاطره ی من از Singletonخاطرم هست در مصاحبه استخدامی داتین از من راجع به دیزاین پترن ها و میزان آشناییم باهاشون، پرسیده شد و من خودم برای اینکه پیش دستی کنم و کار رو به جایی نرسونم که طرف مقابلم بخواد راجع به یک الگوی خاصی که توی ذهنشه ازم سوال کنه، بعد از یک مقدمه کلی از دیزاین پترن ها،بدون اینکه ازم خواسته بشه، شروع کردم به توضیح دادن Singleton که مثلا Singleton اِله و بِله.مصاحبه به خیر و خوشی به پایان رسید و اون موقع فکر میکردم عجب!. اینقدر خوب گفتم که فهمید دیزاین پترن ها رو بلدم و دیگه خودش رفت سراغ سوال بعدی.ولی الان که کمی عمیق تر شدم روی این مباحث، میفهمم اون وسط های &quot;اِل و بِل&quot; گفتن هام، یک عالمه &quot;جیم بل&quot; هم تحویلش دادم! و احتمالا صرف نظر کردن مصاحبه کننده از ادامه سوال درباره دیزاین پترن ها، ناشی از ریختن کُرک و پر اش بوده!مخصوصا که بین Singleton و کلاس استاتیک پیوند ژنیتیکی پیدا کردم!حالا به هر حال، اینو گفتم که بگم اصولا دیزاین پترن ها چیز حفظ شدنی نیست.درک کردنیه و سعی کنید درک کنیدش و محل استفاده اش رو پیدا کنید.مقدمه ای بر الگوی Singletonالگوی Singleton برای برآورده کردن این دو هدف معرفی شده که :1- از یک کلاس تنها و تنها یک شی ایجاد شود.2- امکان دسترسی سراسری در اپلیکیشن هم برای آن یک دونه شی وجود داشته باشد. علارغم راه های مختلفی که برای پیاده سازی این الگو وجود داره، در حالت کلی کلاس هایی از الگوی Singleton دارن پیروی میکنند، دارای یک سری مشترکات اساسی هستند:1- یک سازنده با سطح دسترسی Private که هدف اش محدودیت برای ایجاد بیشتر از یک instance یا شی از کلاس هست.2- یک متغیر Static از جنس خود کلاس هستند که این متغیر در واقع همون یک دونه شی موجود ما هست.3- یک متد Static با سطح Public که کارش برگردوندن همون متغیر بند دوم هست. این متد Static همون سطح دسترسی سراسری رو ب--رای instance ایجاد شده به وجود میاره.ایجاد الگوی Singletonهمانطور که در بخش قبل اشاره شد گفتیم که راه های مختلفی برای پیاده سازی Singleton وجود داره. این تفاوت ها عمدتا در زمان ایجاد شدن شی است. یعنی :1- شی در زمان تعریف خود متغیر Static ایجاد بشه. (Eager initialization)2- شی داخل متد Static ایجاد بشه. (Lazy initialization)3- شی درون داخل سازنده Private ایجاد بشه.و تفاوت های بعدی این پیاده سازی ها هم در :1- نحوه چک کردن عدم وجود Instance از کلاس2- دفعات چک کردن وجود نداشتن شی است. که این بحث چک کردن، برای سیستم هایی مهم می شود که یا دارای Multi threading هستند. یا از طریق reflection قراره کلاس ازش استفاده بشه و ... . یعنی دغدغه سیستم های خاصی است که safe بودن از بابت اینکه مطمئن باشیم فقط و فقط یک شی در کل برنامه ایجاد میشه، اهمیت پیدا میکنه. من یک نمونه ساده و استاندارد این موضوع از Singleton رو مثال میارم :public sealed class SingletonSample
{
     private static SingletonSmaple _instance;
     private SingletonSmaple() {}
     public static SingletonSmaple GetInstance
     {
                get
               {
                         if (_Instance == null)
                                _instance = new SingletonSample();
                         return _instance;
       }
}سوال : Singleton کجاها به درد ما میخوره؟عموما Singleton در سناریو هایی مطرح میشه که ما در مورد دسترسی به منابع مشترک در سامانه دغدغه داریم. مثلا دسترسی به دیتابیس. اگر کانکشنی به دیتابیس هست و ایجاد شده، ما مجدد یک کانکشن جدید نسازیم که اون قبلیه به حال خودش رها بشه. هر وقت نیاز به ارتباط با بانک در جایی از بیزنس برنامه بود همون شی موجود رو ازش استفاده کنیم.سوال : اگر قراره که فقط یک شی باشه با سطح دسترسی عمومی، خب چرا از کلاس Static استفاده نکنیم؟ چرا الگوی Singleton؟کلاس Static درسته که ازش فقط و فقط میشه یک instance یا شی تولید کرد و این شی رو به صورت عمومی ازش استفاده کرد. با  اما یک سری تفاوت های عمده با کلاسی که از الگوی Singleton پیروی میکنه داره :  اولا یک کلاس Static نمیتونه یک اینترفیس رو پیاده سازی کنه.دوما از یک کلاس Static نمیشه ارث برد.سوما خود کلاس Static هم نمیتونه child یک کلاس دیگه باشه. حتی اگر کلاس پدرش هم static باشه.چهارما یک کلاس static رو نمیشه Dispose کرد.پنجما که یک کلاس با الگوی Singleton از Lazy loading یا به عبارتی Lazy Initializing میتونه استفاده کنه ولی کلاسی که Static هست حتما در زمان Load اپلیکیشن ازش شی ساخته میشه.ششما کلاس با الگوی Singleton میتونه سازنده داشته باشه. درصورتیکه کلاس Static بابت سازنده محدودیت داره.هفتما متد های یک کلاس Static قابلیت Override شدن رو ندارن.سوال : اون Sealed اون بالا توی کدی که نوشتی واسه چیه؟کلمه کلیدی Sealed باعث میشه که من مانع از این بشوم که از کلاس ایجاد شده طبق الگوی Singleton خودم کسی ارث ببره.</description>
                <category>آزاده خرسندنیا</category>
                <author>آزاده خرسندنیا</author>
                <pubDate>Sat, 08 Apr 2023 12:12:40 +0330</pubDate>
            </item>
                    <item>
                <title>دیزاین پترن ها(قسمت سوم)</title>
                <link>https://virgool.io/@az.khorsandnia/%D8%AF%DB%8C%D8%B2%D8%A7%DB%8C%D9%86-%D9%BE%D8%AA%D8%B1%D9%86-%D9%87%D8%A7%D9%82%D8%B3%D9%85%D8%AA-%D8%B3%D9%88%D9%85-uylsk3ccbfo3</link>
                <description>در این قسمت در مورد مدل دیگه از الگوهای ایجادی یا Creational صحبت خواهیم کرد. در قسمت قبلی الگوی Factory رو توضیح دادم.الگوی دیگه ای که در این قسمت میخوام بهش بپردازم بی ارتباط با الگوی Factory نیست و اسمش هست Abstract Factory.مقدمه ای بر الگوی Abstract Factoryاین الگو به Super Factory یا Factory of Factories هم شناخته میشه و ایده اش شبیه به همون ایده Factory هست.با این تفاوت که ما اینجا در مورد تنها یک کلاسی به اسم Factory، که بیاد بر اساس پارامتر ورودی که بهش پاس میدیم، به ما یک شی تحویل بده، اونم از یکی از Concrete کلاس های ارث برده شده از یک اینترفیس واحد، صحبت نمیکنیم. داریم در مورد یک لایه انتزاع برای خود اون کلاس Factory هم صحبت میکنیم.حالا سوال مهم اینه که در چه شرایطی من باید تشخیص بدم که از Abstract Factory باید استفاده کرد؟ یکی از نشانه ها اینه که در اینجا هم باز ما داریم رد پای یک اینترفیس رو میبینیم، که یک تعدادی Concrete کلاس ازش ارث بردند. اما این کلاسها با هم دیگه از نظر نوع و کارکرد در سامانه متفاوت هستند.بیاین یک مثال Real یا واقعی بزنیم.فرض کنید یک سامانه آموزشی داخل یک ERP سازمانی نوشتید. قبلا این سامانه آموزشی، داخلش همه کلاس های از نوع حضوری بودن. ولی خب از تایپ های مختلف:سیمینارضمن خدمتکنفرانسو ...حالا کرونا شده! و کارفرما توی جیرا براتون یک تیکت توسعه زده که &quot;آقا، من بعد یک مدل کلاس های دیگه هم دارم که اینا مجازیه!.یعنی یک سری کلاس دارم که آنلاین برگزار میشه، یک سری کلاس دارم که مدرس ها فیلم هاشو آپلود میکنه و یک عده افراد خاص مجوز دانلود دارند و ...&quot;الان خب یک سری موجودیت های جدید داره به سامانه شما افزوده میشه که اینا واقعا کلاس هستند. رفتار همون کلاس رو دارن. همون ویژگی ها رو دارند:مدرس دارن، ارزشیابی دارن، چاپ نمرات دارن، دانشجو دارند و ... به همون اینترفیس شما که برای کلاس ایجاد کردید، پایبند خواهند بود و ملزم به پیاده سازی Api همون متد ها هستند.ولی واقعیت با اون Concrete کلاس ها دیگه که از این اینترفیس ارث بردند، یک فرق هایی هم دارند. اینجاست که شاخک های ما باید روی الگوی Abstract Factory حساس بشه. مخصوصا اگر شما قبلا یک کلاس Factory داشتید. بهترین کار اینه که نیاید اون رو دست ببرید توش و بهش پارامتر اضافه کنید و ایف و الس بزنید.بلکه یک Super Factory بسازید که اون بیاد باز براتون تشخیص بده که از کدوم Factory شی قراره ایجاد بشه، از Factory کلاس های حضوری ، یا از Factory کلاس های غیر حضوری. ایجاد الگوی Abstract Factory_________________________________________________________________________ public interface ICourse
{
      CourseDTO GetCourse();
}
کلاس های حضوری ____________________________________________________________ public class FaceToFaceClass: ICourse 
{
       #region ICourse Members
             public CourseDTO GetCourse() { ... }
       #endregion
}
//---------------------------------
public class SeminarClass : ICourse
{
       #region ICourse Members
             public CourseDTO GetCourse() { ... }
       #endregion 
}
کلاس های غیر حضوری ________________________________________________________ 
public class OnlineClass: ICourse
{       
        #region ICourse Members
             public CourseDTO GetCourse() { ... }
       #endregion 
}
//--------------------------------
public class OfflineClass: ICourse 
{
        #region ICourse Members
             public CourseDTO GetCourse() { ... }
        #endregion
}حالا میریم سر وقت Factory سازی:____________________________________________________________________________________________
public class AbstractFactory
{
     abstract ICourse GetCourse(string courseType); 
}
فکتوری کلاس های حضوری ____________________________________________________ 
public class InPersonClassFactory : AbstractFactory
{
      public ICourse GetCourse(string courseType)
      {
          if (courseType == &amp;quotSeminar&amp;quot)
              return new SeminarClass();
          if (courseType == &amp;quotFaceToFace&amp;quot)
              return new FaceToFaceClass();
          else
              return null;
      }
}
فکتوری کلاس های غیر حضوری ________________________________________________ 
public class RemoteClassFactory : AbstractFactory 
{       
        public ICourse GetCourse(string courseType)
        {
            if (courseType == &amp;quotOnline&amp;quot)
                return new OnlineClass();
            if (courseType == &amp;quotOffline&amp;quot)
                return new OfflineClass(); 
            else 
                return null; 
         } 
}حالا یک کلاسی میسازیم به اسم FactoryProducer :public class FactoryProducer
{                
     public static AbstractFactory GetFactory(bool isRemote)         
     {             
           if (isRemote)
                 return new RemoteClassFactory();             
           else                 
                 return new InPersonClassFactory();
     }
}کاره ما تمومه. وقته اونه که از این کلاس ها در بیزنس ها استفاده کنیم :AbstractFactory courseFactory = FactoryProducer.GetFactory(false);ICourse course = courseFactory.GetCourse(&quot;FaceToFace&quot;) </description>
                <category>آزاده خرسندنیا</category>
                <author>آزاده خرسندنیا</author>
                <pubDate>Thu, 23 Feb 2023 12:25:35 +0330</pubDate>
            </item>
                    <item>
                <title>دیزاین پترن ها(قسمت دوم)</title>
                <link>https://virgool.io/@az.khorsandnia/%D8%AF%DB%8C%D8%B2%D8%A7%DB%8C%D9%86-%D9%BE%D8%AA%D8%B1%D9%86-%D9%87%D8%A7%D9%82%D8%B3%D9%85%D8%AA-%D8%AF%D9%88%D9%85-zjov6n8sb48d</link>
                <description>در این قسمت به بررسی اجمالی یکی از  پترن های Creational یا ایجادی می پردازیم.در قسمت قبلی گفتیم که الگوهای معروف به GoF یا Gang of Four، به سه دسته بندی تقسیم میشوند که یک دسته از این الگو ها، الگوهایی هستند که تمرکز آنها بر روی ایجاد شی از کلاس است. که به آنها Creational یا ایجادی میگویند.نکته مهمی که برای هر برنامه نویسی اهمیت داره، این نیست که بتونه یک پترن رو از نظر تئوری توضیح بده توی مصاحبه ها. بلکه نکته مهم در اینه که بدونه کجا باید از چه الگویی استفاده کنه؟ در واقع باید علت و چرایی انتخاب اون الگو رو به درستی درک کنه و هدف منم همینه که بتونم تا حد امکان این انتخاب کردن رو توضیح بدم.مقدمه ای بر Factory patternالگوی Factory، یکی از پرکاربرد ترین الگوهای Creational و در زمره یکی از بهترین های اونهاست. و هدف اصلیش اینه که به جای فراخوانی مستقیم خود concrete کلاس هایی که یک اینترفیس یکسان رو پیاده سازی کردند، برای ایجاد شی، از خود اینترفیس استفاده کنیم و یک مرجع واحد برای ایجاد شی داشته باشیم.نکته ی مهم جهت انتخاب الگوی Factory همینه که ما با یک مجموعه کلاس روبه رو هستیم که این کلاس ها از یک Implemention یکسانی بهره مند هستند.یعنی همه شون از یک اینترفیس مشترک ارث بری کردند.نکته مهم دیگه که ما رو به این نتیجه میرسونه که باید از این الگو استفاده کنیم، اینه که ما نمیدونیم کدوم شی دقیقا قراره ایجاد بشه. یعنی ما نمیدونیم کدوم کلاس قراره دقیقا new بشه. به بیان بهتر، ایجاد شی در زمان Run time ئه که داره تعیین میشه. و نکته آخر اینکه عموما ایجاد شی، یک سری عملیات لازم داره که این عملیات یک کاره هزینه بر است. یعنی ما عموما برای اشیا ایجاد شده بابت هر کلاس، یک سری کارهایی داریم انجام میدیم.بنابراین:سه شرط برای انتخاب الگوی Factory عبارتند از :کلاس هایی که از روی یک interface یکسان پیاده سازی یا Implement شدن.نوع شی ای که قرار است ایجاد شود، در لحظه Runtime مشخص میشود.ایجاد شی یک کاره هزینه بر است و باید یک سری عملیات بابتش انجام بشود.بزارید با یک مثال واقعی و ملموس شروع کنیم.فرض کنید که دارید یک سیستم بانکی پیاده سازی میکنید. در اونجا موجودیتی هست به اسم حساب بانکی. که خب نوع های مختلفی ازش هست ولی یک سری عملیات یکسان داره.مثل گرفتن اطلاعات حساب، بستن حساب، گرفتن جزئیات گردش حساب و  ...پس من احتمالا با یک اینترفیس روبه رو هستم به اسم BankAccount و یک سری متد دارم داخل این اینترفیس که اومدم API شون رو مشخص کردم. و حالا هر حساب بانکی که بخواد این اینترفیس رو دنبال کنه، ملزم به پیاده سازی متدهای این قرارداد هست.مثلا متد GetAccount که برای گرفتن اطلاعات حسابه. یا متد GetAccountDetails که برای گرفتن جزئیات حسابه و غیره. خب طبیعتا ما نوع های حساب بانکی مختلفی داریم. مثلا حساب جاری، قرض الحسنه، ارزی و ...حالا چه اتفاقی می افته اگر شما بخواید بسته به ورودی کاربر، هر کدوم از این Concrete کلاس ها رو ایجاد کنید؟ مثلا یک صفحه وب جلوی کاربر باز کردید که کارش افتتاح حسابه و بعد چند تا گزینه برای انتخاب داره:افتتاح حساب جاریافتتاح حساب قرض الحسنهافتتاح حساب ارزیو ...این همون قضیه runtime ئه که اشاره کردم.یعنی ما عملا نمیدونیم چه input ای قراره بیاد و این ندونستن، ایجاد شی رو روال مند میکنه و هزینه بر.چون شما باید این انتخاب رو هندل کنید:یعنی بنویسید if حساب جاری بود، then برو از کلاس حساب های جاری یک شی نیو کن، برگردون.باز یک if دیگه که اگر حساب قرض الحسنه بود، then برو از کلاس حساب های قرض الحسنه یک شی نیو کن، و برگردونو همینطور تا اخر.و حالا چند مشکل خودشو داره نشون میده.اولا من اگر جای دیگری از بیزنس اپلیکیشنم، خواستم امکان افتتاح حساب بگذارم، اون وقت باز باید تمام این ایف و الس ها رو بردارم اونجا هم ببرم کپی کنم، که گزینه افتتاح حساب ام توی اون بخش برنامه ام، نره توی دیوار.دوما اگر یک کلاس جدیدی اضافه شد،یعنی یک نوع حساب جدید که بخواد از این اینترفیس ارث بری کنه، باز باید برم تک به تک بیزنس هایی که برای افتتاح حساب نوشتم رو تغییر بدم و یک ایف جدید بهشون اضافه کنم.اینجاست که شما باید برید به سمت الگوی Factory  pattern.ایجاد الگوی Factory patternاین الگو فهم ساده ای داره.همونطور که از اسمش مشخصه، ما باید برای موجودیت خودمون، یک کارخونه کوچیک بسازیم! و ایجاد شی رو بر عهده اون کارخونه بگذاریم و اون کارخونه است که برای ما شی رو میسازه و میاره بهمون تحویل میده. و اصلا هم اهمیتی نداره اون روال ساختنش. اون چیزی که مهم اینه که ما هر چی سفارش دادیم، همونو بهمون بده. یعنی ما علاوه بر کلاس هایی که اومدن اون اینترفیس مورد نظر ما رو، یعنی BankAccount رو پیاده سازی کردن، یک کلاس مستقل دیگه هم میسازیم به اسم BankAccountFactory.این BankAccountFactory، یک متدی داره که کارش اینه که سفارش بگیره، خروجی رو بده. فقط چون نوع خروجی مشخص نیست. خروجی رو از نوع همون اینترفیس مشترک میده.(بر طبق اصل L اصول SOLID) یعنی یک متدی داره به اسم CreateBankAccount که یک پارامتر ورودی از نوع string داره به اسم accountType و بعد در خروجی BankAccount برمیگردونه. این پارامتر ورودی نوعش به خودتون بستگی داره. میتونه یک Enum باشه. میتونه یک عدد اینتیجر باشه.میتونه هر چیزی باشه، ولی باید در ورودی ما نوع ای که قراره ایجاد بشه رو مشخص کنیم.بعد تمام اون ایف و الس ها داخل این متده مینویسیم. یعنی دقیقا داخل متد ما یک نوع Concrete کلاس رو return میکنیم:_________________________________________________________________________
public interface IBankAccount 
{
    AccountDTO GetAccount();
    َAccountDetailDTO GetAccountDetails();    
}
کلاس حساب های جاری _______________________________________________________
public class CheckingAccount: IBankAccount
{
     #region IBankAccount Members
        public AccountDTO GetAccount() { ... }
        public AccountDetailDTO GetAccountDetails() { ... }
     #endregion
 }
کلاس حساب های قرض الحسنه _________________________________________________
public class LoanAccount: IBankAccount 
{
      #region IBankAccount Members
          public AccountDTO GetAccount() { ... }
          public AccountDetailDTO GetAccountDetails() { ... }
      #endregion
}تعریف BankAccountFactory به شکل زیر است :public class BankAccountFactory    
{ 
     public IBankAccount CreateBankAccout(string accountType)
     {
         if (accountType == &amp;quotCheckingAccount&amp;quot)
             return new CheckingAccount();
         if (accountType == &amp;quotLoanAccount&amp;quot)
             return new LoanAccount();
     }
}نحوه استفاده در بیزنس برنامه هم به این شکل هست :BankAccountFactory accountFactory = new BankAccountFactory(); 
IBankAccount account = accountFactory.CreateBankAccout(inpute);</description>
                <category>آزاده خرسندنیا</category>
                <author>آزاده خرسندنیا</author>
                <pubDate>Tue, 21 Feb 2023 02:12:00 +0330</pubDate>
            </item>
                    <item>
                <title>دیزاین پترن ها(قسمت اول)</title>
                <link>https://virgool.io/@az.khorsandnia/%D8%AF%DB%8C%D8%B2%D8%A7%DB%8C%D9%86-%D9%BE%D8%AA%D8%B1%D9%86-%D9%87%D8%A7%D9%82%D8%B3%D9%85%D8%AA-%D8%A7%D9%88%D9%84-zdzuaftqalhz</link>
                <description>مقدمهبه عنوان یک برنامه نویس، فارغ از اینکه با چه زبان شی گرایی کد نویسی کنید، یک سری چهارچوب فکری برای کد نویسی باید در اختیار داشته باشید. این چهارچوب هاست که در کنار کد نویسی، به شما در تولید کد با کیفیت کمک میکنه.ما در برنامه نویسی:یک سری اصول داریم مثل SOLID،DRY و KISS.یک سری پترن یا الگو داریم که مشهور ترینشون GOF است.سوالی که مطرح میشه، اینه که این دسته بندی، الگو و اصل بر چه اساسی است؟ یعنی چه چیزی رو ما الگو می نامیم و چه چیزی رو اصل؟الگو ها تمرکزشون روی پیاده سازیه. در صورتی که اصل ها اصلا در مورد پیاده سازی صحبت نمیکنند.به بیان بهتر، الگوها از تجربه های زیاد در کدنویسی و در برخورد با صورت مساله های تکراری که در حال حاضر در بسیاری از سامانه های نرم افزاری هست، به وجود می آیند و راه حل هایی هستند که در دنیا توسط بسیاری از برنامه نویسان استفاده شده و نتایج استفاده خوبی در بر داشته و به برنامه نویس ها توصیه میشه که ازشون استفاده کنند. همون اصطلاح معروف چرخ رو اختراع نکن! اگر کسی قبلا چرخ رو ساخته، ازش استفاده کن.اما اصل ها به پیاده سازی نرم افزار کار ندارند. تمرکزشون روی اینه که با توجه به ماهیت نرم افزار و اینکه دائما در حال تغییره و مرتبا گسترش پیدا میکنه، چه طور میشه در مقابل این تغییر و توسعه مقاوم بود و محصولی با قابلیت نگهداری و توسعه ی خوب داشت. در واقع اصل ها تمرکزشون روی خود حفظ و نگهداری محصوله و پایبندی به اصل ضروریه. وگرنه احتمال شکست نرم افزار در مارکتینگ، در نهایت بسیار بالاست.دسته بندی الگوها به بیان سادهبر اساس Gang of Four (GOF) که گفتم مرجع اصلی دیزاین پترن هاست، ما سه دسته بندی اصلی داریم. این دسته بندی بر چه اساسیه؟ بر اساس کاربرد.دسته اول الگوها، الگوهای Creational هستند : یک سری الگو معرفی شدند بابت ایجاد شی از کلاس. یعنی چی؟ به بیان خیلی ساده، یعنی شما یک کلاس داری، و بسته به بیزنس و نیازمندی هایی که داری بابت اون موجودیت، پیچیدگی اش و اینکه میخوای منطق ایجاد شی ات رو هم پنهان کنی و .... به جای اینکه همه جای کد ات، همینطوری خیلی علی الله ای!، فقط بخوای بنویسی new و شی ایجاد کنی، بخوای راه حل های مختلف ارائه بدی.صورت مساله : مثلا یک کلاس Person داری که بر اساس موجودیت شخص حقیقی ایجاد شده. |این آدمه یک جا توی زیر سیستم حسابداری ات ممکنه new بشه که خب رول های مختلف، سطح دسترسی های مختلف و ... میگیره. یک جا ممکنه توی زیر سیستم انبارت new میشه. یک جا ممکنه توی زیر سیستم حقوق دستمزدت new میشه. یک جایی ممکنه توی زیر سیستم فروش به عنوان مشتری ات new بشه. یعنی ممکنه از این کلاس برای مصارف مختلفی شی ایجاد بشه.پس صورت مساله ات اینه که وقتی یک کلاسی دارم که ازش داره اشیایی مختلفی ایجاد میشود.بسته به نیازمندی، چطوری این ایجاد شدن رو بنویسم خوبه؟ خب الگوهایی مثلا Factory Method یا Abstract Factory رو میتونی به کار بگیری.صورت مساله: آقا من یک کلاسی دارم، خیلی سنگینه. و مدام هم در تمام بیزنس هام ازش داره شی ایجاد میشه. چطوری میتونم این ایجاد شی رو بهینه تر و سبک تر کنم؟...اینجا الگوی prototype توصیه میشه. صورت مساله: من یک کلاس دارم که میخوام یک دونه شی ازش ایجاد کنم.فقط یک instance. چی کار کنم...بهش میگیم برو الگو Singleton رو برای کلاست پیاده سازی کنو الی ماشاالله  که حالا در قسمت های بعدی اگر عمری بود به ریز این الگوها رو توضیح میدم.دسته دوم الگوها، الگوهای ساختاری یا Structural هستند : اینا الگوهایی هستند که تمرکزشون روی نحوه نگارش خود کلاس، توسعه و نیازمندی متد های ایجاد شده داخل کلاس هستند. در واقع اینها الگوهایی هستند که زمانی که میخوای یک کلاس ایجاد کنی،یا یک متد برای کلاست بنویسی و ... قبل از اینکه شروع کنی به نوشتن اش، ازت میخوان که به بیزنس ات، اینکه اصلا این کلاسه یا متده برای چی داره ایجاد میشه و قراره چی کار کنه و چه نیازمندی هایی داره و اینا فکر کنی و بعد شروع کنی به ایجاد کلاس ات. در واقع این الگو ها تمرکزشون روی خود کلاس و متدهاشه. این کلاس قراره چی کار کنه؟ چه طوری توی ارث بری ها شرکت کنه؟ از چه اینترفیسی میخواد ارث ببره یا کرده و ...صورت مساله: فرض کنید میخواهید یک  ERP برای یک شرکت سازمانی خاص ایجاد کنید. خب مسلما در هر ساختار سازمانی، ما موجودیتی به اسم چارت سازمانی داریم که ساختارش درختیه. مدام در تمامی زیر سیستم های مختلف داره پیمایش میشه و عملیات Crud روش انجام میشه و پشت این عملیاتم بیزنس ران میشه.مثلا آدمه از اون سازمان استعفا میده، جابه جا میشه، سمت اش عوض میشه، یا در یک جایگاه سازمانی یک جایگاه جدیدی که قبلا نبوده، قراره ایجاد بشه و ...خب در چنین ساختار درختی، اگر کلاسی برای موجودیت چارت دارید ایجاد میکنید باید به این ساختار Tree گونه این موجودیت فکر کنید و الگو Composit برای این صورت مساله تکراری در دنیا، مطرح شده.صورت مساله: آقا من قبلا توی زیر سیستم حضور غیابم اومدم تمام متدها و روال های محاسبه ی روز تعطیلی و شیفت تعطیلی و ... رو نوشتم. و بعد زیرسیستم حقوق و دستمزد من داره از اینها استفاده میکنه و کارم میکنه.حالا کارفرما میاد میگه که آقا من یک پاداش میخوام توی سازمانم راه بندازم تحت عنوان کارانه ، بعد یک سری فرمول برای محاسبات رقم این کارانه به شما میده. خب یک قسمتی از این روال ها همین الان در حقوق و دستمزد داره استفاده میشه.ولی برای پاداش یک سری تغییراتم لازم هست که صورت بگیره.آیا من بشینم از اول جدا بنویسم همه این روال ها رو مختص کارانه؟ یا بیام دست بزنم توی اون روال ها و برای زیر سیستم حقوق دستمزدم ریسک خطا ایجاد کنم؟خب طبیعتا اینجا الگو Adapter بهتون کمک زیادی می کنه که به این چالش هاتون فائق بشین. و همینطور صورت مساله های مختلفی که الگوهای ساختاری توشون ایجاد شده.دسته سوم یا دسته آخر الگوها، بهشون میگن الگوهای رفتاری یا Behavioral:این الگو ها روی روابط بین اشیا تمرکز دارند. جاهایی که در مورد رفتار یک کلاس یا شی لزوما صحبت میکنیم.صورت مساله: خیلی بر میخوریم توی کد ها به الگوهای شرطی. اگر اینجوری بود، برو اینکارو بکن. else برو اینکارو بکن.باز توی else همینطور یک if دیگه.یک else دیگه و  همینطور تاااااا بی نهایت داره بسته به بیزنس زیاد میشن. خب به مروز زمان این نگهداری کد، انتقال کد به برنامه نویسان بعدی، تست نویسی رو هی بیشتر سخت و سخت تر و سخت تر میکنه. اینجا خب میشه برای چنین رفتار سیستمی از الگو Chain of Responsibility استفاده میکرد. مثل Middleware ها توی دات نت کور. که هر واسط یا Middleware ای کار خودش رو انجام میده خروجی رو میده به واسط بعدی، واسط بعدی و در نهایت کار از همون مسیری که رفته جلو، لازم باشه برمیگرده.صورت مساله: یک سری مجموعه از یک اشیایی دارید که اینها نوع مجموعه شون مشخص نیست. یک بار لیست بهتون پاس داده میشه توی بیزنس. یک بار آرایه پاس میدن. یک بار صف هستند... اصلا مشخص نیست این مجموعه شی شما از چه مدل مجموعه ای قراره بیاد. بعد شما از فارغ از نوع مجموعه، میخوای یک روال پیمایش برای این اشیا بنویسی و خب یک بیزنسی پیاده سازی کنی. خب این یک صورت مساله خیلی پر تکرار در دنیا بوده... من چه جوری میتونم بر این عدم درک از نوع مجموعه ورودی ام غلبه کنم و یک کد همیشگی بنویسم؟ الگو معرفی شده بابت چنین مسائلی Iterator هست.و همینطور مسائل مختلف Behavioral که در دنیا مطرح شده و راه حل به شکل الگو براش ارائه شده.در قسمت های بعدی به جزئیات بیشتری از Design pattern ها خواهیم پرداخت.</description>
                <category>آزاده خرسندنیا</category>
                <author>آزاده خرسندنیا</author>
                <pubDate>Thu, 16 Feb 2023 15:30:27 +0330</pubDate>
            </item>
                    <item>
                <title>مقدمه ای بر تست نویسی</title>
                <link>https://virgool.io/@az.khorsandnia/%D9%85%D9%82%D8%AF%D9%85%D9%87-%D8%A7%DB%8C-%D8%A8%D8%B1-%D8%AA%D8%B3%D8%AA-%D9%86%D9%88%DB%8C%D8%B3%DB%8C-j90qwwnlvrpz</link>
                <description>تست؟فرایند تست برای یک سیستم نرم افزاری، یعنی Verify کردن رفتار اون نرم افزار با استفاده از یک نرم افزار دیگر!. یعنی چی؟ یعنی یک قطعه کدی، منحصرا نوشته می شود که تنها وظیفه اش این است که یک قطعه کد دیگری را فراخوانی و اجرا کند،و صحت رفتارش را بر اساس یک سری معیارهای مشخص شده، تایید یا عدم تایید کند.به این فرایند تست میگویند که خود تست انواع مختلفی دارد، که هر نوعش، اهداف مختلفی را پوشش میدهد.به طور کلی رفتار یک سیستم نرم افزاری، از دو مدل بررسی میشه:رفتار Functionality که یک نرم افزار داره چه کاری انجام میده.رفتار None-Functionality که پیرامون مسائل پرفرمنسی اون نرم افزار هست که چه قدر خوب عمل میکنه.  انواع تست های نرم افزاری1- یونیت تست(Unit test)ساده ترین لول تست، یونیت تست است. یعنی رویکردی که اجزای یک سیستم به خودی خود و فارغ از نحوه ارتباطشان با اجزای بیرونی به خوبی عمل میکنند یا نه. در یونیت تست، ما به اینکه کل یک نرم افزار درست کار میکند یا نه، کار نداریم.بلکه برای هر جز، مستقلا یک تست مینویسیم. مثلا برای یک متد که کارش جمع دو عدد صحیح است، یک تست مینویسید. این یونیت تست کار ندارد که آیا یک نرم افزار ماشین حساب که این متد در آن فراخوانی شده، درست کار میکند یا نه. وظیفه اش فقط و فقط تست همان یک متد است.2- اینترگیشن تست (Integration Test)اینترگیشن تست، در واقع تست یکپارچه است که یک کد رو تست و خروجی های اون یا ورودی کد دیگری میشه یا کد دیگری مستقل از خروجی کد اول فراخوانی میشه و به همین ترتیب یک سری توالی کد ها فراخوانی میشوند و نتیجه تست در نهایت در سطح کل این توالی بررسی میشود که آیا صحیح بود یا نه.3- اکسپتنس تست (Acceptance Test)که بهش یوزر تست هم میگن که تست از نگاه مشتریه. یعنی چی؟ یعنی یک نرم افزاری نوشته شده، خطا هم نداره و مشکلی هم نیست ولی مشتری اون رو نمیپذیره چون نیازش رو ساپورت نمیکنه یا نیازهایی که در اول طراحی مطرح کرده، به عنوان خروجی نمیبینه.4- لود تست (Load Test)جزو تست های None-Functionality یک نرم افزار هست و هدف اش چیه؟ هدف اش اینه که ببینه اون نرم افزار یا اون قطعه کد زیره بار شدید و اگر لود بالایی بهش وارد بشه، باز هم آیا میتونه خروجی صحیحی بده، و اصلا خروجی میتونه بده یا نه.5- پرفورمنس تست (Performance Test)این با لود تست فرق داره. در Load Test، نگاه اینه که پرفورمنس تست اوکی شده!، حالا با لود بالا میاد ببینه اون پرفورمنسه برآورده میشه یا نه.توی پرفومنس تست، ما برای یک عملیات یک معیاری را قرار میدهیم.مثلا این متد من اگر یک بار صدا زده بشه، باید زیره 5 ثانیه خروجی بده. این میشه پرفورمنس تست. لود تست میگه خیلی خب اگر پرفورمنس اوکی بودی، حالا میتونی برای 10 هزاربار کال شدن هم خروجی زیره 5 ثانیه بدی یا نه؟6- استرس تست(Stress Test)این تست با لود تستینگ معمولا ترکیب میشه. یعنی شرایط حساس و نکات حساسی رو در زمان تست در نظر میگیره.مثلا یک دیتابیس Fail over یک دیتابیس دیگه باشه. این استرس تست، با اون لود بالا حالا چی میشه.در واقع معیار استرس تست، اینه که شرایط خیلی خاص و استثنا هم در لود تستینگ مورد بررسی قرار بگیره.7- اسموک تست (Smoke Test)این برای بعد از ریلیز یک نرم افزاره. یعنی تست هایی که وقتی یک سیستمی در محیط عملیاتی Release شد براش اجرا میشه که ببینه آیا انتشار نرم افزار اوکی بوده و کلیات سیستم درست عمل میکنه یا نه.هرم تست یا Test pyramidما یک اصطلاحی داریم تحت عنوان هرم تست و اون یعنی شما وقتی برای یک نرم افزاری آغاز به تست نویسی میکنید چه گام هایی رو باید سلسله مراتبی بردارید.این هرم در واقع نسبت تست ها به همدیگر را نشان میدهد. در واقع من حجم بسیار زیادی Unit test دارم به نسبت Integration test و به همین ترتیب حجم بیشتری نسبت به E2E. ایده این هرم بر این استواره که میگه تست هایی که سریع تر اجرا می شوند یعنی یونیت تست ها، باید به نسبت تست هایی که بزرگتر و کند تر اجرا می شوند در یک نرم افزار بیشتر باشد.اصطلاحات تست1- اس یو تی(SUT : System Under Test)همیشه در یک نگاه، یک نرم افزار یکی است. در صورتیکه اینجوری نیست و در واقع ترکیبی از اجزا است که هر جز اش مستقله.SUT در واقع واحد هدف تست ماست. در یک یونیت تست، شما یک کلاس رو تست میکنید.SUT شما میشه اون کلاس. در اینترگیشن تست، ممکنه n کلاس رو دارید تست میکنید. پس SUT شما الان فرق کرده و شده اون n تا کلاس. در واقع این اصطلاح برای اشاره به هدف تست به کار میره.2- فیکسچر (Fixture)بهش تست فیکسچر هم میگن. هر آنچیزی که باید وجود داشته باشد که ما بتوانیم یک SUT را تست کنیم.اون ها همه میشن فیکسچر. مثلا من میخوام کلاس همکاران را تست کنم. پس باید اول یک شی از اون کلاس new بکنم که بتونم متد مثلا Save اش رو تست کنم. یا باید فلان داده رو از فلان جدولی بخونم که به این متد پاس بدم. اون شی ئه، اون متغیره که همه پیش نیازهای تست کلاس همکار هستند، میشن Fixture های تست شما.نکته : در تست نویسی ما سه گام اصلی داریم. که اینها هم یک جور اصطلاح هستند.در گام نخست، Arrange رو داریم که میشه آماده کردن فیکسچرها و ماک کردن یک سری اطلاعات برای آغاز تست.یک گام Act داریم که در واقع فراخوانی اون متدی که قراره تست بشهو یک گام Assert داریم که میشه چک کردن ریزالت با اون انتظاری که داریم.با اون معیاری که ملاک Fail کردن یا Success کردن یک تست هست برامون.3- تست متد (Test method)سناریو تست. بهش میگن تست متد. معمولا تست متدها رو ما با یک سری فریم ورک مینویسیم که برای دات نت مشهورترین و قویترینش XUnit.NET هست. در واقع فریم ورک هایی مثل XUnit ابزارهایی رو برای تست نویسی در اختیار ما میگذارند. مثلا attribute ای به اسم Fact در بالای یک متد، معرف اینه که این متد، یک تست متده.یک مثال ساده بزنم. یک متدی در یک کلاسی نوشتید که کارش تقسیم کردنه. حالا من میخوام برای این متد تست بنویسم. یک سناریو دارم، تقسیم صحیح بر صحیح. میخوام ببینم این متده تقسیمی که من نوشتم، درست انجام میده این نوع تقسیم رو. پس یک تست متد مینوسم که با یک سری attribute بالای متدم به دات نت میفهمونم این یک تست متده. و داخل اون متد، توش فیکسچرهای تست صحیح بر صحیح رو ایجاد میکنم و متد اصلیه رو باهاش کال میکنم و بعد هم ریزالت اش رو چک میکنم. حالا یک سناریو دیگه دارم تقسیم فلوت بر صحیح. این میشه یک تست متد دیگه و به همین ترتیب.نکته : یک مجموعه از تست متد ها، که بهم مرتبط هستند، تست کلاس رو میسازند.(حالا روش ها و دیدگاه های مختلفی برای دسته بندی تست کلاس ها وجود دارد.)4- تست فریم ورک (Test framework)یک سری کتابخانه در زبان های مختلف، که ما برای نوشتن تست ازشون استفاده میکنیم.مثلا توی جاوا SUnit داریم.JUnit داریم.باز برای دات نت فریم ورک هایی مثل NUnit داریم.XUnit داریم و ...5- تست رانر(Test runner)ابزاری که تست های نوشته شده رو در یک فریم ورک، اجرا میکنه. البته خیلی از تست فریم ورک ها، خودش کتابخانه هایی هم برای ران کردن تست دارند. ولی خب مثلا Resharper میتونه تست های نوشته شده با Xunit رو ران کنه. خود XUnit که یک فریم ورکه، باز رانر خودشم داره. XUnit Runner.نکته : رانرها دو مدل هستند. یا گرافیکی هستن که بهش میگن Graphical یا کامند لاین هستند.6- اَزرشن متد (Assertion method)این متدیه که توی تست قراره عمل Verification رو انجام بده. در واقع متدی که اون نتیجه مورد نظر رو مقایسه میکنه که ببینه خروجی تست متد، باهاش همخوانی داره یا نه.کتابخانه هایی که ابزارهای تست رو در اختیار ما میگذارند، متدهایی هم دارند که عمل Assertion رو انجام میده. مثلا Assert.Equal یا Assert.Should().Be و اینطوری کاره برنامه نویسان رو بسیار راحت تر میکنند.7- دی او سی (DOC : Depend On Component)وابستگی های یک کلاس به کلاس دیگر در زمان تست، یا سرویس یا ریپازیتوری که SUT ما بهش وابسته است رو میگن DOC.</description>
                <category>آزاده خرسندنیا</category>
                <author>آزاده خرسندنیا</author>
                <pubDate>Tue, 25 Jan 2022 13:24:39 +0330</pubDate>
            </item>
                    <item>
                <title>اگر NET. کار هستید باید بدانید(قسمت سوم)-&gt;وابستگی و اصل D از SOLID</title>
                <link>https://virgool.io/Whitenoise/%D8%A7%DA%AF%D8%B1-net-%DA%A9%D8%A7%D8%B1-%D9%87%D8%B3%D8%AA%DB%8C%D8%AF-%D8%A8%D8%A7%DB%8C%D8%AF-%D8%A8%D8%AF%D8%A7%D9%86%DB%8C%D8%AF%D9%82%D8%B3%D9%85%D8%AA-%D8%B3%D9%88%D9%85-%D9%88%D8%A7%D8%A8%D8%B3%D8%AA%DA%AF%DB%8C-%D9%88-%D8%A7%D8%B5%D9%84-d-%D8%A7%D8%B2-solid-h9pui7x2t3cn</link>
                <description>در قسمت دوم ما اصل L از اصول SOLID رو بررسی کردیم.در این قسمت به بررسی اصل D یا همون Dependency Inversion میپردازیم. که به فارسی میشه معکوس سازی وابستگی ها. اصل D، در یک تاپیک مهمی در نرم افزار، تحت عنوان مدیریت وابستگی یا Dependency management، مطرح شده که به ارتباط اجزا با همدیگه میپردازه. مدیریت وابستگی این سوال رو مطرح میکنه، که Component ها یا اجزای درون یک پروژه چطور به هم وصل بشوند، تا ما کد مون در مقابل تغییرات، Flexible یا منعطف تر باشه.اینکه میگیم اتصال بین Component یا اجزا، از دو بعد بررسی میشه:یک بعدش اینه که در یک سلوشنی، پروژه های مختلفی هستند و ما چطوری این پروژه ها رو اصطلاحا Wired-Up یا سیم بندی کنیم که در زمان بیلد کردن سلوشن، سیکل یا Cycle ای نداشته باشیم. جوری که پروژه A، رفرنس به B داشته باشه و B به C و باز C به A و اینطوری کل سلوشن اگر بخواد بیلد بشه،هر پروژه معطل بیلد شدن پروژه دیگه باشه.یک بعد دیگه اش اینه که اصولا چه Concrete کلاس هایی، چه اینترفیس هایی میتوانند داخل یک پروژه در کنار هم قرار بگیرند.چه متر و معیاری باید وجود داشته باشه که ما بخوایم کلاس ها رو در پروژه های گوناگون یا در یک پروژه در کنار هم قرار بدیم؟ چون در نهایت پروژه ها تبدیل به پکیج میشوند. حالا Package در دات نت، همون فایل Assembly به شکل dll هست و در جاوا Jar file. که این خودش دنیایی از بحث رو در مورد Package Cohision و Package Couppling مطرح میکنه. ولی من همه سعی ام رو میکنم که تیکه تیکه وارد بحث ها بشم تا رشته کار از دستمون خارج نشه.&quot;کانکریت کلاس(Concrete class) به کلاسی گفته میشه که متد هاش همگی  پیاده سازی داره و میشه ازش شی ایجاد کرد.&quot;معماری سه لایه -&gt; Big Ball Of Mudبیشتری از ماها که تجربه کاری بالای 6 سال در مارکت نرم افزار رو داریم، با یک طراحی رایج قدیمی که به عنوان معماری سه لایه شناخته میشد آشنایی داریم.معماری سه لایهدر این مدل، اینطور فرض میشد که :من یک لایه با abstraction یا انتزاع بالا دارم، که لایه ی Presentation من هست. گاها بهش لایه UI هم میگن.که در واقع همون واسط کاربری که من ساختم و متشکل شده از گرید ها و تولبارها و ... که به کاربرم نشون میدم.پشت این لایه یک لایه ی Business دارم که Logic یا منطق برنامه ام توش هست. و لایه ی Presentation من به dll یا همون اسمبلی لایه ی بیزنس رفرنس داره. دلیلشم واضحه!. چون برای رخداد های پشت دکمه های تولبار و نمایش داده ها درون گریدش و ...، باید متد ازش فراخوانی کنه.و در نهایت یک لایه ی پایین تر دارم، که لایه Low level تر یا سطح پایینه منه، که به بانک داده وصله و از بانک اطلاعات میگیره و وظیفه این لایه، تنظیم Data Type های پراپرتی های درون کلاس های لایه Business، سرویس دهی برای عملیات CRUD و ... است. و اینجا هم لایه ی Business به dll لایه ی Data Access رفرنس داره. اگر نحوه ی Reference دهی رو در این مدل نگاه کنیم، میبینیم که از بالا به پایینه. یعنی کامپوننت High level داره Low level رو صدا میزنه، برای گرفتن خدمات یا سرویس.ولی آیا Flow یا جریان تغییرات در برنامه هم به همین شکل هست؟ یعنی چی Flow یا جریان تغییرات؟ منظورم اینه که اگر در لایه ای من تغییری ایجاد کنم، این تغییر به لایه ی پایین ترش منتشر میشه و اونجا رو تحت تاثیر قرار میده؟ یا نه اثر تغییراتی که دادم رو در لایه ی بالایی میبینم؟جواب مسما نه هست. جریان تغییرات شبیه به جریان رفرنس از بالا به پایین نیست.چون در واقع تغییر در لایه ی دیتا، که Low level ترین لایه برنامه است، میتونه تا High level ترین لایه هم گسترش پیدا کنه. و این یعنی برنامه ما در معرض ریسک بالایی برای تغییرات هست. چون لایه ای مثل Business که سطح بالا محسوب میشه، و ارزش بالایی هم داره چون منطق برنامه عموما اونجاست و پیچیدگی اشم به مراتب بالاتره از لایه ی پایینی هست، به راحتی میتونه توسط لایه ی پایینی خودش Data، تحت تاثیر قرار بگیره.حالا همین تغییر هم از دو منظر هست.یعنی خود تغییر دادن در یک لایه از دو جنبه میتونه باشه: یک وقتی تغییرات Implementation ای هست، مثلا من میام یک dll جدید به رفرنس های لایه ی Data اضافه کنم و از اون دی ال ال در متدهای این لایه استفاده میکنم و Using میکنم. اینطوری لایه ی بالایی خودم یعنی Business رو وادار کنم که این dll رو یا بشناسه. یا بهش رفرنس بده.یک وقتی تغییرات وحشتناک تره و در سطح ارتباط بین دو تا Concrete کلاس مطرح میشه. مثلا فرض کنید من یک کلاسی دارم در لایه ی بیزینس، که داخلش یک متد محاسباتی داره به اسم CalculateTax.محاسبه ی مالیات که از قضا متد خیلی هم پیچیده است.  این متد برای انجام محاسباتش، احتیاج به پارامتری تحت عنوان Rate داره که از بانک داده خونده میشه. لذا یک شی از کلاسی در لایه دیتا new میکنم و از متد GetRate اون شی برای خوندن عدد Rate ام استفاده میکنم.حالا فردا روزی من میام در API این متد GetRate تغییر ایجاد میکنم. مثلا میام به پارامترهاش یک چیزی اضافه میکنم. یا ترتیب پارامترهاش رو بهم میزنم یا نوع خروجی اش رو تغییر میدم و .... همین تغییر ساده، لایه ی Business من رو میتونه دچار تغییرات عدیده و گاها باگ در چندین نقطه حساس بیزینس برنامه بکنه.پس میبینین که عملا افسار تغییرات به دست لایه ی پایینی افتاده و اونه که داره بالایی ها رو روی دست خودش میچرخونه!! و جریان تغییرات رو هدایت میکنه. و این خیلی بده.بریم در ادامه ببینیم چطور میتونیم وابستگی هامون رو معکوس کنیم.دو مفهوم SAP و SDP در Dependency managementمدیریت وابستگی مفهومی رو در دل خودش داره تحت عنوان stability یا پایداری.یعنی چی؟اگر عکس پایین رو نگاه کنید، از دیدگاه Dependency management ، الان Z از A پایدارتر یا Stable تره. چرا؟ منطقش اینه که تغییر دادن Z سخت تره! چون اگر Z تغییر کنه، A و B و C به نحوی بهش وابسته هستند و تحت تاثیر قرار میگیرند.پس Z باید Stable باشه.پایداری یا Stability رو که اگر یک عددی بین 0 تا 1 فرض کنیم. خونه پایین اش یعنی 0 میشه حداکثر پایداری و خونه بالاش یعنی 1، میشه حداقل پایداری.حالا چطور به این عدد برسیم؟ خیلی ساده است.I = OUT / (IN + OUT)میزان Dependency یا وابستگی خروجی یک کامپوننت، تقسیم بر میزان Dependency یا وابستگی ورودی + خروجی.الان Z هیچ وابستگی از خارج به خودش نداره.(هیچ Referency از بیرون خودش نگرفته). ولی 3 تا وابستگی به خودش داره(یعنی سه جا خودش Reference داده شده و واردشون شده) که A و B و C هستند.پس عدد I برای Z میشه 0. حداکثر پایداری.پس در مقابل Stability، ما مفهومی تحت عنوان Flexibility داریم(بعضی منابع بهش میگن InStability) که یعنی حداقل پایداری که منظورمون کامپوننتی هست، که درونش تغییرات زیاد اتفاق می افته.حالا فرض کنید Z به O که Flexible هست وابسته باشه مثل تصویر بالا. اینجا اولین جایی که اصل Dependency Inversion چراغش قرمز میشه و مفهوم Stable Dependency Principle یا SDP رو مطرح میکنه.یک کامپوننت Flexible نباید یک کامپوننت Stable بهش وصل باشه. چون پایداریش در معرض تهدید واقع میشه.حالا سوالی که مطرح میشه اینه که من چطور میتونم مانع از این وابستگی خطرناک بشم. بالاخره من به O نیاز دارم.نمیتونم که بگم برو گمشو!! Dependency inversion چه راهکاری پیش روی من میگذاره؟در واقع راه حل ساده اینه که من بیام کاری کنیم که این وابستگی از جنس تبعیت باشه. یعنی چی؟یعنی یک اینترفیس معرفی کنم. بعد به کامپوننت Flexible برنامه یعنی O بگم که از اون اینترفیس ارث ببر. به کامپوننت Stable هم بگم تو هم از اینترفیس استفاده کن. حالا O ناگزیر هست که از Contract اینترفیس من پیروی کنه و Z هم دیگه ارتباط مستقیم با O نداره. این میشه همون مفهوم تبعیت که من میگم.اینترفیس در واقع abstraction یا انتزاعی هست که Dependency inversion به عنوان راهکار معرفی میکنه. و هدفش سست کردن ارتباطات(Loose coupling) برای ماژول های Stable هست که توسعه پذیر بودن برنامه رو بالاتر ببره.برعکس شدن وابستگی رو میبینی؟حالا که abstraction یا نقش انتزاع در Dependency inversion مطرح شد. مفهوم Stable Abstraction Principle یا SAP رو هم مطرح میکنم.این مفهوم یا اصل میگه که هر چی یک کامپوننت Stable تر باشه. میزان abstraction یا انتزاعش هم به همون نسبت بالاتره. به زبان ساده تر، یعنی تعداد کلاس های abstract و اینترفیس ها در اون کامپوننت، از تعداد کلاس های Concrete به مراتب بالاتره.جالبه بدونین که abstraction هم مثل Stability یک عدد محاسباتی بین 0 و 1 هست.که از تقسیم میزان کلاس های abstract و اینترفیس، به تعداد کل کلاس های اون کامپوننت به دست میاد.A = AbstractFiles / TotalFilesعدد 1، یعنی حداکثر انتزاع و 0 یعنی حداقل انتزاع.نمودار بالا، ارتباط بین Abstraction و InStability هست که به سه قسمت تقسیم میکنه.ناحیه بالا که Uselessness که یعنی منطقه بلا استفاده.یعنی کامپوننت در حداکثر انتزاع و حداقل پایداری هست. مثل این میمونه که من یک کامپوننت دارم نه به جایی Reference داره و نه از جایی Reference گرفته  و واسه خودش سیلون و حیرون توی پروژه هست!ناحیه پایین Zone of Pain یا قسمت خطرناکه ماجراست. که Abstraction در سطح پایینی هست و Stability در حد بالا. یعنی چی؟ یعنی کامپوننت من پر از Concrete کلاس هست و به خیلی جاها هم Reference داره. پس هر تغییری در این کامپوننت، من رو وادار خواهد کرد که خیلی جاها رو عوض کنم. و این یعنی برنامه نویس دردش میاد!! چون با هر تغییر، توی دردسر بزرگی می افته.پس با این تفاسیر، بهترین و ارزشمند ترین کامپوننت ها، اونهایی هستند که کاملا از این دو ناحیه دور باشند. این کامپوننت ها اونهایی هستند که باب مارتین بهشون میگه ترتیب اصلی یا Main Sequence.فاصله از این ترتیب اصلی، باید شما رو نسبت به کامپوننت خودتون مشکوک کنه.و نیازتون رو به Dependency inversion بررسی کنید.در قسمت های بعدی الگوی طراحی Dependency Injection رو مطرح خواهیم کرد که در مورد تزریق وابستگی به کلاس های Concrete سطح بالاست و چگونگی انجام آن.</description>
                <category>آزاده خرسندنیا</category>
                <author>آزاده خرسندنیا</author>
                <pubDate>Wed, 11 Aug 2021 03:01:03 +0430</pubDate>
            </item>
                    <item>
                <title>اگر Net. کار هستید، باید بدانید(قسمت دوم) -&gt; ارث بری و اصل L در اصول SOLID</title>
                <link>https://virgool.io/@az.khorsandnia/%D8%A7%DA%AF%D8%B1-net-%DA%A9%D8%A7%D8%B1-%D9%87%D8%B3%D8%AA%DB%8C%D8%AF-%D8%A8%D8%A7%DB%8C%D8%AF-%D8%A8%D8%AF%D8%A7%D9%86%DB%8C%D8%AF%D9%82%D8%B3%D9%85%D8%AA-%D8%AF%D9%88%D9%85-%D8%A7%D8%B1%D8%AB-%D8%A8%D8%B1%DB%8C-%D9%88-%D8%A7%D8%B5%D9%84-l-%D8%AF%D8%B1-%D8%A7%D8%B5%D9%88%D9%84-solid-tgakxqpqysnc</link>
                <description>ارث بری یا وراثتارث بری یا Inheritance یکی از جنبه های مهم شی گرایی در سی شارپ است.ارث بری در زبان ساده یعنی من یک کلاسی دارم که در آن یک سری خصوصیت و رفتار، پیاده سازی کردم. حالا میخوام از روی این کلاس، یک کلاس دیگر را Extend کنم. به نحوی که در اون کلاس Extend شده، یا بسط شده:اولا عینا به همون خصیصه ها و رفتارهای کلاس اول دسترسی داشته باشم.اگر خواستم، بتونم رفتارها یا متد های کلاس اول رو در کلاس دوم، بازنویسی یا override کنم.و در نهایت اینکه بتونم به این کلاس Extend شده، خصیصه و رفتار جدید هم اضافه add کنم.نکته ای که در ارث بری مهمه، اینه که در واقع ما میخواهیم از یک کدی که از پیش نوشته شده هست،، دوباره استفاده کنیم و اون کد رو به عنوان یک base یا پایه برای کد جدید، در نظر بگیریم و دیگه دوباره کاری نکنیم و از اول چرخ نسازیم.و نکته مهم دیگه اینه که ارث بری ساختار سلسه مراتبی داره. یعنی چی؟ یعنی یک کلاس میتونه یک کلاس Extend شده ای داشته باشه، که خود اون کلاس Extend شده، باز کلاس دیگری ازش بسط یا Extend بشه و این روال تا بی نهایت هم بره!!  سطح یا Level ارث برینکته مهمیک اشتباهی که در ارث بری به کار میره، اینه که ما از لفظ های Parent-Child یا پدر، فرزندی یا Master-Detail برای توصیف کلاس اول، و کلاس Extend شده استفاده میکنیم و این اشتباهه.لفظ درست ارث بری که اصل L سالید یا همون قانون Liskov بهش اشاره داره، BaseType و SubType هست و سعی کنید که از این به بعد، با این لفظ به ارث بری ارجاع کنید.البته غیر از این لفظ، از دوتایی SubClass-BaseClass یا DriveType-BaseType یا DriveClass-SuperClass هم استفاده می شود.ارث بری و سینتکس #Cارث بری یکی از ساده ترین کارهای ممکن در سی شارپه! اصلا سینتکس پیچیده ای هم نداره.یک کلاس دارم به اسم Apublic class A{       }یک کلاس دیگه دارم به اسم Bpublic class B {}چطور بگم B از A ارث میبره؟ فقط کافیه یک : بگذارم، جلوی اعلان کلاس B و بعدش بنویسم A.public class B : A{}تمام! B از A ارث برد. آیا B میتونه از یک کلاس دیگه ای هم زمان با A ارث ببره؟ نه! از کلاس دیگه ای نمیتونه. ولی از اینترفیس، اره میتونه. میتونه همزمان از چندین اینترفیس ارث ببره، یا از ترکیب یک کلاس با چندین اینترفیس.چرا خب؟ چرا B میتونه از چندین اینترفیس ارث ببره، ولی فقط میتونه از یک کلاس ارث ببره؟ دلیلش دو عامل هست : اولیش اینه که اینترفیس پیاده سازی نداره و در واقع یک Contract محسوب میشه. و پیاده سازی یک اینترفیس، به طور مستقل، درون هر کلاسی که ازش ارث ببره می تونه اتفاق بیفته و این هیچ Conflict یا تضادی در برنامه ایجاد نمیکنه.       عامل دومش سازنده است!. کلاس ها، متد سازنده دارند. حتی اگر شما در کدتون صراحتا متد سازنده ای        نداشته باشید هم، پشت صحنه این سازنده وجود داره! و خود سی شارپ میسازدش. حالا فرض کنید من        شی ای از کلاس B میسازم. با کلمه کلیدی new. اونوقت این سازنده ها چطور صدا زده میشوند؟ سازنده         SuperType اول فراخوانی میشه. اگر من چند تا کلاس Super داشته باشم، اون وقت این ایجاد Conflict         ممکنه بکنه و اینکه نحوه فراخوانی این سازنده ها، برای برنامه گیج کننده باشه.آیا اگر کلاس دیگه از B ارث ببره، مثلا C. اون وقت C به متدها و پراپرتی های A دسترسی داره؟ بله. البته اگر متد یا خصوصیت Private ای در A باشه. نه B بهش دسترسی داره و نه C. ولی به بقیه اش دسترسی داره.آیا من میتونم رفتار یا همون متدی در A رو در کلاس B شخصی سازی کنم. یعنی مثلا A متدی داره به اسم Add و بعد من بیام با همین عنوان Add، یک بدنه(پیاده سازی) دیگه و مستقل،در B براش بنویسم؟ بله. فقط کافیه در اعلان متد Add در کلاس A از کلمه کلیدی Virtual استفاده کنید.public class A  {     public virtual void Add()     {    } }      و بعد در کلاس B، زمان تعریف متد Add از کلمه کلیدی Override استفاده کنید.public class B : A{    public override void Add()    {    }}خب حالا اگر توی همین تابع Add کلاس B، بخوام Add کلاس A رو صدا بزنم، باید چی کار کنم؟ یا اصلا یک فرض دیگه بکنیم. من یک Add توی A دارم و یک Add توی B که بدنه هاشون باهم فرق داره.چون من اومدم override اش کردم در ساب کلاس. حالا در یک متد دیگه ای، من میخوام Add صدا بزنم. برنامه از کجا بفهمه باید Add کلاس Base رو اجرا کنه یا Add کلاس Sub رو؟ اینجا هم یک کلمه کلیدی داریم به اسم base. شبیه this هست، فقط وقتی base رو به کار میبرید، یعنی BaseType. اگر Base نگذارید، برنامه Add کلاس فعلی، یعنی B رو اجرا میکنه.public class B : A  {             public override void Add()           {            }             public void AddAndPrint()                  {                      base.Add();             }}پلی مورفیسم (چند ریختی) و رابطه اش با وراثت. قاطی نکنید!پلی مورفیسم و وراثت، حکایت شون دقیقا حکایت ماست ها و قیمه هاست که نباید قاطی بشوند! درسته که Override کردن یک متد Virtual، درون یک Subtype یک نمونه از کاربرد Polymorphism هست. ولی پلی مورفیسم یا چند ریختی، اصلا مترادف وراثت نیست و این دو در یک کفه با هم قرار نمیگیرند.چند ریختی، یک جنبه دیگری از برنامه نویسی شی گراست. مثل وراثت. و مثل وراثت، به هدف استفاده مجدد کد ها به کار میره. منتها وراثت، میگه اگر کلاسی از یک کلاس دیگه Extend شد، من همه رفتارها و خصیصه های غیر Private اش رو به اون کلاس دیگه هم میدم و میتونه اونم ازش استفاده کنه. ولی پلی مورفیسم، جزئی تر در مورد استفاده مجدد یک کد صحبت میکنه، نه لزوما در سطح کلاس.چند ریختی به دو دسته کلی تقسیم میشه:در زمان کامپایل یا Compile Time که Static binding هم بهش میگن.            که خود همین به دو دسته Function overloading و Operator overloading تقسیم میشه.در حین اجرا یا Run Time که بهش Dynamic binding یا Late binding هم میگن.تقسیم بندی پلی مورفیسمحالا یعنی چی Compile Time و Run Time. این نامگذاری و تفکیک، از چی ناشی میشه؟به این سوال جواب میدم ولی قبلش بیایم در مورد overriding و overloading صحبت کنیم.مفهوم overloadingمفهوم Overloading ، یعنی من برای یک نام(Function) یا یک عملگر(operator)، شکل های رفتاری مختلفی ارائه بدم.برای متد یا Function به سه طریق میشه این کار رو کرد:تفاوت در تعداد پارامترتفاوت در نوع پارامترتفاوت در ترتیب پارامترها، با نوع های مختلف.و برای Overloading در سطح عملگر. فرض کنید من یک کلاس دارم که میتونم ازش instance یا شی تعریف کنم. حالا میخوام برابر بودن دو شی از این کلاس رو چک کنم. بدترین کار، اینه که بشینم دونه دونه، value های پراپرتی های شی ها رو باهم چک کنم.بهترین کار اینه که عملگر == رو برای اون کلاس Overload کنم. به نحوی که هرجا لازم بود، تساوی دو شی رو باهاش چک کنم.public class A{       public int a { get; set; }       public int b { get; set; }       public static bool operator ==(A obj1, A obj2)         {                          return (obj1.a == obj2.a) &amp;&amp; (obj1.b == obj2.b);      }       public static bool operator !=(A obj1, A obj2)     {            return (obj1.a != obj2.a) || (obj1.b != obj2.b);      }}چند نکته مهم درباره Operator overloading اینکه :اولا Operator ها اعضای Static یک کلاس یا struct محسوب میشوند.دوم اینکه حتما باید حداقل یکی از پارامترهای پاس داده شده، در زمان overload کردن عملگر، از جنس همون کلاسی باشه که داریم عملگر رو براش overload میکنیم.سوم اینکه بعضی از عملگرها جفت هستند. وقتی یکی رو دارین overload میکنین، حتما باید جفت اشم Overload کنین.وگرنه بهتون خطا میده. مثل همین مثالی که من نوشتم بالا. == یک جفت =! داره.چهارم اینکه ترتیب پارامتر ورودی، نباید اثری در خروجی عملگر داشته باشه. یعنی الان برای == نباید فرقی بکنه در نتیجه خروجی اش، که کدوم شی، به عنوان پارامتر اول ارسال بشه.پنجم، در Overload کردن یک عملگر، اولویت اعمال اون عملگر رو تغییر نمیده. یعنی اگر * بر + الویت داره. اگر من * و + رو overload کنم.باز هم این الویت پابرجاست.و در آخر اینکه یک سری عملگر ها، مثل + باید حتما در خروجی خودشون، جنس پارامتر ورودی برگردونند. یعنی int + int ، خروجی اش میشه int. حالا اگر شما دارید + رو برای یک کلاس overload میکنین.باید به این نکته دقت داشته باشید.مفهوم overridingدر بالا اشاره کردیم که overriding در زمان ارث بری کاربرد داره و به این شکل هست که من میتونم با virtual کردن یک متد در یک کلاس، با استفاده کلمه override در کلاس SubType، بدنه دیگری رو جایگزین این متد بکنم بدون اینکه اسمش رو تغییر بدم.تقسیم بندی CompileTime و RunTimeحالا برگردیم به اون سوال اول که تقسیم بندی CompileTime و RunTime از کجا میاد.این تقسیم بندی به این اشاره داره که پلی مورفیسم کی قطعا اتفاق می افته. آیا زمانی که من سورسم رو کامپایل کنم و ازش یک اسمبلی بسازم. پلی مورفیسم رخ داده؟ یا نه.ممکنه در حین اجرا شدن برنامه، پلی مورفیسم اتفاق بیفته و ممکن هم هست اتفاق نیفتاده. همه چیز به زمان اجرا شدن بستگی داره؟!بیاین ساده تر کنیم.فرض کنید من یک متد Add نوشتم داخل یک کلاسی، که دو تا پارامتر int میگیره و جمع شون رو خروجی میده. حالا توی همون کلاس، یک Add دیگه نوشتم که دو تا String میگیره و بهم دیگه join شون میکنه و خروجی میده.من سورسم رو که کامپایل کنم و اسمبلی ازش بسازم. پلی مورفیسم من اتفاق می افته و دیگه هیچ ربطی به اتفاقات حین اجرا شدن اون برنامه نداره. این کلاس الان دیگه دارای دو تا Add شده!.تا به ابد. پلی مورفیسم رخ داده و اگر این سورس، به یک سورس دیگه Reference داشته باشه. هر بار من یک شی ایجاد کنم از این کلاس، دو تا Add براش میبینم.ولی حالا فرض کنید که در همون مثال اولیه خودمون، یعنی کلاس B ، من اومدم متد Add رو توش override کردم و این شکلی از پلی مورفیسم بهره بردم. ولی توی بدنه اون متد override شده، بنویسم if کاربر لاگین کننده admin بود، آنگاه Base.Add وگرنه برو این کد دیگه رو اجرا کن. حالا من سورس رو کامپایل میکنم. آیا چند ریختی یا همون پلی مورفیسم اتفاق افتاده با کامپایل شدن؟ نه! چون ممکنه کاربر لاگین کننده ادمین باشه و اینجوری اصلا من ریخت! دیگری از Add ارائه ندادم. چون گفتم Base.Add. که یعنی برو همون Add کلاس A رو صدا بزن. ولی اگر کارم ادمین نبود.الان پلی مورفیسم اتفاق می افته.اصل L در اصول SOLIDسالید، یک مجموعه از اصول در شی گرایی هست که متشکل شده از پنج اصل:Single Responsibility PrincipleOpen-Closed PrincipleLiskov Substitution PrincipleInterface Segregation PrincipleDependency Inversion Principleالان میخوایم اصل سوم که به اختصار LSP گفته میشود و در رابطه با ارث بری هست رو، به تفصیل اینجا بررسی کنیم. اصل لیسکو! که در بعضی منابع به اصل جایگزینی مشهوره. قرارم نیست تاریخچه بگیم که چی شده و کی بوده و چجور شده.اصل Liskov، این پرسش رو مطرح میکنه که چه زمانی، یک کلاس میتواند از کلاس دیگری ارث ببرد؟ آیا تنها یک سینتکس، که من بنویسم public class B : A یعنی ارث بری نوشته شده، درست و صحیح است؟نه!. و برای صحیح بودنش، یک قاعده کلی رو مطرح میکنه و اون اینه که :یک SubType باید از رفتار BaseType خودش پیروی کنه. منظورش چیه؟ منظورش اینه که هر جا شما در کد ات نوشتی :A myObj = new B();و Subtype رو به جای BaseType قرار دادی(جایگزین) کردی، رفتار شی myObj، مشابه تمام آبجکت هایی باشه که از نوع کلاس A هستند و فرقی نکنه.و بابت توضیحش که منظورش چیه، یک مثال کلاسیک میزنه:میگه فرض کنید یک کلاس دارید به اسم Rectangle یا مستطیل.public class Rectangle{      public int Hight {get; set;}      public int Width {get; set;}      public Rectangle(int H,int W)      {            Hight = H;            Width = W;      }      public int Area      {                return Hight * Width;       }}کلاس Rectangle یک سازنده داره، که میاد به پراپرتی های خودش مقدار میده. و یک تابع محسابه ی محیط داره.حالا شما میخواین یک کلاس دیگه بسازین به اسم مربع و با خودتون میگین : مربع همون پراپرتی های مستطیل رو داره، یعنی طول و عرض. مربع هم یک تابع Area داره که شیوه محاسبه اش مشابه مستطیل هست.یعنی ضرب طول در عرض.از نظر هندسی هم، مربع همون مستطیلی است که طول و عرض یکسان دارد. پس میشه که من کلاس مربعی که می سازم، از مستطیل ارث ببرم، و از اون کد ها دوباره استفاده کنم. با این تفاوت که شرط یکسان بودن طول و عرض رو هم بهش اعمال کنم:    public class Squre : Rectangle   {        public Squre(int H,int W) : base(H,W)        {            Hight = Width = H;        }    }حالا در متد Main ، قاعده کلی Liskov رو مینویسیم . یعنی دو تا شی مشابه ایجاد میکنیم از نوع BaseType یعنی مستطیل. منتها برای یکیشون، یعنی S، اومدیم SubType رو جایگزین کردیم. و انتظار داریم S ، رفتارش مشابه با R باشه. چون مربع هم یک جور مستطیله. اگر ما طول و عرض رو یکسان پاس ندهیم، انتظار داریم مربع تبدیل بشه به مستطیل و بتونه جایگزین BaseType خودش بشه.static void Main(string[] args){            Rectangle R = new Rectangle(2, 3);            Rectangle S = new Squre(2, 3);            System.Console.WriteLine(R.Area());            System.Console.WriteLine(S.Area());            System.Console.ReadKey(); }و هیچ خطای کامپایلی هم تولید نمیکنیم و سورسمون اجرا میشه.اما خروجی اون چیزی که انتظار داریم نیست. شی Rectangle S رفتارش در خروجی، به ازای شرایط پارامتری یکسانی که پاس داده شده، مشابه با Rectangle R نیست.چرا میگیم یکسان نیست؟ چون خروجی متد محاسبه محیط برای شی R میشه 6، ولی برای S میشه 2.چرا اینطوری شد؟ چون کلاس Squre با سازنده ای که درون خودش نوشته، قاعده مستطیل بودن baseType رو  نابود کرده! و اینطوریه که با پارامتر های طول و عرض متفاوت، خروجی ایجاد کرده که جوریه که انگار یک مربع با طول و عرض 2 هست!و قاعده جایگزینی، یا لیسکو، یا LSP میگه که این ارث بری، ناصحیح است.ارث بری سلسله مراتبیحالا چطور بفهمیم که ارث بری مون صحیح هست :لیسکو، 6 شرط رو اعلام میکنه و میگه اگر این 6 شرط بین BaseType و SubType برقرار بود. بدونین ارث بری صحیح بوده.شرط اول : Covarient در خروجی متد ها یا Return Type ها مطرح میشه.به این ترتیب که میگه در سلسله مراتب وراثت، ما یک Base کلاس داریم و یک Sub کلاس. حالا اگر متدی در Base هست که داره یک نوع خروجی برمیگردونه، SubType یا باید از همون نوع خروجی بده یا یک کمی محدود تر. یعنی چی؟ یعنی اگر در کلاس base ما متدی داریم که double برمیگردونه. نباید Subtype بتونه در کد خودش، object برگردونه به جای double. باید یا double برگردونه یا محدودتر، مثل int.شرط دوم : Contravarient این مشابه با بالایی هست.ولی در سطح پارامتر های ارسالی یا Method Arguments.اگر متدی در Base هست که داره یک نوع ورودی، SubType یا باید از همون نوع ورودی یا یک کمی محدود تر. یعنی اگر مثلا در کلاس Base ما متدی داریم که double میگیره. نباید Subtype بتونه در کد خودش، به این متد Object پاس بده. یا double پاس میده یا محدودتر میتونه پاس بده و int بده.شرط سوم : Exceptionsاین شرط میگه که SubType باید از Exception هایی که BaseType میده پیروی کنه و Exception جدیدی از خودش نده. مگر اونکه Exception های خودش هم ارث برده شده از Exception های base باشه.شرط چهارم : PreConditionبه هر شرطی که قبل از اجرای کامل یک متد یا کلی تر بگیم یک قطعه کد درون یک Scope، باید true یا صحیح باشه میگن PreCondition یا پیش شرط. مثلا متدی که به عنوان پارامتر ورودی عدد صحیح یا int میگیره و بعد هنوز اجرا نشده یک if گذاشته و میگه عدد پاس داده شده بزرگتر از 10 بود اونوقت بدنه رو اجرا کن، وگرنه برو بیرون از متد. خب این یک PreCondition هست.اصل Liskov میگه که یک SubType حق این رو نداره که پیش شرط ها رو سخت گیرانه تر کنه. یعنی چی؟ یعنی بیاد توی همون مثال متدی که پارامتر ورودی عدد صحیح میگیره،، شرط دیگه هم کنار بزرگتر از ده، قرار بده و بگه and عدد صحیح زوج!. این تغییر جریان در PreCondition نباید برای هیچ متدی از BaseType اتفاق بیفته.شرط پنجم : PostConditionبر خلاف، PreCondition ، که شرط های قبل از اجرا شدن هستند، PostCondition ها بعد از اجرا حتما صحیح یا true  هستند. یعنی چی؟ یعنی مثلا همون متد قبلی فرض کنید که درون بدنه ما همون اول نوشتیم که if پارامتر نال بود، برو به جاش بزار 0. این شرط یک شرط postCondition هست. یعنی این کد اجرا بشه، پارامتر ما دیگه نال نیست. 0 ئه! چون ما داخل متد 0 رو به جاش گذاشتیم.حالا Liskov میگه که یک  SubType حق نداره که PostCondition ها رو ضعیف کنه. یعنی چی؟ یعنی نباید پارامتر رو نال رها کنه. و postCondition رو ضعیف کنه.و شرط ششم : Invarientیعنی ثابت ها. اگر کلاس Base داره به طور ثابت یک سری مقدار دهی میکنه. یک سری عدد های ثابتی رو داره در کد اش قرار میده. Subtype هم باید از همون ثابت های BaseType پیروی کنه.</description>
                <category>آزاده خرسندنیا</category>
                <author>آزاده خرسندنیا</author>
                <pubDate>Sat, 17 Jul 2021 00:40:22 +0430</pubDate>
            </item>
                    <item>
                <title>اگر .NET کار هستید،باید بدانید.(قسمت اول)</title>
                <link>https://virgool.io/@az.khorsandnia/%D8%A7%DA%AF%D8%B1-net-%DA%A9%D8%A7%D8%B1-%D9%87%D8%B3%D8%AA%DB%8C%D8%AF%D8%A8%D8%A7%DB%8C%D8%AF-%D8%A8%D8%AF%D8%A7%D9%86%DB%8C%D8%AF%D9%82%D8%B3%D9%85%D8%AA-%D8%A7%D9%88%D9%84-otcgtna8pe1j</link>
                <description>مقدمهاز نظر من برنامه نویسان، بی شباهت با نوازندگان نیستند. ساز دستشون، تکنولوژی هست که باهاش کد میزنند، و هنرشون توانایی کد نویسی یا به عبارتی نوازندگی اون سازه. فقط و فقط یک تفاوت عمده بین یک برنامه نویس و یک نوازنده وجود داره و اون اینه که فرقی نمیکنه که شما به عنوان برنامه نویس، در یک تیم بزرگ مثل یک ارکستر سمفونی و در یک سالن اپرای عظیم ساز بزنید، یا نوازنده ای باشید که برای دل خودتون و تکی می نوازید. در نهایت در کل عالم و هستی،تنها یک شنونده دارید! و خواهید داشت!بهتر اینه که بگم، غیر از اون، هیچ کسی نیست که توانایی شنیدنه آهنگ شما رو داشته باشه!حتما مشتاق اید بدونید اون کیه؟...سیستم عامل!سیستم عامل رو در تخیل خودتون شبیه مردی میان سال و خوش پوش ببینید، که همیشه کفشهاش برق میزنه.اکثر اوقات لبخندی مبهم روی لبهاشه و کارهاش با هوش و آرامش خاصی توامه.همه باور دارند اون لایق مدیرعاملی کامپیوتر هاست...سلطان بدون منازع!ولی خب سیستم عامل وقته اینو نداره که بیاد خودش حضوری آهنگی بشنوه.تنها لطفش در حقتون اینه که حاضره فایل رکورد شده توسط دستیار اول(CLR) ، کمپانی سازنده سازتون(.NET فریم ورک) رو که با نت های 0 و 1 زده شده، تحویل بگیره.اون دستیار اول هم این فایل رو بر مبنای فایل اسمبلی(exe یا dll) ای که منشی(کامپایلر) در اختیارش گذاشته ایجاد کرده.دیدید؟!...پس فکر نکنید اگر ساز زدن بلد هستید، حتما آهنگساز خوبی هم هستید! چون این به هیچ عنوان کافی نیست.برای آهنگساز بودن و موزیسین شدن، باید اولا درک خوبی از نت ها و ملودی ها داشته باشید. و دوما از شنونده ی خودتون و سلایق و هوش موسیقیایی اون هم آگاه باشید. جوری که قریحه ی اش رو بنوازید تا اونم بتونه باز نوازی زیباتری از کارتون رو گوش بده.پس برنامه نویسان دات نت بدونند. فرقی نمیکنه با چه تکنولوژی(asp .NET,.NET Core,Windows Form) و با چه زبانی (++C یا سی شارپ یا اف شارپ و ...) دارید کد میزنید.زمانی موفق هستید که در باره دات نت عمیقا یاد بگیرید و بدونید دارید چی رو کد میزنید و این کد چه اثری بر روی سیستم عامل داره و چطوری میشه کدی نوشت که حافظه بهتر مصرف بشه و در نهایت سرعت بیشتر بشه و در نهایت کد شما بهینه تر و قابل توسعه تر بشه. دونستن اصول دات نت و فهم متقابل اثر کد شما روی خروجی که سیستم عامل از اجرا میاره مهمه. معماری .NETمعماری .NET در تصویر ذیل نشان داده شده است.این معماری بر روی سیستم عامل قرار میگیرد.لایه 1 پایین ترین سطح، و لایه 5 بالاترین سطح آن است و IDE دات نت، Visual Studio می باشد. ابزار قدرتمندی که با محیط گرافیکی خود، قابلیت کد نویسی به زبان های .NET را بسیار آسان کرده و برنامه نویسان را از قابلیت های این معماری بهره مند میکند.معماری .NETماشین مجازی .NET یا همون CLRبا نگاه کلی، .NET از دو بخش اساسی تشکیل شده است:کتابخانه دات نت یا همون Class library .NET ،که متشکل شده از یک سری کلاس های آماده و از پیش نوشته شده، با قابلیت استفاده مجدد، که در دسترس تمامی زبان های برنامه نویسی تحت دات هست و برنامه نویس ها میتونند از اون ها استفاده کنند.ماشین مجازی دات نت یا CLR که مخفف Common Language Runtime هست. که بدون شک اصلی ترین بخش .NET Framework محسوب میشه.بخش های مختلف CLRوظیفه CLR  اجرا و مدیریت اجرای کد های نوشته شده تحت فریم ورک یا چهارچوب .NET است.تصویر زیر پروسه ی اجرا شدن کد های نوشته شده تحت فریم ورک دات نت، را نشان میدهد.اتفاقی که زمان Build و Run کردن کد، رخ میدهد.زمان کامپایل یا Buildزبان مشترک حین اجرا یا CLR، تنها یک کد را میفهمد، آن هم کدی به زبان IL یا MSIL است که مخفف Microsoft Intermediate Language  می باشد. کامپایلرهای هر زبانی در دات نت، همگی خروجی یکسانی از نظر زبان برنامه نویسی ایجاد میکنند. IL یا MSIL یک زبان میان سطحی است.چیزی شبیه به زبان اسمبلی.کد IL در فایلی تحت عنوان Assembly فایل نگهداری می شود که میتواند یک فایل با پسوند اجرایی یا exe باشد یا فایلی از نوع dll.توی فایل اسمبلی غیر از کد IL اطلاعات مهم دیگه هم هست که خیلی از این اطلاعات در Reflection در دات نت، قابل استفاده مجدد در کد می شوند. که اگر عمری باشه حتما در مورد Reflection خواهم نوشت.فراداده ها یا MetaData هاکه توصیف تمامی Type های استفاده شده و سطح دسترسی ها و ... در کد شماست.مثلا اگر کلاسی داشته باشید به اسم X. و بعد از این کلاس اشیایی با تایپ X ایجاد کرده باشید. تمامی اطلاعات کلاس X به شکل متا دیتا قابل دستیابی هست که چه متغیرهایی داره.چه رفتارهایی داره.چه سطح دسترسی هایی داره و ...خود توصیفی یا Manifest  که درباره خود اون فایل Assembly که نسخه اش چیه، از چه کامپایلری اومده و ... توضیحاتی داره.اطلاعات اجرایی یا PE که مخفف Portable Executable می باشد اگر بعد از کامپایل، یک فایل با قابلیت اجرایی ایجاد شد، اطلاعات اجرایی اون فایل رو در یک هدری تحت عنوان PE نگهداری میکنه.زمان اجرا یا RUNبا اجرای برنامه، CLR وارد میشه. سرویسی رو تحت عنوان Class Loader فراخوانی میکنه. این سرویس ، میاد اطلاعات اولیه مورد نیاز جهت اجرا کد، مثل قسمت آغاز شونده کد IL و متا دیتاها رو وارد حافظه میکنه و بارگذاریشون میکنه.بعد این کد بارگذاری شده توسط JIT به کد ماشین تبدیل میشه و در نهایت اجرا میشه.در تمام طول مدت اجرای اون در سطح سیستم عامل، مدیریت و کنترل مدیریت حافظه در زمان اجرا، اعمال Type Safety،کنترل امنیت در اجرای برنامه ها،مدیریت Exception ها، مدیریت نخ هاو ... در حال انجام است.</description>
                <category>آزاده خرسندنیا</category>
                <author>آزاده خرسندنیا</author>
                <pubDate>Mon, 19 Apr 2021 13:50:59 +0430</pubDate>
            </item>
                    <item>
                <title>پروتکل HTTP قسمت ششم</title>
                <link>https://virgool.io/@az.khorsandnia/%D9%BE%D8%B1%D9%88%D8%AA%DA%A9%D9%84-http-%D9%82%D8%B3%D9%85%D8%AA-%D8%B4%D8%B4%D9%85-rygwisehepyb</link>
                <description>گفتیم بعضی از فیلد های هدر مختص درخواست هستند. در ادامه قصد داریم همین فیلد ها رو معرفی کنیم.request-header fieldsAcceptاین فیلد نوع رسانه یا media ای که کلاینت به عنوان پاسخ از سرور انتظار داره رو، مشخص میکند که از نوع text باشه، یا از نوع image یا هرچیز دیگه ای . این &quot;نوع&quot; هم به شکل جفتی  تعیین میشه. یعنی چی؟ یعنی مثلا اگر کلاینت image میخواد، باید پسوند تصویر رو هم بگه که jpeg هست، png هست، چی هست؟ که نحوه اعلانش با / است.یعنی image/jpeg. اگر پسوند تصویر خاصی مد نظرش نیست، میتونه به جای ساب تایپ، از * استفاده کنه. بگه imgae/*.غیر از جفتی &quot;type&quot; / &quot;subtype&quot;، فیلده  Accept یک پارامتر دیگه هم داره که بهش میگن q که در واقع همون quality یا کیفیته. حالا این q نقشش چیه؟ الویت ارسال رو برای سرور مشخص میکنه که مقدار دیفالتش برابر با 1 هست. نوع میتونه، مقادیر مختلف بگیره که با کاما از هم جدا میشن. هر نوع هم یک الویت میتونه بگیره و سرور به ترتیب همون الویت بندی، هرچیزی که پیدا کرد ارسال میکنه.بیاین یک مثال باهم ببینیم. Accept: text/html; q=1.0, text/*; q=0.8, image/gif; q=0.6, image/jpeg; q=0.6, image/*; q=0.5, */*; q=0.1الان مثال بالا داره به سرور میگه که، من یک ریسورس از تو میخوام.الویت اول اینه که این ریسورس به شکل یک فایل متنی با پسوند html به من بدی.اگر با این نام فایل متنی با پسوند html پیدا نکردی.الویت بعدی ات این باشه که یک فایل متنی با هر پسوندی، ولی با این نام برای من بفرستی. بعدش اگر نداشتی، میتونی به من یک image بدی با تایپ gif. نداشتی یک image بده با پسوند jpeg. نداشتی یک تصویر بده حالا هر چی بود. اگر تصویرم نداشتی، جهنم!، هر چی با این نام در این path ای که بهت دادم که در سطر آغازین پیام میبینی، برای من بفرست!!! یک گلی خودم اینور توی مرورگر، به سرم میگیرم!Accept-Charsetاینم مشابه Accept، با این تفاوت که کلاینت  اینجا داره در مورد charset های مورد پذیرشش صحبت میکنه.مثلا :Accept-Charset: utf-8Accept-Encodingاینم مثل Accept، با این تفاوت که در مورد انکدینگ charset مورد پذیرشش، داره صحبت میکنه.Accept-Languageاینم مشابه است با Accept، با این تفاوت که در اینجا ما زبان طبیعی که در پاسخ میخواهیم را مشخص میکنیم. مثلا : Accept-Language: da, en-gb;q=0.8, en;q=0.7Authorizationخب رسیدیم به Authorization یا احراز هویت.قبل از اینکه احراز هویت رو بگیم یک نکته ی مهم از پروتکل HTTP باید بدونین و اون اینکه HTTP یک پروتکل StateLess هست. این یعنی چی؟ state یعنی وضعیت و less یعنی کم. و این یک اصطلاحه که مختص HTTP نیست. stateless به معنی عدم نگه داری وضعیته. به زبان ساده، اگر دارین درخواستی به سرور میدین، نمیتونین در اون درخواست، اشاره ای به درخواست های قبلی بکنید! یا از درخواست های قبلی اطلاعاتی بفرستید برای سرور بفرستید. همه چیز در لحظه است!. چون از وضعیت درخواست های قبلی تون چیزی نگه داری نمیشه.پاسخم به همین شکله. مرورگر درخواست میده.سرور پاسخ میده و تمـــــــام! نقطه سره خط!. توی درخواست 10 ام نمیشه چیزی از درخواست 1 ام گفت.چون درخواست 1 پرونده اش به کل بسته شده.منظور از Stateless یعنی این.حالا با این تصور وارد احراز هویت بشیم. احراز هویت یعنی شما باید ثابت کنید که کی هستید. این اثبات هم با ثبت نام کردن یا ورود پیدا کردن از طریق نام کاربری و پسورد اتفاق می افته. وقتی کلاینت درخواست میده برای URL ای که احتیاج به احراز هویت داره، سرور در جواب کد 401 رو بهش میده. همونجا که داره پیغام 401 میده یک سرآیند یا هدر فیلدی به نام WWW-Authenticate را هم پر میکنه که در واقع به مرورگر میگه باید احراز هویت ات به این شکلی باشه که من بهت میگم.و اینجا دیگه کلاینت مجبوره که این فیلد رو پر کنه.یعنی چاره ای نداره که در درخواست بعدی، فیلد Authorization رو مطابق با همون چیزی که سرور توی WWW-Authenticate بهش گفته، پر کنه و بفرسته. حالا این فیلد چه مقادیری میگیره؟ما چند مدل احراز هویت داریم در HTTP. یک مدل Basic که ساده ترین، عمومی ترین و نا امن ترینشونه.مدل Basic مطابق تصویر بالاست.یعنی اول درخواست میره.بعد سرور میگه 401 و همونجا WWW-Authentication رو برابر با Basic قرار میده. میتونه پارامتر Realm داشته باشه یا نداشته باشه. بعد User Agent یا حالا ساده تر بگیم، مرورگر، میاد Username و Password رو معمولا بر اساس یک رمزگذاری بر پایه Base64 که یک روش هش کردن داده است، هش میکنه و میفرسته برای سرور.برای مثال:Authorization: Basic YWxhZGRpbjpvcGVuc2VzYW1l و در پاسخ یا 200OK میگیره.یا سرور بهش میگه 403 که یعنی Forbiden.علاوه بر Basic، یک مدل دیگه هم داریم که بهش میگیم Digest.مدل Digest عملکردش مشابه با Basic هست.فقط یک مقداری امنیت اش بالاتره و اون بیشتر به خاطر اینه که علاوه بر هش کردن ساده، قبلش از الگوریتم های کد گذاری که بر مبنای درهم سازی، برای بالا بردن امنیت هم استفاده میکنه. این الگوریتم ها هم معمولا با SHA نامگذاری میشن. در مدل Digest، سرور یک مقداری به اسم nonce به کلاینت میده. که در نهایت این مقدار به شکلی کد گذاری شده دوباره به سرور داده میشه با این تفاوت که الگوریتم هم ذکر میشهروالشون اینه که میان یک سری اطلاعات دیگه غیر از Username و پسورد رو هم درگیر میکنند و انگار دو بار هش کردن داده دارند که دستیابی به اطلاعات رو به نسبت Base64 سخت تر میکنه.یک نمونه دیگه هم بر اساس یک قرارداد بین کلاینت و سرور هست که بهش میگن توکن.خیلی بحث طولانی ای داره و شاید در این مجال نگنجه و اگر عمری باشه در بحث های دیگه اگر راجع به JWT خواستم بگم اشاره کنم.توی HTTP نمیشه این بحث رو باز کرد. اما به زبان ساده بگم که ما مفهومی داریم تحت عنوان توکن یا Token. این چی هست؟ این یک قرارداد بین سرور و کلاینته که بعد از اولین لاگین ساخته میشه.وقتی من لاگین کردم یک رشته ای به اسم توکن برام ساخته میشه که این رو هم منه کلاینت و هم سرور نگه میداره. تا کی؟ . دفعه های دیگه من همیشه در فیلد Authorization، اون توکن رو با تایپ Bearer میفرستم. البته حتما تایپ اش نباید Bearer باشه.میتونه یک تایپ دیگه بگیره.Expectاین هدر فیلد چون در همه مرورگرها عمومیت نداره بهش خیلی نمیپردازیم.Fromاین هدر فیلد جلوش به عنوان ولیو یک ایمیل میاد. ایمیل شخصی و کاربری. برای یوزر ایجنت های ربات کاربرد داره.Hostاین هدر فیلد که مشخصه کارش چیه.هاستی که داره درخواست به سمتش میره رو مشخص میکنه.If-Matchخب این فیلد هم نکته ی جالبی داره و راهی هست برای کارآمد کردن حافظه ی نهان یا همون Cache سمت کلاینت.بیایم قبل از اینکه بگیم چطوری، ETag رو معرفی کنیم:وب سرور میاد به ریسورس های یک URL یک مقدار Identifier یا همون شناسه به اسم ETag میده. هر تغییری در اون ریسورس، ETag اش رو هم عوض میکنه. حالا اگر درخواستی از کلاینتی بیاد، که توش اومده این هدر فیلد If-Match رو با مقدار یک ETag پر کرده باشه، اون وقت سرور چک میکنه که اگر ETag با ETag خودش همخوانی داشته باشه، دیگه پاسخ کامل نده که پهنای باند رو اشغال کنه و به کلاینت اجازه میده از حافظه ی نهان خودش استفاده کنه.If-None-Matchاین بر خلاف بالاییه.یعنی زمانی که مطابقتی رخ نده، سرور متد درخواست رو اعمال میکنه.If-Modified-Sinceاین درخواست رو در صورتیکه با تاریخ یا زمانی که برای تغییرات گذاشته مطابقت بکنه، متدش رو اعمال میکنه.If-Rangeاین هدر فیلد یک مقداری رو به شکل بازه میگیره. بعد اگر همخوانی داشته باشه که سرور استاتوس کد 206 برمیگردونه و درخواست رو اعمال میکنه. اگر همخوانی نداشته باشه کل ریسورس یا محتوا رو برمیگردونه.نمونه ای از این هدر فیلد رو که برای ما ملموس تره، دانلوده!.فرض کنید دارید یک فایل رو دانلود میکنید.اولین بار درخواستی دادید و سرور داره با متد GET به شما پاسخ میده.بعد ارتباطتتون قطع میشه.اگر محتوای دانلودی شما از قابلیت دانلود چند قسمتی برخورددار باشه، دوباره که اتصال برقرار بشه از سر نو غرل خانوم کل محتوا رو سرور نمیفرسته، بلکه اگر Resume بزنین، این هدر فیلد If-Renge یک مقداری به سرور میده که سرور اگر بتونه اون مقدار رو پردازش کنه، مابقی ریسورس با استاتوس کد 206 یا Partial Content به شما میده.If-Unmodified-Sinceاین برعکس تگ if-Modified-Since است.Max-Forwardsاین هدر فیلد فقط و فقط زمانی کاربرد داره که ما از متد TRACE استفاده کنیم. حالا داستان چیه؟ مقدار این فیلد یک عدد اینتیجره.مثلا 10.بعد این درخواست سره هرراه خودش از پروکسی سروری یا ... ای رد بشه یکی از مقدارش کم میشه و سرور زمانی پاسخ 200 OK میده که وقتی درخواست به دستش میرسه، مقداره این فیلد 0 شده باشه و اونجاست که محتوا رو برمیگردونه.شاید نمیدونم.من از خودم حدس میزنم.شاید برای بحث های امنیتی شبکه مفید باشه.چون میشه فهمید درخواست از مسیر خودش یا مسیر قابل پیش بینی ما یا مورد انتظاره ما خارج شده و به دست یک پروکسی سرور دیگه رسیده که یک مقدار بیشتر ازش کم شده و دیگه 0 نیست.Proxy-AuthorizationRangeRefererTEUser-Agent</description>
                <category>آزاده خرسندنیا</category>
                <author>آزاده خرسندنیا</author>
                <pubDate>Sun, 18 Apr 2021 12:24:44 +0430</pubDate>
            </item>
                    <item>
                <title>پروتکل HTTP قسمت پنجم</title>
                <link>https://virgool.io/@az.khorsandnia/%D9%BE%D8%B1%D9%88%D8%AA%DA%A9%D9%84-http-%D9%82%D8%B3%D9%85%D8%AA-%D9%BE%D9%86%D8%AC%D9%85-a0y4js5z6xsw</link>
                <description>ابتدا یک مرور جامع بر کل مطلب تا کنون داشته باشیم و بعد ادامه مطلب رو بگیم. تا اینجا گفتیم که پروتکل ارتباطی حاکم بر وب، HTTP است که یکی از اهداف ایجادش پنهان کردن توزیع شدگی و پیچیدگی های شبکه ای و سخت افزاری از دیده کاربران می باشد و هدف مهم دیگه اش امکان تبادل داده و برقراری ارتباط، بین کامپیوترها در یک فرم استاندارد و مشخص است.در ادامه گفتیم در یک سمت HTTP، کلاینت با مرورگرش قرار داره و در سمت دیگه اش هم سرور با اپلیکیشن وب سروری(IIS و ...) که روی خودش نصب داره و HTTP بین دو کامپیوتر، در نقشه &quot;سرور&quot; و &quot;کلاینت&quot; داره ارتباط برقرار میکنه. این ارتباط هم فقط و فقط از طریق جُفته &quot;درخواست-پاسخ&quot; اتفاق می افته. یعنی حتما درخواستی باید باشد از سمت کلاینت که HTTP بخواد با سرور ارتباط برقرار کنه، و حتما هم در قبال این درخواست، پاسخی به دست کلاینت میرسونه و این یک قاعده بدون استثناست : هر درخواست، پاسخی هم به همراه دارد.همچنین گفتیم که URL ای که کلاینت به HTTP پاس میده، زمینه ساز ایجاد درخواست HTTP است. به بیانی بهتر، URL درخواست نیست، ولی برای ایجاد یک درخواست از سمت کلاینت، احتیاج به URL داریم.(شرط ضروری درخواست HTTP، وجود یک URL که درونش Host یا سرور مشخص باشه). که راجع به قسمت های URL هم توضیح دادیم. در قسمت قبلی هم بیشتر راجع به خود درخواست و پاسخ گفتیم. اشاره کردیم که درون درخواست یک قسمت مهمی وجود داره، تحت عنوان HTTP متد یا فعل. و درون پاسخ هم یک قسمت مهمی وجود داره، تحت عنوان Status code یا کد وضعیت. الان هم بیشتر میخوایم روی همین درخواست و پاسخ فوکوس کنیم و بیشتر با کاربردشون، کنترل یا هندل کردنشون آشنا بشیم که یواش یواش با پیشروی آموزش ها، با REST و API هم درگیر شیم که مساله ی بسیار مهمیه. یادمون نره که آشنایی با HTTP ربطی به اینکه با چه زبانی کد مینویسین نداره.جزو اصول اولیه بک اند کار شدنه.لذا صحبت های این قسمت هم در تکمیل قسمت قبلیه، ولی تئوری وارتر و با انسجام بالاتر.خُب، شروع کنیم: تا اینجا از درخواست و پاسخ به این نتایج رسیدیم که آدرس یا URL ، میزبان رو درون درخواست مشخص میکنه. HTTP method داره میگه که ما از میزبانمون چی میخوایم که اصلا داریم میریم سر وقتش. میزبان یا همون سرور هم با Status Code به ما میگه که تونسته از پس کاری که ما خواستیم بربیاد یا نه که این نَه هم کلی حرف ها برای ما داره و فقط یک نَه خالی نیست. حتی تونستن اشم حرف های زیادی داره که به ما بگه چطور تونسه! پس اول یک کمی تئوری وار تر وارد استاتوس کد بشیم:کلا Status code متشکل شده از یک رنج سه تایی ارقام که رقم اولش مشخص کننده ماهیت اشه.اگر با 1XX شروع بشه، یعنی کد های Information یا اطلاعاتی.یعنی چی؟  این یعنی سرور درخواست ما رو دریافت کرده و در فهم درخواست هم مشکلی براش پیش نیومده. ولی پاسخی که با 1xx به ما میده، پاسخ نهایی درخواست ما نیست!.سرور فقط با این کد ها، داره از چگونگی و نحوه پردازش درخواست ما در سمت سرور، بهمون اطلاعات میده.خب کاربرد و هدف این اطلاعات برای چیه؟یکی از کاربردهاشون اصطلاحا Server check ئه.یعنی قبل از اینکه بدنه ی درخواست فرستاده بشه، یک چک میکنه با یک سری اطلاعات از هدر درخواست که ببینه اصلا رد میشه درخواستتون یا نه. اگر بناست که سرور درخواستی رو رد بکنه، یعنی اصلا بدنه درخواست رو نگاه نمیکنه دیگه. پس اصراری نیست که درخواست از اول با بدنه بره. اگر سرور در ازای هدر گفت 100 Continue، که یعنی تا اینجا مشکلی نداشته درخواست، بعد بدنه ی درخواست  تکمیل بشه.( این گروه استاتوس کدها بعد از HTTP 1.0 به وجود اومدند)اگر 2XX داد، در پاسخ که یعنی Successful. یعنی خطا نداشته.معروفترینشونم که 200 ok.اگر با 3XX شروع شد، یعنی این درخواستی که بهش دادیم برای انجام شدن نیاز به یک سری اقدامات دیگه داره. اصطلاحا به پیام های گروه 3xx میگن پیام های Redirection.یعنی سرور در فهم درخواست مشکلی نداشته ولی برای انجام درخواست، داره حواله مون میده به چیزهای دیگه ای که به عنوان نیاز انجام درخواستش میخواد.پس بازبینی و بررسی این پیام ها برای ما مهمه.گروه 4XX یعنی مشکلی در خود درخواست ارسالی کلاینت وجود دارد. حالا یا خطا در خود درخواست هست که آدرس اشتباهه یا Resource ای که ما ادرس دادیم، دیگه وجود نداره و … . یا اینکه اصلا امکان تحقق درخواست به هر شکلی و تحت هیچ عنوانی، وجود نداره و رد شده.گروه 5XX میشن خطاهای سرور. این یعنی درخواست واضح بوده ولی خود سرور توانایی انجامش رو به هر دلیلی، نداره و خبر از مشکلی در سمت سرور حکایت داره.--------------------------------------------------------------------------------------------------------------------------------------------------------پیام های HTTP از 4 بخش تشکیل شده :1- سطر آغازین که الزامیه و گفتیم مهمترین قسمت اش برای درخواست، HTTP متد ئه و برای پاسخ Status code ئه.GET /hello.htm HTTP/1.1     (نمونه سطر آغازین در پیام درخواست)HTTP/1.1 200 OK             (نمونه سطر آغازین در پیام پاسخ)2- بعد از سطر آغازین دوتایی های &quot;فیلد-مقدار&quot; سربرگ یا Header میان. (که الزامی نیستند. میتونند باشند و میتوانند نباشند). بعضی از این دوتایی ها بین درخواست و پاسخ مشترک هستند.بعضی مختص درخواست هستند.بعضی مختص پاسخ هستند و بعضی اطلاعاتی راجع به Body یا بخش چهارم پیام میدند.حالا در این قسمت من دوتایی های جنرال رو براتون میگم. که عبارتند از :general-header fields Cache-Control این فیلد در هدر، داره مکانیزمی که برای ذخیره سازی یا caching باید پیروی بشه رو مشخص میکنه.به زبان بهتر، زمان و نحوه کش شدن یک ریسورس رو مشخص میکنه. مثلا فرض کنید یک درخواستی بابت ریسورس یک تصویر داره از سمت کلاینت، به سرور میره و سرور در پاسخ داره این تصویر رو با status code 200ok در سطر آغازین،برمیگردونه. اگر سرور در همون پاسخ، بیاد این فیلده هدر رو هم مقداری برابر با Cache-Control: max-age=2592000, publicبده. اون وقت کلاینت یا همون مرورگر، میاد این محتویات body پاسخ رو به مدت حداکثر 2592000 ثانیه، نگه میداره یا اصطلاحا کَش میکنه که برای دفعه های بعدی نره از سرور بگیرتش و از حافظه نهان خودش استفاده کنه.موضوع Cache-Control از موضوعاتی هست که میتونین راجع بهش مطالعه داشته باشین چون میشه با دستکاری خصیصه ها و پیکربندیش، این عمل کش کردن رو کاملا هدفمند و امنیتی تر(احراز هویت) باهاش برخورد کرد.Connection این فیلد وضعیت کانکشن رو مشخص میکنه. قبلا اشاره کردیم که HTTP از TCP یا UDP(در HTTP 3.0) برای ارتباط شبکه ای خودش استفاده میکنه. حالا سرور و کلاینت میتونند بعد از اولین ارتباط کانکشن tcp باز شده رو نگه دارند(با مقدار دادن Keep-alive به این فیلد) و نبندند تا هر بار به ازای هر درخواست، لازم به برقراری یک کانکشن جدید نباشه.Date        تاریخ و ساعتی که پیام شکل گرفته رو میگهPragma  این فیلد میتونه اثرات متعددی داشته باشه.اما بیشتر من دیدم برای معکوس سازی Cache-control به کار میره.خودم هم راستش خیلی دقیق راجع بهش نمیدونم.این کاربردش رو دیدم. Trailer           این فیلد همونطور که از نامش پیداست برای اطلاعات اضافی که توی درخواست در زنجیره زنجیره درخواست و پاسخ میخوایم استفاده میشه.فرض کنید یک امضای دیجیتال، مازاد بر احراز هویت.یک نمونه از Trailer هایی که میتونه باشه.Transfer-Encoding این فیلد بیشتر برای رمزگذاری یک جورهایی استفاده میشه.اصطلاحا بهش میگند یک فیلد HOP به HOP ئه.یعنی بین دو نود توافقی میشه.ربطی به خود ریسورس نداره.این رو حتما یادتون باشه.این رمزگذاری روی خود ترنسفر داره اتفاق میافته.اونم فقط بین دو نود.اگر چندین کامپیوتر باشند.هر کدوم میتونند Transfer-Encoding خودشون رو برای نود بعدی قرار بدند.مقدار های یا value های مختلفی داره که در بحث ما خیلی طولانی میشه.خودتون میتونید بیشتر بخونید.Upgrade      این فیلد همونطور که از اسمش پیداست، برای تغییر نسخه ی HTTP به کار میره یا تغییر پروتکل. معمولا درخواست ارتقا توسط کلاینت میره.ولی گاهی سرور کلاینت رو مجبور به ارتقا میکنه که اینجوری یک ریسپانس به کلاینت میده که مضمونش اینه که پروتکل رو تغییر بده. (426 Upgrade Required)  که بعد کلاینت درخواست دیگه ای باید بده.  Viaاین سرآیند توسط پروکسی ها پر میشه.بخواین ساده نگاه کنید.یک جورایی کارش رد یابی پیامه که داره از مسیر پروکسی به پیش میره. اصطلاحا پروکسی forward داریم و reverse. پروکسی بخواد پیامی رو تغییر بده کلا پروتکلش رو و ... از این فیلد برای رهگیری پیامش داره استفاده میکنه.        Warningاینم که وضعیت پیام رو میگه.هشدارهایی که در زمان درخواست و پاسخ رخ داده.این مطلب ادامه داره هنوز و من راجع به فیلد های هدر که مربوط به درخواست و پاسخ هست هم میگم و خواستم این نکته رو هم بگم که من هم مثل شما هنوز در حال یادگرفتنم.خوشحال میشم اگر نکته ای مازاد بر این بود یا اشتباهی من مرتکب شدم در کامنت ها بگین که همه استفاده کنند.</description>
                <category>آزاده خرسندنیا</category>
                <author>آزاده خرسندنیا</author>
                <pubDate>Mon, 08 Feb 2021 11:29:53 +0330</pubDate>
            </item>
                    <item>
                <title>پروتکل HTTP قسمت چهارم</title>
                <link>https://virgool.io/@az.khorsandnia/%D9%BE%D8%B1%D9%88%D8%AA%DA%A9%D9%84-http-%D9%82%D8%B3%D9%85%D8%AA-%DA%86%D9%87%D8%A7%D8%B1%D9%85-h198o276hprr</link>
                <description>طبق روال پست های پیشین یک یادآوری از آنچه تا کنون گفتیم.گفتیم پروتکل HTTP، به عنوان پل ارتباطی بین کلاینت و سروره که پیچیدگی های سخت افزاری و شبکه ای رو از این دو پنهان میکنه و کارشون رو راحت تر. کلاینت با مرورگرش با این پروتکل در تماس هست و زبانی که این دو، یعنی کلاینت و HTTP باهم صحبت میکنند، Request است! و سرور هم با نرم افزار IIS ای که روش نصبه یا هر نرم افزار وب سروری دیگه ای که غیر از IIS داره اینکارو براش انجام میده، با HTTP در ارتباطه و زبانی هم که این دو میفهمند و میتونند باهم صحبت کنند، Response ئه.در قسمت سوم راجع به URL صحبت کردیم و اینکه چطوری کلاینت به HTTP میفهمونه که درخواستی داره، تا HTTP هم براش ریسپانس بیاره، گفتیم از طریق URL این اتفاق می افته.ولی آیا URL همون درخواسته؟خیر!... URL شرط &quot;ضروری&quot; ولی &quot;ناکافی&quot; برای یک درخواست HTTP است. یعنی خودش به تنهایی یک Request نیست، ولی برای ایجاد Request، لازمه که یک URL ای بالاخره وجود داشته باشه، وگرنه HTTP علم ماورا طبیعی نداره و نمیفهمه که باید به کدوم سرور یا هاست بره که اصلا پاسخی از اونجا بیاره. پس خیلی ساده نقش URL رو مثل کد پستی برای اداره پست یا همون HTTP تصور کنید. اداره ی پست خودش بر اساس اون اطلاعات کد پستی، محموله رو تنظیم میکنه.فرمت کلی درخواست در HTTPفرمت کلی پاسخ در HTTPپروتکل HTTP یک فرمت کلی برای پیام هاش داره که استانداردشه. پیام هاش چه Request باشه و چه Response با همین فرمت خاص میره. منتها اگر محتویات داخل پیام رو نگاه کنیم، از روی جزئیات سطر آغازین و پارامتر های هدر، میشه فهمید این پیام نوعش درخواسته، یا پاسخ.آموزش های بسیار زیادی خوشبختانه در دسترس هست، حتی به زبان فارسی، که میشه رفت خوند و منم الان قصد ندارم یک آناتومی جامعی از این موضوع شرح بدم و تکرار مکررات از استاندارد و تئوری پارامترهاش بکنم. فقط قراره راجع به چیزهای مهمی که باید برای کارمون، یعنی کد نویسی بک اند یا حتی فرانت اند، بدونیم و دونستنش واجبه صحبت کنیم. برای من هیچ اهمیت نداره که HTTP بین Header و Body فاصله میندازه!به قول خارجی ها، It&#x27;s none of your business. این پروتکل سالهاست وجود داره و کارشم خوب بلده! پس بیایم وقتمون رو روی چیزهای مرتبط با کاره خودمون بزاریم. ما برنامه نویسیم و داریم کد مینویسیم. کدمون رو در نهایت روی هاست، یا سروری پابلیش میکنیم. اگر بخواهیم در چنین فضایی، یعنی وب، کد خوبی بنویسیم باید از دو بُعد به این کد نویسی خوب نگاه کنیم :1- خوده کُد، که بالاخره قاعده مند و شکیل و منطبق بر شی گرایی و هزار شرط دیگه که همه به بهتر بودنش و درجه ی اعتبار شما به عنوان برنامه نویس، کمک میکنه.2- فضایی که داره کُد ما اجرا میشه، که هرچی بیشتر شما این فضا رو درک کنین، عملکرد مطلوب تر و تضمین شده تری رو از کدتون میتونین ارائه بدین و وقتی هم میرین مصاحبه، تبحر خودتون رو بهتر نشون میدید.بنابراین بیایم از HTTP اون چیزهایی رو یاد بگیریم که ما رو بیشتر به بند دوم مسلط میکنه.به این سوال پاسخ بدیم که چی مهمه من برنامه نویس از HTTP بدونم که بتونم کد بهتری، حالا در هر فریم ورک تحت وب، بنویسم؟بیایم یک کمی با فضا آشنا بشیم.سرور یک پیرمرده ساکت، نسبتا بداخلاق و بی نهایت منضبطه. که سالهاست در یک اداره و با یک روتین کارمندی، کار میکنه. هیچ وقت بازنشسته نمیشه، مگر اینکه بمیره! ولی از وضعی هم که داره راضیه و به اهمیت کارشم واقفه. اتاقی که بهش دادند پره از قفسه های تا سقف، مملو از پرونده که هر کدوم از اون پرونده ها رو یک برنامه نویسی نوشته و گذاشته اونجا. کلا هم در تمام زندگی کاریش، با دو همکار در ارتباط بوده که با یکیشون  بابت کارش، بیشتر در تماسه، یک نرم افزار وب سروری که ما دات نت کارها معمولا به اسم IIS میشناسیمش. یکیش سیستم عامله که خیلی نمیبینتش ولی خب بالاخره میشناستش.شما برنامه نویس هم با این پیرمرد دارین کار میکنین، چون پرونده تون اونجاست.نرم افزار IIS و اون مامور HTTP که داره از شبکه رد میشه و درخواستها رو میده به IIS هم با این پیرمرد دارن کار میکنند. پس همه باید جوری کار کنین که منطبق با خلق و خوی سرور باشه.وگرنه سرور آدم بی حوصله و علافی! نیست که بخواد چیزی به کاره شما اضافه کنه.پروتکل HTTP کارشو خوب بلده.چون سالهاست که داره با این سبک پیرمردها کار میکنه. برای همین همیشه مهمترین چیزها رو در همون سطر اول درخواستش، مینویسه که زودتر سرور، بفهمه این پرونده یا درخواست زیره دستش چیه. اسم این داده ی اطلاعاتی مهم در درخواست،HTTP method یا در بعضی از منابع Verb یا فعل هست.حالا HTTP متد چیه؟ پیامی واضح و شفاف و بدون هیچ حاشیه چینی که به سرور بفهمونه این درخواست چیه؟ این بابا کلاینته چی میخواد؟ میخواد یک چیزی رو ذخیره کنه توی یکی از پرونده های قفسه ها، که اگر اینطوریه سرور بره برگه Body این درخواست رو بکنه و ببره توی پرونده قفسه مرتبطش بزاره. یا نه میخواد یک چیزی از توی قفسه ها براش بیارن و با پاسخ براش بفرستن.یا نه یک چیزی رو قبلا فرستاده، سرور براش ذخیره کرده، الان یک اصلاحیه میخواد روی اون بزنه.یا نه اصلا میخواد اون چیزی که قبلا فرستاده رو به کل باطلش کنه.شما هم از HTTP همین نکته رو به عنوان برنامه نویس یاد بگیرین. استفاده از HTTP متد های درست و به موقع در کدهاتون که بهتر بتونین، الان هیچ حضوری در اون اتاق ندارین و فقط پرونده تون اونجاست، به سرور بی حوصله و دقیق ما کمک کنین. پرونده تون براش یک پرونده خوانا باشه.سرور هم همیشه مهمترین مطلبی که لازمه به شفاف ترین و گویاترین حالت، چون حوصله توضیح به هیچ کس رو نداره توی همون سطر اول پاسخش مینویسه. ما بهش میگیم Status Code.حالا بیایم یک کمی از تصورات بیایم بیرون و علمی تر صحبت کنیم.پرکاربرد ترین متد های HTTP عبارتند از :GET / POST  / PUT / DELETE / PATCHتطبیق عملیات CRUD با متد های HTTPمتد GET برای خواندن داده استفاده میشه. درخواستی که IIS به سرور بده با سربرگ متد GET به این پیرمرد میفهمونه که این پرونده یا Request صفحه ی Body نداره.برای همین این درخواست ها بررسیشون برای سرور واضح و ساده است.در مقابل هر درخواست GET، سرور دو مدل پاسخ داره. یا مهر موفقیت آمیز میزنه که یعنی من پرونده رو پیدا کردم و گذاشتم توی صفحه ی Body ریسپانسم.مرورگر محترم از اونجا برش دار لطفا.یا مهر ناموفق میزنه که دیگه حساب کار دسته مرورگر میاد.این مهر برای موفقیت میخوره 200 ok.برای ناموفق باز سرور بسته به اتفاقی که توی اتاق افتاده چند مهر مختلف داره.یا میزنه 401 که بهش میگند Un authorization که به زبون به زبونی به مرورگر یا همون کلاینتی که این درخواست رو داده میفهمونه که تو دسترسی نداری به این پرونده چون هویتت برای من مشخص نبود. بهتره یک بار به سایت لاگین کنی و بعد درخواستت رو با یک توکن احراز هویت برای من بفرستی.یا مهر 403 یا Forbidden میزنه که آب پاکی رو روی دست کلاینت میریزه که تو اصلا سطح دسترسی به این محتوا نداری.برو پی کارت.یا مهر 404 میزنه که برای اکثر ماها آشناست. یعنی Not found که به کلاینت میگه یک وقت فکر نکنی، من از اون کارمندهای بی مسئولیتم که پرونده ارباب رجوع رو بررسی نکرده پس میفرسته!. خیر، من سرور پاشدم گشتم ولی پیدا نکردم.ببین چی رو اشتباه برای من فرستادی. یا شایدم اون برنامه نویس احمقی که این پرونده رو اینجا گذاشته یک اشتباهی کرده. من توی کاره سروریم زیاد دیدم!.یا گاهی هم مهر 405 میزنه که میگه من پرونده هه رو پیدا کردم، تو هم سطح دسترسی داشتی، احراز هویت هم شده بودی.ولی درخواستت رو اشتباه فرستادی. چون برنامه نویس بالای پرونده نوشته این پرونده فقط قابل ویرایشه.قابل ارسال شدن نیست. از سمت برنامه نویس بالاش صراحتا نوشته شده POST. این یعنی کلاینت نمیتونه به این اکشن یا متد با GET دسترسی داشته باشه.این از HTTP متده GET.برای اینکه مطلب طولانی تر نشه. متد های دیگه رو سریعتر بگیم.ما سه  متد ذخیره سازی داریم:POST   PUT  PATCHمتد POST برای ذخیره داده ی جدید به کار میره. مثل GET هم دو حالت برای پاسخ براش پیش نمیاد. یا موفق ذخیره میشه یا ناموفق.اگر موفق بود که کد 201 یا Create به ازاش سرور میده.اگر ناموفق بود کد های 401/404/ و 409 برمیگرده که این آخری یعنی 409 میگه که یک Conflict ای رخ داد. که یعنی داده ای که داری ذخیره میکنی همچینم جدید نیست جناب کلاینت، از قبل درج شده و موجود بوده.ببین چه اشتباهی کردی.متد PUT فرقش با POST برای سرور اینه که پیرمرد میفهمه این داده جدید نیست.وجود داره و میخواد ویرایش بشه.در مقابلش سرور یا کد موفقیت یا 200 ok رو میده.یا ناموفق که برای ناموفق یا مهر 204 یا No content میزنه که یعنی من محتوایی به این شکلی که تو قصد ویرایشش رو داری اصلا پیدا نکردم که بخوام درستش کنم.یا مهر های 404 و 405 که راجع بهش گفتیم.متد PATCH مثل PUT.پس چه کاریه؟...صد درصد باید یک فرقی داشته باشند.بله.فرقشون در اینه که با PUT کلاینت باید همه اطلاعات اون داده رو برای ویرایش بفرسته و سرور هم همه داده ها رو میگیره از درخواست و ویرایش میکنه. ولی PATCH نه. توی درخواست یک قسمتی از داده ارسال میشه و سرور هم فقط همون تیکه رو درست میکنه.یا مهر 200 ok میزنه که یعنی تونستم.یا کد های ناموفق 401/403/404 و 405.یک متد دیگه هم میمونه که مشخصه. DELETE.متد DELETE شبیه به GET ئه. Status کد هاشم شبیه به GET ئه.فقط 409 یا Conflict هم در زمره Status کدهاشه.و کلام آخر...به عنوان یک برنامه نویس.چیزی که از HTTP درخواست و ریسپانس باید درک بهش داشته باشین و روش فوکوس کنین و ازش استفاده کنین در کدهاتون، همین متد ها و استاتوس کد هاست. چون شما قادر هستید که با اینها کار کنید در کدتون و مثلا کاربرتون رو به جای مواجه شدن با پیغام های ناخوانا که قراره مرورگر یهو بندازه روی صفحه اش مثل 404! که همون پاسخ سروره، و کاربر شما هیچی نمیفهمه چی شد؟ چی کار شد؟ چرا اینطوری شد؟ با یک پیام فارسی و صفحه ی خوانا هدایت اش کنین. و از طرفی میتونین به عملکرد سرور در پیدا کردن و پاسخ دادن کمک کنید و از خطاها و تخلف های کلاینت ها برای دسترسی های غیرقانونی و ... جلوگیری کنید.راجع به این مباحث بیشتر صحبت خواهیم کرد. </description>
                <category>آزاده خرسندنیا</category>
                <author>آزاده خرسندنیا</author>
                <pubDate>Fri, 22 Jan 2021 19:18:12 +0330</pubDate>
            </item>
                    <item>
                <title>پروتکل HTTP قسمت سوم</title>
                <link>https://virgool.io/@az.khorsandnia/%D9%BE%D8%B1%D9%88%D8%AA%DA%A9%D9%84-http-%D9%82%D8%B3%D9%85%D8%AA-%D8%B3%D9%88%D9%85-gs4mhzhaqnn4</link>
                <description>پیش از آغاز بحث، یک مرور بر آنچه تا کنون اشاره کردیم بپردازیم.تا اینجا خیلی ساده، فهمیدیم که &quot;کلاینت&quot; (Client) و &quot;سرور&quot; (Server) از طریق دروازه های خودشون، یعنی &quot;مرورگر&quot; (Browser)  برای کلاینت و  &quot;IIS&quot; برای سرور، از طریق پروتکل HTTP و در قالب درخواست(Request) و پاسخ (Response) باهم ارتباط برقرار میکنند.همینطور گفتیم تا درخواستی نیاد، خود به خود از سمت سرور پاسخ نخواهد اومد.اما درخواست چطور عملی میشه؟ به عبارت بهتر ما چطور درخواست میدیم به سرور.پاسخش میشه از طریق URL.بیایم ساده ترین حالت رو فرض کنیم. شما به عنوان کلاینت، بعد از اینکه اتصالتون به اینترنت محقق شد، مرورگر خودتون رو باز میکنید و یک آدرس اینترنتی، مثلا www.youtube.com رو در قسمت URL مرورگرتون میزنید.اصولا URL از چند قسمت تشکیل میشه:قسمت اول : پروتکله. پروتکل های دیگری هم مثل HTTPS، FTP هستند.HTTPS برای ارتباط امن یا Secure استفاده میشه و FTP برای انتقال فایل از سرور.قسمت دوم، که در واقع ترکیبی از 3، 4 و 5، همه اش باهم Host یا Hostname (نام میزبان)، گفته میشه. هاست خودش از SubDomain، Domain و Top Level Domain یا به اختصار TLD تشکیل شده. البته به کل youtube.com هم دامین گفته میشه.یادآوری که این در واقع همون IP آدرسیه که به یک نام خوانا مپ شده.TLD ها دسته بندی موضوعی دامین رو مشخص میکنند. مثلا edu داره میگه که این سایت، یک سایت آموزشیه. یا gov میگه این سایت یک سایت دولتی است و ...بعد از TLD،اگر از port پیشفرض پروتکل استفاده نمیکنیم، باید شماره پورت رو هم بیاریم.  پورت پیشفرض HTTP برابر است با 80 و برای HTTPS برابر است با 443. اگر از این دو پورت داریم استفاده میکنیم لازم نیست در URL شماره پورت رو بنویسیم وگرنه باید با : شماره پورت رو هم در آدرس بیاریمقسمت ششم، Path یا مسیر، که در واقع محل قرار گیری فولدری این صفحه یا Resource رو در سرور مشخص میکنه. اگر صفحه HTML یا Resource ای که ما بهش URL دادیم، در فولدر اصلی اون وبسایت باشه، Path نداره.ولی اگر در زیرشاخه های اون فولدر اصلی در سرور باشه، Path مسیر اون زیرشاخه رو نشون میده.از علامت ؟ به بعد، در واقع مقادیریه که ما داریم به سمت سرور به عنوان پارامتر ارسال میکنیم. که این مقادیر یا پارامتر ها، به شکل name - value یا عنوان - مقداری فهرست میشوند که اصطلاحا بهشون Query string یا رشته پرس و جو، میگن. ما میتونیم بیشتر از 1 دونه Query string یا پارامتر نام- مقداری داشته باشیم که در این صورت با &amp; از هم جدا میشوند. مثلا فرض کنید من در سایتی دارم ثبت نام میکنم و بعد با ثبت، دارم به مسیر یک متد( با دید MVC، یک اکشن) در سرور با درخواست خودم هدایت میشوم که اطلاعات من به شکل Query string بهش ارسال میشه : name=azadeh&amp;family=khorsandnia.خب، این از URL.لازم به ذکر است که URL در اختیار کلاینت نیست. اصولا URL ها رو نمیتونند کلاینت ها به دلخواه خودشون تنظیم کنند.URL باید وجود داشته باشه و وجود داشتنشم در سروره و کلاینت دقیقا باید به همون آدرسی که در سمت سرور براش مشخص شده، درخواست بده. وگرنه کلاینت هیچ واکنشی جز خطا که حالا راجع بهش صحبت میکنیم، نمیبینه.اما یک قسمتی در آدرس یا URL هست که در اختیار کلاینته و بعد از کوئری استرینگ با # جدا میشه و بهش  Fragment یا در بعضی منابع Anchor، میگن. اینکه میگم در اختیار کلاینته، یعنی این بخش بندی ها با درخواست اولیه به سمت کلاینت میاد و در مرورگر هست و مرورگر داره کنترل میکنه. در سایت هایی که صفحات بزرگی دارند، طراحان میتونند تقسیم بندی هایی برای صفحه مشخص کنند که اصطلاحا بهشون لنگر میگن، و این بخش بندی ها سمت کلاینت میاد و با کلیک کاربر روی صفحه، بلافاصله به اون مکان میره و دیگه بابتش درخواستی به سرور نمیره.</description>
                <category>آزاده خرسندنیا</category>
                <author>آزاده خرسندنیا</author>
                <pubDate>Tue, 19 Jan 2021 19:15:34 +0330</pubDate>
            </item>
                    <item>
                <title>پروتکل HTTP قسمت دوم</title>
                <link>https://virgool.io/@az.khorsandnia/%D9%BE%D8%B1%D9%88%D8%AA%DA%A9%D9%84-http-%D9%82%D8%B3%D9%85%D8%AA-%D8%AF%D9%88%D9%85-io4avxpdprbg</link>
                <description>در قسمت اول، گفتیم HTTP ، پروتکل ارتباط بین Client و Server است که با استفاده از اون، این دو میتوانند با هم تبادل داده داشته باشند و تبادل داده هم در HTTP با Request و Response اتفاق می افته. HTTP یک رکوئست از کلاینت میگیره، اون رو درشبکه حمل میکنه، به سرور میده و در ازاش از سرور یک ریسپانس دریافت میکنه و مجدد به کلاینت برمیگردونه.اما قبل از اینکه بیشتر وارد این پروتکل بشیم باید چند تا مفهوم برامون روشن باشه.شاید بدیهی به نظر میاد ولی بهتره که باز هم بهشون اشاره ای بکنیم:1- مرورگر یا Browser : یک نرم افزاره که به ما امکان دسترسی به صفحات HTML و اطلاعات وب رو میده.2- عامل کاربر یا User agent : وقتی مرورگره کلاینت، یک درخواست به سمت سرور میفرسته، همراه باهاش، یک سری اطلاعات هم از کاربر به سرور میده. مثل اینکه خودش چه مرورگری هست، روی چه سیستم عاملی داره استفاده میشه، ورژن HTTP که داره ازش استفاده میکنه چیه و غیره. این اطلاعات مخصوصا در سایت های آمارگیر استفاده میشه و برای برنامه نویسان هم ارزش بالایی داره. البته چون داره از سمت کلاینت میاد، قابل دستکاری هم هست. برای همین خیلی قابل استناد و مطمئن نیست.3- پروتکل TCP و UDP : گفتیم خود HTTP یک پروتکله. در این پروتکل، برای ارتباط بین سرور و کلاینت، از پروتکل های انتقال داده استفاده کرده که مهمترین این پروتکل ها TCP/IP است. از HTTP 3 به اینور، از پروتکل UDP استفاده شده.حالا فرق این دو در چیه؟ پروتکل TCP بین دو کامپیوتر در یک شبکه، به این شکل عمل میکنه که درخواست یا Request رو به بسته های استاندارد خودش میشکنه و این بسته ها رو به شکل ترتیبی، و پشت سره هم میفرسته.منتها در ازای هر بسته منتظر یک پاسخ از سمت سرور هم هست. یعنی ارسال بسته ی بعدی،منوط به تاییدیه دریافت بسته ی قبلیه. این یک حسن داره و اینکه این پروتکل تضمین میکنه که درخواست کامل ارسال میشه. اما یک عیب داره و اون اینکه اگر بسته ای بنا به هر دلیل گم شد وسط راه یا نرسید، نمیاد مابقی بسته ها رو بفرسته و ارسال همونجا متوقف میشه. پروتکل UDP فرقش با TCP در همین قسمته که UDP اگر بسته ای مفقود شد،کماکان ارسال رو ادامه میده و این ترتیبی پشت سرهم ارسال رو رعایت نمیکنه و در نهایت، دوباره بسته های مفقود شده رو ارسال میکنه. این حسنش همینه که سرعت به شدت میره بالا، مخصوصا در ارتباطاتی مثل لایو های اینستاگرام که سرعت بسیار مهمه، خیلی اثر داره. ولی بدیش اینه که تضمینی دیگه برای ارسال همه ی اطلاعات نداره. 4- آی پی یا IP : هر کامپیوتری در شبکه اینترنت، چه Router یا مسیریاب باشه، چه سرور، چه کلاینت، چه پروکسی،فرقی نمیکنه، هر کامپیوتری در وب دارای یک شناسه ی منحصر به فرده که از بقیه متمایزش میکنه.5- آدرس یا URL : هر فایل یا محتوایی که در اینترنت قرار داره، حتما باید دارای یک URL یا آدرس منحصر به فرد باشه. 6- ریسورس یا Resource : به هر محتوایی که ما از طریق URL بهش دسترسی داریم، Resource گفته می شود.7- فضای نام یا DNS : گفتیم کامپیوتر ها در وب دارای IP یکتا هستند. اما میشه یک نام و یک دامنه رو به شکل یک آدرس یا URL به یک IP نسبت داد که خوانایی دسترسی بهش بیشتر بشه. یعنی آدرس IP مثل X.X.X.X رو میشه گفت معادل MyWebSiteName.Com است.این به چه شکله؟ یک سری سرورها هستند که کارشون مثل دفترچه تلفنه!. در واقع یک دیتابیس عظیم از نام ها و آی پی ها دارند که میگه هر آی پی معادل چه نامیه. از این دست سرورها در تمامی جهان زیاده و اینها بهمدیگه هم متصل هستند. وقتی شما در یک شرکت هاستینگ فضای نامی رو که خریداری کردید رو، ثبت میکنید، بعد از مدتی تقریبا در تمامی این DNS سرورها، در سرتاسر جهان این نام در دیتابیس هاشون ثبت میشه و اینطوریه که IP خاصی،معرف یک نام مشخص میشه که دیگه کسی نمیتونه اون نام رو برای خودش بزنه.وقتی هم که شما در یک مرورگر، ادرسی رو میزنید، مرورگر هم برای رفتن به اون آدرس بعد از اینکه Cache خودش رو چک کرد که اگر قبلا رفته، زودتر سایت رو لود کنه، اگر پیدا نکرد میره سر وقت همین DNS سرورها. البته سلسله مراتبی داره که در بحث نمیگنجه.8 - آی آی اس یا IIS : راه ارتباطی کاربر کلاینت با اینترنت از طریق نرم افزاریه به اسم مرورگر. از اون سمت هم یک اپلیکیشنی روی سرورها نصبه که بهش میگن IIS و این میشه راه ارتباطی سرور و اصلا سرور کردن یک کامپیوتر!. اگر کامپیوتری IIS نداشته باشه، پس نمیتونه نقش سرور رو ایفا کنه.قبلا هم اشاره کردیم که کامپیوتر کلاینت دروازه ارتباطیش با HTTP از طریق مرورگر باز میشه و برای سرور از طریق IIS.9- پروکسی یا Proxy : سرورهای واسطی هستند که سره راه سرور و کلاینت قرار میگیرند و هدف  از قرار گیریشون هم یا احراز هویت برای کاربرانه یا تغییر هویت اونها برای دور زدن فیلترینگ.10- درخواست و پاسخ یا به عبارتی Request و Response : پروتکل HTTP، ارتباط بین سرور و کلاینت رو با استفاده از Request و Response هندل میکنه. به درخواست های سمت کلاینت میگن Request و به پاسخ از سمت سرور به کلاینت میگن Response. هر دوتاشونم یک بخش Header دارند که اطلاعات بسیار مهمی درباره اینکه چی هستند و چی میخوان و چی کاری قراره انجام بگیره به طرفین میرسونه.11- کوکی یا Cookie : که هم سمت سروره و هم سمت کلاینت و هدفشم تسریع در مراجعات بعدیه. به این شکل وقتی کاربر از سایتی بازدید میکنه، فایل متنی به اسم کوکی حاوی یک سری اطلاعات از اون بازدید رو در خودش نگه میداره و در دفعات بعدی و رکوئست های بعدی اون اطلاعات رو هم میفرسته.برای همینه که گاهی به سایتی که لاگین میکنید، میبیند که حتی اگر مرورگرتون رو ببندید و مجدد باز کنید، هنوز هم لاگین هستید.نکته ی مهم اینه که نباید کوکی با Caching فایل های CSS و JS در سمت کاربر اشتباه گرفت.</description>
                <category>آزاده خرسندنیا</category>
                <author>آزاده خرسندنیا</author>
                <pubDate>Thu, 14 Jan 2021 18:32:56 +0330</pubDate>
            </item>
                    <item>
                <title>پروتکل HTTP</title>
                <link>https://virgool.io/@az.khorsandnia/%D9%BE%D8%B1%D9%88%D8%AA%DA%A9%D9%84-http-l5fdnbhhj3kd</link>
                <description>اگر بخواهید به عنوان یک برنامه نویس بک اند کار کنید، فرقی نمیکند که با چه زبانی کد مینویسید. از اصلی ترین و پایه ترین چیزهایی که باید بدانید پروتکل HTTP است.همه ما میدانیم اینترنت در واقع شبکه عظیمی از شبکه های کامپیوتری می باشد که از دو بُعد قابل بررسی است. یک بُعد آن زیرساختی است که در واقع نحوه ی اتصال فیزیکی و پیاده سازی این شبکه ها را هدایت میکند. ولی بُعد دیگر آن، قوانین، استانداردها و قواعد حاکم بر این زیرساخت است که پروتکل HTTP یکی از اصلی ترین ارکان آن می باشد.هدف اینترنت یا همین شبکه ی عظیم از شبکه های کامپیوتری، امکان &quot;ارتباط داشتن کامپیوترها&quot; بدون محدودیت های جغرافیایی، تکنولوژی، مقیاسی و غیره، بهم دیگر است. منظور از ارتباط داشتن کامپیوترها هم ، &quot;تبادل داده&quot; می باشد. حالا این تبادل داده میتونه یک عکس، سند HTML و یا چیزی از این دست باشه، یا فقط یک Status Code ساده که نشان دهنده موفقیت یا عدم موفقیت یک عملیات، در یکی از این کامپیوترها هست. اما نکته ی مهم اینه که تبادل داده یک پروسه خودکار نیست و باید حتما طی یک &quot;درخواست&quot; و &quot;پاسخ&quot; اتفاق بیفته. بنابراین، اگر دو کامپیوتر، میخواهند باهم ارتباطی از جنس تبادل داده داشته باشند، باید حتما یکی از اینها درخواست بده و دیگری پاسخ اون درخواست رو. درخواست کننده میشه &quot;کلاینت&quot; و پاسخ دهنده &quot;سرور&quot;.اما HTTP در این فضای درخواست و پاسخ نقشش کجاست؟برای این پاسخ میتونیم فضای وب رو شبیه سازی کنیم با یک  داروخانه متشکل از انواع و اقسام دارو ها که هر کدومشون در یک موقعیت فیزیکی و با یک چیدمان خاص در قفسه ها تقسیم و قرار گرفتند. داروخانه، حکم اینترنت رو داره و دارو همون داده است که داخل قفسه های مختلف که در واقع سرورهای ما یا همون کامپیوترهای پاسخ دهنده در موقعیت های مختلف هستند، قرار داره. Client یا مشتری وارد داروخانه میشه و فقط یک نسخه دستشه که توش دارو یا همون Request اش رو نوشته و اصلا هم نمیدونه که کدوم قفسه و کجا این دارو قرار داره و این موضوع اصلا براشم اهمیتی نداره. اون فقط یک چیز میخواد، دارو! اون سمت، یعنی پشت پیشخوان، هم دارو قرار داره که درون یک قفسه یا به عبارتی، هارد یک Server واقع شده که باید به مشتری به عنوان پاسخ داده بشه. حالا شاید بفهمید که پروتکل HTTP در این سناریو کیه؟ متصدی داروخانه.داده موجودیت خامه. که قدرت جابه جایی نداره و فقط از نظر فیزیکی درون هارد یک کامپیوتر قرار داره. کامپیوترها هم فقط دروازه های درخواست و پاسخ بابت اون داده رو باز میکنند. خودشون مسئول این نقل و انتقال نیستند. دروازه ی Client مرورگرشه و دروازه ی Server ، نرم افزار وب سروری که روش نصبه. جاده ی متصل کننده این دو دروازه به منظور حمل و انتقال این داده، پروتکل HTTP است.پروتکل HTTPاگر بخواهیم یک جمع بندی داشته باشیم، گفتیم هدف اینترنت، ارتباط بین کامپیوترها است. این ارتباط هم خود به خودی نیست و طی پروسه درخواست و پاسخ اتفاق می افته. پس همیشه در هر ارتباطی در اینترنت، یک درخواست کننده یا Client وجود داره و یک Server که پاسخ دهنده است. دست آورد این ارتباط بین کلاینت و سرور، هم داده است. حالا داده یا شامل یک فایل فیزیکی میشه یا فقط یک Status Code ساده رو میخواد برگردونه.پروتکل HTTP با سرور و کلاینت سر و کار داره. کارش چیه؟ قراره از Client درخواست بگیره و به سرور برسونه و  از اون سمت، از Server ، پاسخ اون درخواست رو بگیره و مجدد به کلاینت برگردونه. هدفی هم دنبال میکنه ، همین تضمین رساندن درخواست و پاسخ به مبدا و مقصد مشخصه خودش، البته در کوتاهترین و امن ترین حالت ممکنه. البته این هدف آرمانی پروتکل HTTP ئه!. به منظور این هدفم، مجبوره از یکی از پروتکل های انتقال داده پیروی کنه. مثل TCP یا UDP.در پست های بعدی با ساختار و نحوه ی کار HTTP بیشتر آشنا خواهیم شد.</description>
                <category>آزاده خرسندنیا</category>
                <author>آزاده خرسندنیا</author>
                <pubDate>Wed, 13 Jan 2021 02:11:57 +0330</pubDate>
            </item>
            </channel>
</rss>