<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>نوشته های solmaz.oskouie (سولماز اسکویی)</title>
        <link>https://virgool.io/feed/@solmaz.oskouie</link>
        <description>Java ( web)  developer. Cats lover. a left-handed(southpaw) girl . ISTJ</description>
        <language>fa</language>
        <pubDate>2026-04-14 19:58:24</pubDate>
        <image>
            <url>https://files.virgool.io/upload/users/6684/avatar/6HDge4.jpeg?height=120&amp;width=120</url>
            <title>solmaz.oskouie (سولماز اسکویی)</title>
            <link>https://virgool.io/@solmaz.oskouie</link>
        </image>

                    <item>
                <title>من میخواهم دورکار باشم اما ...</title>
                <link>https://virgool.io/@solmaz.oskouie/%D9%85%D9%86-%D9%85%DB%8C%D8%AE%D9%88%D8%A7%D9%87%D9%85-%D8%AF%D9%88%D8%B1%DA%A9%D8%A7%D8%B1-%D8%A8%D8%A7%D8%B4%D9%85-%D8%A7%D9%85%D8%A7-zjojx6jntnrw</link>
                <description>دورکاریبیشتر از یک سال و نیم از ظهور و همه گیری کرونا در همه سطوح زندگی مان چه فردی چه اجتماعی گذشته . وقتی به این مدت زمان سپری شده نگاه می کنیم در بیشتر مواقع چه در سطح  زندگی فردی چه زندگی اجتماعی شاهد یک نوع رفتار کج دار و مریز هستیم . این رفتار کجدار و مریز رو توی محیط کار هم بشدت شاهدیم  .  تعداد خیلی کمی از شرکتهای ایرانی  توانستند همگام با تغییرات دنیای مدرن ، سبک کاری موسوم به دورکاری رو مدیریت صحیح کرده و نیروهایشان رو درحین دادن حق انتخاب برای دورکاری یا حضور در محل یا ترکیبی  راضی نگه دارند . سوالی که از خیلی وقت پیش ذهنم رو ازار میداد و این روزها بیشتر اینکه :دورکاری چه میزان خوبه و چه کسی /نهادی میتواند این میزان مناسب دورکاری رو تشخیص داده و  مدیریت کند؟ببینید  اول کار اجازه بدید روشن کنیم که بحث سر بودن یا نبودن کرونا نیست الان بحث سر سبک جدیدی از کار هست و صد البته سبک جدیدی از ارتباط کاری افراد باهمدیگه .من یک برنامه نویس شاغل در یک شرکت نسبتا بزرگ هستم  و شرکتم تمام هم و غمش در راضی نگه داشتن نیروی کارش هست . مدل ترکیبی  دورکاری و حضور در شرکت  تقریبا جزو فرهنگ شرکت شده ولی هنوز مثل خیلی از شرکتهای فعال در حوزه High tech نتوانسته  این مدل سبک کاری رو درست مدیریت کنه .هنوز باید ستاد کرونا تعیین کنه ما چن روز در هفته می توانیم دورکار باشیم . مثلا این روزها ما می توانیم دوری کاری کنیم  اما در شرکت بازه و افرادی که به هر دلیلی نمی توانند یا نمی خواهند از منزل کار کنن می توانند  سرکار بروند . من یه نیروی کار مهاجر به تهران هستم و دوری از خانواده و زندگی در شهر دیگه برایم از نظر روانی بار سنگینی تحمیل می کنه .  قبل از کرونا خوانواده ام بین شهر خودمون و تهران در رفت امد بودند درنتیجه بار روانی این  موضوع برایم کمتر ملموس بود ولی  وقتی کرونا آمد و رفت امدها سخت تر و محدودتر شد و از اون طرف همین سبک ترکیبی دورکاری - حضور در شرکت باعث شد این بار روانی  چن برابر بشود ( تصور کن ۴ روز در هفته توی یه اپارتمان تک و تنها کار و زندگی کنی ) . امیدوارم بودم کرونا باعث شود من به سبب نوع و ماهیت کارم بتونم ازادانه بین حضور فیزیکی در محل کار و یا کار از منزل  انتخاب کنم . به عنوان مثال این روزها  نوع کار و تسک های من طوری هست که از خونه خیلی بهتر می توانم تمرکز کرده و کار کنم و صد البته کنار خونواده ام هم باشم . من این روزها بجای ۹ ساعت شاید ۱۰ حتی بیشتر هم کار می کنم برای کاری که انجام میدهم نیاز به مطالعه کتاب جدید با مفاهیم جدید ( جدید برای من ) دارم و این امر محقق نمیشود مگر اینکه بین کارهای فورس و روزانه ام و این موضوع مطالعه  یک مدیریت زمان داشته باشم . گاها صبحها از ساعت ۷ شروع به مطالعه می کنم تا ساعت ده که جلسه روزانه بین بچه های تیم مون هس  و بعد تا زمان ناهار کارهای فورس و تسک هایی که سمتم میاد و باید در یک زمان محدود انجام داده و تحویل دهم و گاها این مورد تا پایان وقت اداری کاریم طول می کشه و من مجبورم  با فاصله کمی استراحت  کار مطالعه و یادگیری مبحث جدید رو تا پاسی از شب ادامه دهم . راستش ، دروغ چرا! اصلا هم مجبور نیستم با شوق و اشتیاق کامل انجام میدهم . من الان در این مقطع زمانی تمایلی به شرکت در کارها و سرگرمی های گروهی شرکتی ندارم اما  حین مطالعه کتاب و البته همزمان اعمال اون ها روی پروژه شرکت  نیاز دارم با همکاران  باتجربه ام که در واحدهای دیگه شرکت مشغول بکار هستن  کانکت بشم و باهاش تبادل اطلاعات و تجربه کنم تا بتوانم هم  ارزش افزوده ای در پروژه و محصولی که دستم هس ایجاد کنم  هم در کار تیمی، دانش و تجربه ام رو به اشتراک بزارم . مثل هر انسان دیگه ای همیشه توی این حالت نمی تونم و نمیخوام بمونم بعد از یه مدتی بدن ، روح و روان و ذهن من حتما نیاز به برقراری رابطه صورت به صورت انسانی خواهد داشت  نیاز به همصحبتی ها و گپ های  سرمیز ناهار و عصرونه و ..  در محیط کار خواهد داشت . حتی گاهی پیش خواهد امد دچار روزمرگی شده و نتونم  با وجود حضور فیزیکی در محل کار بخوبی تمرکز کنم و درنتیجه خروجی مفیدی نخواهم داشت . خب مشکل کجاست ؟مشکل دقیقا جایی برای من نوعی پیش میاد که عامل خارجی درست در موقعی که من در بهترین حالت خودم هستم منو مجبور به تغییر سبک کاری می کنه:  دورکاری ها تموم شد  باید حداقل دوم سوم روزهای کاری رو در شرکت حضور داشته باشید . یا برعکس  بخاطر شیوع کرونا  فلان مراسم و دورهمی کنسل شد و  باید تا حد ممکن دورکاری کنیم . درسته بخاطر وجود این بیماری مسری نمی شود با جان ادمها و سلامتی اونها بازی کرد . سوال  من اینکه وقتی من نیروی کار میتوانم از خونه کار کنم و بهترین خروجی خودم  رو داشته باشم واقعا چه نیازی به حضور فیزیکی در محل کار هست ؟درحالی که در اکثر کشورهای اروپایی و امریکایی حتی با وجود تزریق واکسن و برگشت تدریجی زندگی به روال قبلی  این سبک جدید کاری یعنی دورکاری و کار از منزل توسط خیلی از شرکتهای High Tech  برای کارمندانشان  اختیاری شده و این تصمیم رو به عهده خود کارمند میزارند که خودش تصمیم بگیره  از خونه کار کنه یا در شرکت حضور فیزیکی داشته باشه . و مهمتر از همه ، تمام هم و غم بخش منابع انسانی شرکتها در طراحی شیوه ها و  متدهای جدیدی از ارتباطلات انسانی و دورهمی های دیجیتالی هس. ببینید من کارشناس یا متخصص  روابط انسانی یا هرچیز دیگه نیستم من فقط از منظر خودم و تجربه یک و نیم  ساله خودم از این سبک زندگی و کار اینجا به اشتراک گذاشتم و قبول دارم که شخصیت انسانها متفاوت و رنگارنگه. برای برخی از مردم حضور در محیط سنتی کار ، خروجی بیشتری هم از نطر کاری و مالی و مهم تر از همه روانی داره  اما برای برخی مردم ،حضور توی یه اتاق ساکت و داشتن تمرکز بالا به دور از هرگونه  تشریفات کاری و انسانی  خروجی بالاتری داره. برخی از افراد بخاطر شرایط زندگی متاهلی و داشتن بچه شاید نتوانند در منزل خروجی بهتری داشته باشند و علیرغم تمایل شون به دورکاری مجبورن حضور فیزیکی در محل کار داشته باشند . یا مثلا من دوست بسیار باسواد و متخصص در حوزه برنامه نویسی  دارم که با وجود تخصص و سواد بالا الان خونه نشین شده چرا ؟ برای اینکه اون اوایل همه گیری کرونا به مدت یه ماه تمام درگیر این ویروس منحوس شد و از همون موقع ترس از این بیماری و درگیر شدن دوباره خودش و خونواده اش و صد البته وسواس فکری که به سراغش اومده امکان حضور در محل کار رو نداره . از اون طرف برخی شغل ها بخاطر شرایط و قوانین حاکم برکار امکان دورکاری براشون فراهم نیست . هر کسی برحسب شرایط روحی و روانی و جسمی و خونوادگی و مالی خودش فکر می کنه بهترین سبک کاری در چه دوره ای چی باشه . دنیا به سمت سفارشی شدن در همه سطوح میره (خوب یا بدش رو نمیدونم ) . در مورد سبک کاری جدید هم به نظرم ماهم باید تجدید نظر کلی در همه سطوح مدیریتی و منابع انسانی و شخصیتی و ... داشته باشیم .</description>
                <category>solmaz.oskouie (سولماز اسکویی)</category>
                <author>solmaz.oskouie (سولماز اسکویی)</author>
                <pubDate>Sun, 25 Jul 2021 20:43:59 +0430</pubDate>
            </item>
                    <item>
                <title>فهمیدن زمان پاک شدن یک آبجکت از حافظه در جاوا</title>
                <link>https://virgool.io/CodeLovers/%D9%81%D9%87%D9%85%DB%8C%D8%AF%D9%86-%D8%B2%D9%85%D8%A7%D9%86-%D9%BE%D8%A7%DA%A9-%D8%B4%D8%AF%D9%86-%DB%8C%DA%A9-%D8%A2%D8%A8%D8%AC%DA%A9%D8%AA-%D8%A7%D8%B2-%D8%AD%D8%A7%D9%81%D8%B8%D9%87-%D8%AF%D8%B1-%D8%AC%D8%A7%D9%88%D8%A7-fweghiuwgbvk</link>
                <description>در جاوا امکان مدیریت مستقیم حافظه توسط برنامه نویس وجود نداره و این وظیفه رو یک ساب سیستمی بنام Garbage Collector برعهده داره . البته متدهایی چون  System.gc();
وجود داره که میتونید باهاش Garbage collector رو صدا بزنید تا عمل پاکسازی حافظه رو انجام بده ولی هیچ تضمینی برای  حرف گوش کن بودن اون وجود نداره حتی فراخوانی مستقیم متد finalize باعث نمیشه یک آبجکت به دستور ما از حافظه پاک بشه . کلا در این زمینه دست برنامه نویس برای  صادر کردن دستورات مستقیم بسته است ! فرض کنید میخواهیم زمان پاک شدن یک آبجکت از حافظه رو بدونیم تا بعدش یک کاری رو انجام بدیم مثلا فرض کنید میخواهیم یک حافظه کش داشته باشیم که آبجکت رو داخل اون ذخیره کنیم و هر موقع پاک شد دوباره از نو cache ش کنیم چیکار باید بکنیم ؟یا یک آبجکتی داریم که خیلی بزرگه مثلا یک تصویر خیلی بزرگی هس که میخواهیم ازش فقط یکی در حافظه لود شده باشه و هر موقع پاک شد دوباره یکی از اون بسازیم و  توی حافظه لود کنیم چیکار باید بکنیم ؟جواب این سوال رو اگه بخواهیم با دانش پایه ای جاوا جواب بدهیم و سراغ ابزارهای مدیریت و مانیتورینگ منابع حین اجرا مثل JMX و JConsole  نریم  این است :PhantomReferenceدر واقع PhantomRenference یک ارجاع به آبجکتی است که  توسط Garbage Collector  از حافظه heap جمع اوری شده و الان داخل یک صف بنام  ReferenceQueue قرار داره و منتظره تا ما دستی ( به کمک کد ) اونو حذف کنیم در واقع اثر و ردپای اونو پاک می کنیم . برای اینکه بدونیم مکانیسم انجام اینکار چطور است   یک مثال کوچیک کار می کنیم من این تیکه کد رو از گیت هاب برداشتم  که متعلق به یک پروژه بود .public class TestPhantomRef {

    @Test
    public void testPhantomRef() throws Exception {
        SoftCache&lt;String, byte[]&gt; cache = new SoftCache&lt;&gt;();
      1-  byte[] bigImage = new byte[64 * 1024];
        String key1 = &amp;quotbigImage&quot;
     2-   ReferenceQueue&lt;byte[]&gt; queue = new ReferenceQueue&lt;&gt;();
   3-     PhantomReference&lt;byte[]&gt; watcher = new PhantomReference&lt;&gt;(bigImage, queue);
        cache.checkin(key1, bigImage);
        Assert.assertEquals(bigImage, cache.checkout(key1));
        Assert.assertNull(cache.checkout(key1));
        cache.checkin(key1, bigImage);
        int i = 0;
        while (watcher != queue.poll()) {
            String key = &amp;quotkey_&amp;quot + i;
            byte[] value = new byte[64 * 1024];
            cache.checkin(key, value);
            i += 1;
        }
       
        System.out.println(&amp;quotcurrent size of cache: &amp;quot+cache.getCurrentSize());
        Assert.assertNull(cache.checkout(key1));
  
    }
}ابتدا یک آبجکت بنام bigImage ایجاد می کنیم ( خط شماره یک) فرض می کنیم این یه ابجکتی ست که میخواهیم زمان پاک شدنش از حافظه رو بدونیم . بعد برای اینکه بتونیم زمان پاک شدنش از حافظه رو بدونیم براش یک ارجاع از نوع PhantomReference میسازیم (خط شماره سه ) نحوه ساخت یک PhantomReference اینطوری است که دوتا ورودی می گیرد یکی آبجکتی که میخواهیم زمان پاک شدنش از حافظه رو بدونیم و دیگری یه صف که وقتی Garbage collector اونو حذف کرد میندازه داخل این صف (خط شماره ۲)  که بعدا ما بتونیم با چک کردن صف بفهمیم این آبجکت ما مرده و الان جسدش اینجا قرار داره و دست مارو می بوسه تا ببریم رسمی خاکش کنیم . در کد بالا  این آبجکت رو میخوایم  داخل یک کش ذخیره می کنیم بعد یه  مدت زمانی میریم سراغ کارهای دیگه ( مثلا در بدنه حلقه while میاد   داخل اون کش آبجکتهای دیگه ای هم ذخیره می کنه  و مدام چک می کنه کی چیزی که از صف پول میشه همون ابجکت  شبح ما هس به بیان دیگه کی ابجکت ما توسط اشغال جمع از حافظه حذف شده ،به محض اینکه ابجکت شبح  رو پول کرد از حلقه میاد بیرون ) . حالا اگه داخل کش رو بررسی کنیم اثری از اون ابجکت نیس! حال  میتونیم مثلا دوباره همون آبجکت رو بسازیم و داخل کش ذخیره کنیم یا هر کار دیگه ای که دلمون میخواد. ته نوشت : همون طور که میدونید آبجکت ها در داخل حافظه Heap ذخیره می شوند و و برای اینکه برنامه نویس داخل کدش  بتونه به اونا دسترسی پیدا کنه و دستکاری شون کنه نیاز به متغیر رفرنس به اونا داره که معمولا این reference variable ها درجای دیگه ای بنام stack ذخیره می شوند در جاوا چند نوع رفرنس به ابجکت ها داریم :Strong referenceSoft reference weak referencephantom referenceوقتی به صورت عادی یک آبجکتی رو با عملگر new ایجاد می کنیم یک رفرنس از نوع strong ایجاد می کنیم :Cat cat=new Cat();در اینجا رفرنس cat از نوع strong است  وقتی میخواهیم موقعی که باخطای outOfMemoryError  روبه رو شدیم آشغال جمع کن  اول سراغ یک سری خاص از آبجکت ها بره  اون موقع آبجکتهایی که فکر می کنیم اگه از حافظه پاک بشن مشکلی برامون ایجاد نمی کنن  رو بهشون ارجاعی از نوع Soft میدیم  . در واقع آبجکت هایی که ارجاعی از نوع soft داشته باشند فقط موقعی پاک میشوند که هیچ ارجاعی از نوع strong نداشته باشند و نیز حافظه heap  کافی برای ایجاد آبجکت جدید موجود نباشد . اگه برای آبجکتی ارجاعی از نوع weak تعریف کنیم  اون آبجکت در دور بعدی که آشغال جمع کن  اجرا میشه پاکش خواهد کرد . برای ساخت ارجاعی از نوع soft و... باید از کلاس های  پکیج java.lang.ref استفاده کنیم. که خب برای اهداف خاصی طراحی شدند و معمولا توی یه پروژه نرمال چنین ارجاع هایی رو به ندرت خواهیم دید.  </description>
                <category>solmaz.oskouie (سولماز اسکویی)</category>
                <author>solmaz.oskouie (سولماز اسکویی)</author>
                <pubDate>Sat, 23 Jan 2021 21:08:14 +0330</pubDate>
            </item>
                    <item>
                <title>مساله Inject کردن prototype bean درsingleton bean در Spring</title>
                <link>https://virgool.io/@solmaz.oskouie/%D9%85%D8%B3%D8%A7%D9%84%D9%87-inject-%DA%A9%D8%B1%D8%AF%D9%86-prototype-bean-%D8%AF%D8%B1singleton-bean-%D8%AF%D8%B1-spring-cdle4qbeqxvq</link>
                <description>وقتی شما با فریم ورک هایی چون Spring کار می کنید سعی می کنید تا جایی که می تونید از کلیدواژه (اپراتور) new کمتر استفاده کنید برای ساخت آبجکت جدید و این کار رو می سپارید به دست Big Brother یعنی فریم ورک اعظم !چرا ؟ برای اینکه اکثر فریم ورک های مدرن براساس یکسری ویژگی ها ساخته و پیاده سازی می شوند تا کار برنامه نویس و توسعه کد را ساده کنند . البته به شرطی که برنامه نویس به اون اصول و ویژگی ها وفادار باشه و ذهنشو در همون قالب ببره جلو .مثل چاقوی دو لبه هس هم می تونه خوب باشه هم بد . برای برنامه نویس مبتدی استفاده از فریم ورک ها  به نظرم حکم سم و زهر رو داره و جلوی یادگیری و درک عمیق تکنولوژی ها و زبانها رو میگیره و نمیزاره پوست شما در این راه کنده  و یادگیری تون عمیق بشه :)))) باری ، یکی از اون ویژگیها / اصول ، اصل Dependency Injection می باشد. اصل / ویژگی Dependency Injection  می گوید :برنامه نویس جان ! تو نوع ، نحوه کانفیگ ، زمان ایجاد و تعداد Bean هایی که می خواهی بهم بگو من خودم اونارو مدیریت می کنم . درضمن هر جایی دیدی یک bean / object  به object/bean دیگری نیاز دارد . کافیه اسم و نوع اون رو داخل کدت اعلام کنی ، اینکه اون bean/object چطوری و کی ساخته میشه و به کد تو تزریق میشه کاری نداشته باش اونا رو من هندل می کنم .در Spring معمولا از هر bean به صورت پیش فرض یک دونه ساخته میشه به اصطلاح Scope پیش فرض ساخت bean درفریم ورک Singleton ست . scope های دیگری هم در این فریم ورک تعریف شده که بر حسب نیاز پروژه مون می تونیم ازشون استفاده کنیم این scope ها عبارتند از :singleton(default)prototyperequestsessionglobalموقع کد زدن و تعریف bean ها معمولا پیش فرض ذهنی ما همون singleton scope هس مگه اینکه موقعیت /سناریویی برامون پیش بیاد که ببینیم نه باید بریم سراغ scope دیگه . یکی از سناریوها این است که bean ما stateful است و به ازای هر بار مراجعه بهش  حالت و وضعیتش قراره تغییر کنه و مهم تر اینکه اکثر این bean ها قراره توی یه محیط multi-threading  استفاده بشه  واین می تونه یه تهدید و باگ برای برنامه ما در محیط عملیاتی باشه .. در اینجا ست که scope اون bean رو تغییر می دیم . باز این مشکل نیس مشکل موقعی پیش میاد که می خواهیم این bean ها رو بهمدیگه اصطلاحا سیم بندی (wire) کنیم یعنی چی؟یعنی اینکه یک bean  با scope ی از نوع prototype رو به یک bean با scopeی از نوع  singleton سیم بندی کنیم . خب مشکل اینجا چیه ؟مشکل اینکه spring به عنوان big brother و مدیر موقع راه اندازی پروژه همه این bean ها رو در کل پروژه جستجو کرده و سعی می کند از هر کدوم یک دونه بسازه و هر جایی لازم شد همون رو به داخل کد موردنظر inject کنه . وقتی همه bean ها از نوع singleton باشند مشکلی نیس از هر bean یه دونه ساخته میشه و تموم . اما اگه bean از نوع  prototype باشه و  هر موقع جایی از کد به اون نیاز میشه لازمه فریم ورک یک نمونه جدید ازش بسازد و در اختیارش قرار دهد و معمولا اون قسمت از کد که درخواست این bean را دارد همون جا هم میگه من یه bean می خوام با این مشخصات و ویژگی ها . مشکل اینجاست وقتی beanی از نوع singleton   باشه یه بار ازش ساخته میشه و حین ساختش ، هر bean دیگه ای بهش نیاز داره اونم باید ساخته بشه و به این beanی singleton تزریق بشه  حالا فرض کنیم اون bean از نوع prototype باشه چیکار کنیم ؟ راه حل روی کاغذ :راه حلش اینه همون جا یه جوری به spring بگیم ببین beanی singletone ی من الان نیاز به beanی از نوع prototype داره ولی تو الان اون beanی prototype ی رو نساز بزار هر موقع بهش ارجاع واقعی دادم بساز . حالا بزار پروژه رو کامپایل کنم بعد...راه حل واقعی همراه با یک مثال کاربردی :بعد از اینکه صورت مساله رو بیان کردیم می رویم سراغ یک مثال کاربردی برای ارایه یک راه حل مناسب برای این مساله . مثال رو از یک پروژه ای که خودم باهاش برخورد کردم بیان می کنم . توی پروژه من یک Rest Controller ی بود که یک درخواست از مشتری می گرفت مشتری رو از نظر هویتی بررسی می کرد و در صورت تایید هویت و چک کردن مقدار اعتبار شارژش خدمتی بهش ارایه میداد. حین دادن خدمت بهش  همزمان نیاز بود مقداری از اعتبار شارژش کم بشه و این کم شدن از اعتبارش رو به صورت یک درخواست http به میکروسرویس دیگری میداد. در پایین این  کدهای مربوط  به  عمل کم کردن اعتبار مشتری مشاهده می کنید (خلاصه شده جهت درک بهتر موضوع )public class UserConsumptionLots  implements Runnable{    private final RestTemplate restTemplate;    private final Environment env;    private  String deviceToken;    private   String userToken;    public void setDeviceToken(String deviceToken) {        this.deviceToken = deviceToken;    }    public void setUserToken(String userToken) {        this.userToken = userToken;    }
    public UserConsumptionLots(RestTemplate restTemplate, Environment env) {       this.restTemplate = restTemplate;        this.env = env;    }
    @Override    public void run() {     // conntec to microservice and send http request    }}در واقع  در داخل این کلاس یک task تعریف شده که قراره به صورت async  توسط یه thread انجام بشه .در ادامه  اون Rest Controller رو داریم  که قراره از این کلاس ما استفاده کنه همون طور که میدونید معمولا اغلب Rest controller ها به صورت  singletone bean ها تعریف می شوند و باید هم اینطوری باشند :   @PostMapping(&amp;quot/path&amp;quot)    public ResponseEntity&lt;Item&gt; recognize()  {            UserConsumptionLots  userConsumptionLots=getUserConsumptionLots();            userConsumptionLots.setDeviceToken(deviceToken);            userConsumptionLots.setUserToken(userToken);            taskExecutor.execute(userConsumptionLots);             return ResponseEntity.ok();    }
این restController ما از دو bean بنام های TaskExecutor و UserConsumption استفاده می کند . bean دومی یعنی UserConsumption از نوع prototype است چرا که به ازای هر درخواست کاربر باید مقداری درش ست بشود و برحسب اونا کاری صورت بگیرد .(به کد بالایی و دو پارامتر deviceToken و  userTokenتوجه کنید )  نحوه کانفیگ این دو bean به صورت زیر می باشد :@Configuration @EnableAsyncpublic class AsyncConfiguration {    @Bean(&amp;quotthreadPoolTaskExecutor&amp;quot)    public TaskExecutor getAsyncExecutor() {        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();        executor.setCorePoolSize(20);        executor.setMaxPoolSize(100);       // executor.setWaitForTasksToCompleteOnShutdown(true);        executor.setThreadNamePrefix(&amp;quotAsync-consume-user-limit&amp;quot);        executor.initialize();        return executor;    }    @Bean    @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)    public UserConsumptionLots userConsumptionLots(RestTemplate restTemplate,  Environment env) {        return new UserConsumptionLots(restTemplate, env);    }}حالا می رویم سراغ  راه حل اینکه چطوری این دو bean یعنی RestController و UserConsumptionLots رو بهم سیم بندی کنیم . یک روش خیلی رایج استفاده از @Lookup annotation است . به این صورت که در داخل همون کلاس restController یک متدی به صورت زیر تعریف می کنیم :@Lookup
public UserConsumptionLots getUserConsumptionLots() {
    return null;
} 
 در این روش Spring  متد getPrototypeBean() که با @Lookup علامت گذاری شده را override می کند. ولی به اصطلاح عامیانه اسم این bean رو گوشه ذهنش ثبت می کند . و هرموقع نیاز بهش شد یک نمونه جدید می سازد و تحویل میدهد. در این روش spring از CGLIB استفاده می کند برای تولید بایت کد که وظیفه اش ساخت یک نمونه جدید از bean است .روشهای دیگری هم برای این مساله هست ولی رایج ترین روش همینی بود که سعی کردم توضیح بدم . امیدوارم مفید بوده باشه برای شما . اگه علاقه مند به استفاده از روشهای دیگر هستید مقاله زیر را می تونید مطالعه کنید https://www.baeldung.com/spring-inject-prototype-bean-into-singleton</description>
                <category>solmaz.oskouie (سولماز اسکویی)</category>
                <author>solmaz.oskouie (سولماز اسکویی)</author>
                <pubDate>Fri, 17 Apr 2020 23:11:09 +0430</pubDate>
            </item>
                    <item>
                <title>کوبا ،کرونا و کمونیسم</title>
                <link>https://virgool.io/@solmaz.oskouie/%DA%A9%D9%88%D8%A8%D8%A7-%DA%A9%D8%B1%D9%88%D9%86%D8%A7-%D9%88-%DA%A9%D9%85%D9%88%D9%86%DB%8C%D8%B3%D9%85-vo3l4dv86bhy</link>
                <description>دو روز پیش بود که در خبرها خوندم دکترهای کوبایی برای کمک به پزشکان ایتالیایی برای درمان و مراقبت از بیماران کرونایی  وارد این کشور شدند. ناخوداگاه این سوال در ذهنم نقش بست که چرا کوبا ؟!!!! امروز برحسب تصادف در توییتر  چشمم به توییتی خورد  با این متن :&quot;ورود همراه با تشویق ۵۲دکتر کوبایی به ایتالیا برای مقابله با بحران کرونا. چه لحظه‌ی با شکوهی. کوبا که ۵۰سال زیر تحریم‌ ظالمانه غرب بود حالا برای نجات کشورهایی آمده که همدست ظلم بودند. چه افتخار آفرین است دیدن میراث پزشکی درجه یکی که انقلاب کوبا و فرمانده کاستروی بزرگ بوجود آوردند&quot;درجواب این توییت کاربری توضیحاتی در مورد کوبا و وضعیت زندگی پزشکان و استادان دانشگاه و مردم عادی ارایه کرده بود که برای من یکی جالب بود گفتم با شما هم به اشتراک بگذارم شاید برای کسی جالب باشد. البته کسانی که کتاب &quot; کمونیسم رفت ما ماندیم و خندیدیم &quot; را خوانده باشد تک تک جملات این توییت را درک می کند که  کمونیسم و چپ چیست و چه ارمغانی برای انسان قرن بیستم و حتی بیست و یکم آورد و می آورد. آغاز رشته توییت :&quot;پزشکی درجه یک&quot; چه ارزشی دارد، وقتی بیشتر مردم سوء تغذیه دارند و نیمه گرسنه‌اند؟ وقتی که زنان استاد دانشگاه هم ناچارند برای خرجی آخر ماه تن فروشی کنند؟ وقتی که حسرت و آرزوی مردم داشتن اینترنت و موبایل است؟  &quot;بهداشت و درمان رایگان&quot; چه ارزشی دارد، وقتی که برای گرفتن نوبت برای بیماری که نیاز فوری به عمل جراحی دارد، باید رشوه کلان بدهی و یا در دندان‌پزشکی پول آمپول بی حسی را باید زیرمیزی حساب کنی؟ آشغال‌دانی کم نظیری که فرمانده کاسترو به وجود آورد، وضعش به گونه‌ای بود که وقتی در سال ۱۹۹۱ پول توجیبی سالانه ۵ میلیارد دلاری مسکو قطع شد، کشور با خودروهای موتوری خداحافظی کرده و به دوران ترابری اسبی بازگشت. نان و سیب زمینی جیره‌بندی شد و خود فرمانده در برنامه آشپزی تلویزیون ظاهر می‌شد تا به مردم یاد دهد که با پوست سیب زمینی و بادمجان چه غذاهای خوشمزه‌ای می توان درست کرد! البته سلیقه غذایی خود فرمانده متفاوت بود و در این دوران هم برنامه غذایی‌اش که شامل مرغوب ترین غذاهای دریایی از خاویار و صدف تا ماهی اوزون برون و میگو می‌شد و زیر نظر مستقیم خودش در کاخ‌خای مخفی ساحلی‌اش طبخ می‌شد، تغییری نکرد. او و رفقایش پس از کسب قدرت بساط توریسم را که درامد اول کشور بود، به بهانه اینکه موجب گسترش فساد و تحقیر ملت کوبا در برابر یانکی‌ها است برچیدند. ارنستو چه گوارا وزیر اقتصاد شد و اراده کرد تا اقتصاد نوین انسان‌محور را با انگیزه‌ها و پاداش‌های غیر مادی پی ریزد، یعنی حماقتی که حتی شوروی‌ها جرات انجامش را به خود نداده بودند! چه گوارا پیش از آنکه اقتصاد کوبا را به کلی از هستی ساقط کند، در همان میانه دهه شصت میلادی با فشار شوروی‌ها مرخص شد. او دل آزرده از کوبا رفت تا سرزمین‌های دیگری را به فلاکت بکشاند. پس از فروپاشی شوروی که کشور در آستانه قحطی قرار گرفت، کاسترو دریافت که تنها راه نجات، برقراری مجدد توریسم و کازینوها است. یک منطقه مجزا و محدود توریستی ایجاد شد که عملا خود کشوری دیگر درون کشور بود و ورود به آن برای اکثریت مردم کوبا ممنوع. واحد پول آن هم دلار است و پول رسمی کوبا در آنجا ارزشی ندارد. معدود کوبایی‌های خوشبختی که جواز کار در منطقه توریستی را دارند، از وضع رفاهی نسبتا خوبی برخوردارند. یک کوبایی که در منطقه توریستی راننده تاکسی است، بیش از ده برابر یک پزشک یا استاد دانشگاه کوبایی درآمد دارد. مردم کوبا از پشت نرده‌ها و حصارها خوشگذرانی توریست‌ها را با حسرت نگاه می‌کنند و حسرت دوران باتیستا را می‌خورند که لااقل می‌توانستند از کنار سفره خارجی‌های متمول بهرمند باشند اما حالا حتی حق نزدیک شدن به آنها را ندارند. معمولا در خاطرات انقلابیون کوبایی یک صحنه آشنا به عنوان یکی از انگیزه‌های آنها برای مبارزه نقل می‌شود: یک آمریکایی متمول از هتل خارج می‌شد و با دیدن کودکان فقیر کوبایی چند اسکناس یا شکلات جلوی آنها می‌انداخت و بچه‌ها روی سر و کول هم می‌پریند تا زودتر از بقیه شکلات‌ها و اسکناس‌ها را از روی زمین جمع کنند. حاصل مبارزه و حکومت‌داری آن انقلابیون این شده که مردم کوبا حسرت روزهای پیش از انقلاب را دارند. هنوز تولید ناخالص و درآمد سرانه در کوبا به میزان چشمگیری کمتر از دوران دیکتاتوری باتیستا است. ضعیت کشورهایی نظیر کاستاریکا و پاناما برای مردم کوبا چیزی شبیه خواب و رویا است. کوبا همواره بالاترین رقم زندانیان سیاسی در قاره آمریکا را داشته و تنها کشوری در این قاره است که اردوگاه‌های مخصوص بازپروری سیاسی دارند که ده‌ها هزار نفر سال‌های سال در آنجا زندانی می‌مانند.پایان رشته توییت .توییت دیگری در تایید نظر این کاربر تجربه عینی خود رو از سفر به کوبا چنین بیان می کند :آغاز رشته توییت :۱- ضمن تایید همه توضیحات توس عزیز، مشاهدات عینی خود را از کوبا توصیف می‌کنم.  همین چند سال پیش کوبا بودم. مردم در فقر و نکبت می‌زیستند. پولدارترها خودروهای لگن دهه ۱۹۵۰ را سوار می‌شدند. برخی خودروهای پوسیده را از وسط بریده و اتاقش را به قاطر/خر بسته به عنوان گاری استفاده می‌کردند۲- بهای فاحشه چند دلار خرد بود و بدتر اینکه خودشان به هر مرد مجرد یا متاهلی که کمی از همسرش فاصله می‌گرفت، پیشنهاد می‌دادند.  البته برای دیدن این نکبت، لازم بود که از منطقه ویژه توریست‌ها خارج شوی و لای مردم عادی به «کوبای واقعی» بروی.۳- چون از پیش می‌دانستم که مواد شوینده و بهداشتی و دستمال آنجا کمیاب است، یک کوله‌پشتی پر از این مواد با خودم برده بودم. به یک بازار شلوغ دستفروشان در هاوانا رفتم. مردم و دستفروشان تا فهمیدند که مواد شوینده و بهداشتی رایگان پخش می‌کنم، چنان روی سرم ریختند که نزدیک بود له شوم.۴- آخر کار کوله‌پشتی را پشت‌ و رو کردم و تکاندم تا با زبان بی‌زبانی به همه نشان دهم که کمک‌ها ته کشید و دست از سرم بردارند. یک زن دستفروش با انگلیسی شکسته و زبان اشاره پرسید که خود کوله‌پشتی را لازم دارم یا نه ...  کمونیسم یک ایدئولوژی ضدبشری و موجب نابودی کرامت انسانهاست.پایان رشته توییتامیدوارم  دست کم کرونا  هیچوقت و هرگز وارد این کشور نشود. </description>
                <category>solmaz.oskouie (سولماز اسکویی)</category>
                <author>solmaz.oskouie (سولماز اسکویی)</author>
                <pubDate>Tue, 24 Mar 2020 10:16:20 +0430</pubDate>
            </item>
                    <item>
                <title>راز فردوسی و  نوروز</title>
                <link>https://virgool.io/@solmaz.oskouie/%D8%B1%D8%A7%D8%B2-%D9%81%D8%B1%D8%AF%D9%88%D8%B3%DB%8C-%D9%88-%D9%86%D9%88%D8%B1%D9%88%D8%B2-lyuvpnp6tkej</link>
                <description>در شاهنامه‌ی فردوسی روایت عجیبی وجود دارد. داستان از این قرار است که: وقتی زال می‌خواست از سیمرغ خداحافظی کند و او را ترک‌ کند،سیمرغ سه پَر از پَرهای خود را به زال می‌دهد و به او می‌گوید &quot;هر وقت در تنگنا و تیره‌روزی قرار گرفتی پرها را به آتش بکش تا‌ من ظاهر شوم و به یاری‌ات بشتابم.&quot; سال‌ ها می‌گذرد.رودابه،همسرِ زال ، رستم را آبستن می‌شود و ناتوان از وضع‌حمل در بستر مرگ می افتد.زال هراسان اولین پر سیمرغ را به آتش می کشد.سیمرغ به یاری همسر و فرزندش می‌آید و از مرگ می‌رهاندشان. زال در اواخر عمر و قبل از مرگش دو پر دیگر را به رستم‌ می دهد تا درتنگنا آن‌ها را به آتش بکشد. سال‌ها می گذرد و رستم در جنگ با پهلوانی به نام اسفندیار دچار زخم‌های فراوان می‌شود و مستاصل از شکست او. رستم پر دوم را به آتش می کشد.سیمرغ آشکار می گردد. رستم را درمان می کند و راز شکست اسفندیار را بر‌ملا می‌نماید.رستم پیروز می شود. اما راز سر به مُهری که فردوسی قرن‌هاست آن را پنهان کرده، این‌جاست.فردوسی تکلیف پر سوم را مشخص نکرده است.در هیچ جای شاه‌نامه نشان و خبری از پر سوم نیست.سرنوشت پر سوم در پرده‌ی معماست.حتی هنگامی که رستم در هفت‌خوان در نبرد دیو سیاه و سپید گرفتار می گردد،و یا در رزم اول از سهراب شکست می خورد،پر سوم را به آتش نمی‌کشد.یا هنگامی که در چاه شغاد نابرادر به تیرهای زهر‌گون گرفتار می‌آید،کشته می‌شود،ولی پر سوم را به آتش نمی‌کشد. چه چیز با ارزش تر از جانش که مرگ را می‌پذیرد،ولی پر سوم را نگاه می دارد؟ چرا؟ رستم پر سوم را به چه کسی سپرده‌است؟ پر سوم باید به دست چه کسی برسد؟و در چه زمانی به آتش کشیده‌شود؟ادبیات اساطیری ایران شعله‌گاهِ دیرنده‌ای از اشارات و کنایه‌ها و نشانه‌های ژرف و رازآلود است. اشاراتی که خاستگاهش، همان تجسمِ آمال و آرزوهای ساکنان فلات ایران می‌باشد. فردوسی با هوشِ تاریخی و جامعه‌شناسش، پیش‌بینی روزهای تیرگون میهنش را نموده‌بود. او نیک می‌ دانست گردش گردون بر ایرانیان روزهای هم‌دیسِ حاکمیتِ ضحاک را بازمی‌آورد؛ چو ضحاک شد بر جهان شهریار بر او سالیان انجمن شد هزار نهان گشت آیین فرزانگان پراگنده شد نام دیوانگان هنر خوار شد،جادویی ارجمند نهان راستی،آشکارا گزند ندانست جز کژی آموختن جز از کشتن و غارت و سوختن  فردوسی در تعبیری عاشقانه و رازآلود، صبح امیدِ رهایی‌بخش از تیره‌بختی ایرانیان در هر دوره‌ای از این تاریخ را، درصدفی مکتوم قرار داده است. باور این که هنوز راهی بر سعادت‌مندی ایرانیان وجود دارد. تاریخ گواه این مدعاست. ایران خانه‌ی سیمرغ است و ما نوادگان رستم و زالیم... سومین پر سیمرغ را به آتش خواهیم کشید،تا سیمرغ خِرد و شادی و سعادتمندی، از این پس ظلام وحشت و تیره‌روزی بر فلات ایران لبخند بزند. آری ما وارثان پر سوم سیمرغ‌ایم.پا نوشت یک :در کتاب تاریخ سیستان آمده است:  از دور که سواد شهر پیدا شد ، دود و آتش بود که از شهر زبانه همی کشید ، به شهر که رسیدم ، کشته بود که بر جای جای شهر فتاده بود ، زنان و‌مردان و کودکان . مهاجمان حتی بر حیوانات رحم نکرده آنها را نیز کشته بودند . ناگاه از برزنی صدای بربط شنیدیم .به کوی وارد شدیم و مردی را در حال بَربط نوازی و رقص دیدیم . گفتیم ای مرد ، این چه حال است ؟ با چشمانی گریان و حالی پریشان گفت : که سپاهیان مسلمان بر نیمروز تاخته و یزیدابن مهلب دستور کشتار همگان داد و کشتند و سوختند ، من به همراه اندکی بیرون از شهر بودیم و پس از رفتن آنان آمدیم.حیرت زده گفتیم پس این نواختن و رقص از برای چیست ؟گفت : مگر نمیدانید که امروز نوروز است!پا نوشت دو  : برای ماندگاری یک ملت و تمدن سه عامل نقش اساسی دارد (طبق گفته بزرگان ادب و هنر و فرهنگ ) :سرزمین زباندین از بین این سه  مولفه ، ایرانیان جز در حوزه دین  بقیه را با فراز و نشیب های زیاد بازهم حفظ کردند و بهش غنا بخشیدند . نمیدانم دین در دنیای امروز ما چقدر می تواند همان نفوذ و کارکرد قرن ها و سالها پیش را داشته باشد اما اگر فقط جنبه اخلاقی و ارزشهای والای انسانی رو  درنظر بگیریم باید به خودمان متذکر شویم که برای رهایی از تاریکی و سیاهی و فساد فردی و اجتماعی حتما و حتما باید به آیین پاک گذشتگانمان که همان پندار نیک گفتار نیک کردار نیک به اصل مان بر می گردیم . است برگردیم .پانوشت سوم : با وجود همه تلاشها و شستشوهای ذهنی و فکری و تبلیغات بسیاری که گلوبالیستها و جهان وطنی های عمدتا (چپ ) سالها  برای زدودن مفهوم وطن  از ذهن و روان کشورهای جهان و بخصوص خاورمیانه ،  حس می کنم امسال بیشتر از هر سال دیگری وطن،  واژه پرمعنایی برای همه مان باشد .اینطور نیست!؟ به امید سرنگونی همه جهان وطنی های چپ و راست و این وری اون وری . پاینده وطن پاینده ایران امکان اشتراک ویدیو فعلا در ویرگول وجود ندارد این آهنگ ای ایران ای مرز پرگهر رو تقدیم می کنم به همه وطن دوستان عزیزم .https://youtu.be/QWSlJp60N9A</description>
                <category>solmaz.oskouie (سولماز اسکویی)</category>
                <author>solmaz.oskouie (سولماز اسکویی)</author>
                <pubDate>Fri, 20 Mar 2020 12:01:04 +0330</pubDate>
            </item>
                    <item>
                <title>کاوه آهنگر زمانه خود باشیم حتی شده بقدر دستها زیر بغل قایم کردن</title>
                <link>https://virgool.io/@solmaz.oskouie/%DA%A9%D8%A7%D9%88%D9%87-%D8%A2%D9%87%D9%86%DA%AF%D8%B1-%D8%B2%D9%85%D8%A7%D9%86%D9%87-%D8%AE%D9%88%D8%AF-%D8%A8%D8%A7%D8%B4%DB%8C%D9%85-%D8%AD%D8%AA%DB%8C-%D8%B4%D8%AF%D9%87-%D8%A8%D9%82%D8%AF%D8%B1-%D8%AF%D8%B3%D8%AA%D9%87%D8%A7-%D8%B2%DB%8C%D8%B1-%D8%A8%D8%BA%D9%84-%D9%82%D8%A7%DB%8C%D9%85-%DA%A9%D8%B1%D8%AF%D9%86-isxetolca3t1</link>
                <description>کاوه آهنگر زمانه خود باشیم حتی شده بقدر دستها زیر بغل قایم کردن!! این داستان رو یادمه زمان ما تو کتابهای پارسی  دبیرستان بهمون درس میدادند یادتون هست ؟هنوزم این داستان توی کتابهای درسی مون هست یا نه ؟داستان ضحاک یکی از جالب‌ترین قصه‌های شاهنامه است :۱ - ضحاک تازی است و بر ایران ‌زمین سلطه‌ دارد ، چه رویای عجیبی است این کابوس فردوسی .۲ - شیطان در هیأت یک آشپز به‌ استخدام دربار در‌می‌آید و برای نخستین ‌بار به ضحاک گوشت می‌خوراند . طعم پرندگان بریان به ‌مذاق ضحاک خوش ‌می‌آید و تصمیم به تشویق آشپز جدید می‌گیرد .۳ - ضحاک ، آشپز را به‌ حضور ‌می‌طلبد و از او تمجید می‌کند و به ‌او می‌گوید چه دستمزدی برای این غذای لذیذ طلب‌ می‌کند ، آشپز که همان شیطان است می‌گوید بوسه بر شانه‌های شاه بهترین پاداش برای من است . شاه از این تملق خوشش ‌می‌آید و اجازه بوسه می‌دهد !۴ - روز بعد شانه‌های شاه زخم‌ می‌شود و پس از مدتی ‌زخم‌ها باز می‌شوند و دو مار سیاه از زخم‌ها بیرون‌می‌آیند ، مارها تمایل‌ دارند از گوش‌های ضحاک به‌داخل روند و مغز سر او را بخورند ! شیطان اینبار به هیأت حکیم ظاهر‌ می‌شود و می‌گوید تنها ‌‌راه بقای شاه این ‌است که هر‌ روز دو‌ جوان را قربانی‌کند و مغز سر آنان را به‌ مارها بدهد تا سیر شوند و اشتهایی برای خوردن مغز شاه نداشته‌ باشند ! ضحاک بلافاصله می‌پذیرد و امر صادر‌ می شود !۵ - هر‌ روز دو جوان ایرانی به قید قرعه دستگیر ‌می‌شوند و به آشپزخانه دربار آورده‌ می‌شوند ، ظاهرا عدالت برقرار است و به‌کسی ظلم‌ نمی‌شود .ولی روزانه مغز سر دو‌ جوان ، غذای مارها می شود ، باشد که مغز شاه سالم ‌بماند .۶ -  هیچکس جرأت مقاومت ندارد و ایرانیان کماکان دچار این گفتمان هستند که : «بگذار همسایه فریاد بزند ، چرا من ؟؟ » و خشنودی هر خانواده ایرانی این ‌است که امروز نوبت جوان آن‌ها نشده ‌است « از این ستون ‌به آن ‌ستون فرج است »۷- «ارمایل» و «گرمایل» که اداره‌کننده آشپزخانه دربار هستند تصمیم‌ به‌ اقدام می‌گیرند ، البته نه اقدامی «رادیکال» بلکه اقدامی «میان‌دارانه»آن‌ها فکر می‌کنند که اگر هر روز یک ‌جوان را قربانی‌ کنند و مغز سر آن ‌جوان را با مغز سر یک‌ گوسفند مخلوط ‌کنند ، مارها تغییر طعم مغز را متوجه نمی‌شوند و با ‌این‌حساب آن‌ها می‌توانند در طول یک سال ، سیصد و شصت و پنج جوان را نجات‌ دهند!جالب اینجاست که مارها «مغز» می‌خواهند ، مغز ! نه قلب ، نه جگر ، نه ران ، نه دست ، فقط مغز ! هرکس که مغز ندارد خوش ‌بگذراند ، مارها فقط مغز طلب ‌می‌کنند .۸ - اقدام میان دارانه دو آشپز جواب ‌می‌دهد ! مارها طعم مغز مخلوط را تشخیص‌ نمی‌دهند و هر روز از دو ‌جوان که به آشپزخانه سلطنتی سپرده‌ می‌شوند یکی آزاد می‌شود ! ارمایل و گرمایل خشنودند که در‌سال ۳۶۵ نفر را نجات داده‌اند ، نیمه پر لیوان !۹ - ارمایل و گرمایل هر روز یک جوان را آزاد‌ می‌کنند و به‌او می‌گویند سر ‌به‌ بیابان بگذارد و در شهرها آفتابی‌ نشود که اگر معلوم ‌شود او از آشپزخانه گریخته ، هم او خوراک مارها می‌شود و هم سر ارمایل و گرمایل .۱۰ - «کاوه » آهنگر بود و سه‌ جوانش خوراک مارهای ضحاک شده‌ بودند ، کاوه رادیکال بود ، اگر ارمایل و گرمایل هم سه‌جوان داده بودند شاید رادیکال شده بودند . ۱۱ - ضحاک مار‌‌دوش تصمیم‌ می‌گیرد از رعایا نامه‌ای بگیرد مبنی ‌بر این‌که سلطانی دادگر است ! رعایا اطاعت ‌می‌کنند و به‌ صف می‌ایستند تا طوماری را امضا‌کنند به‌نفع دادگری ضحاک ! آنها می‌ایستند و امضا‌ می‌کنند ، در صف می‌ایستند و امضاء می‌کنند ، در صف می‌ایستند و .... ۱۲- نوبت به کاوه می‌رسد ، امضا‌ نمی‌کند ، طومار را پاره‌ می‌کند و فریاد‌ می‌زند که تو بیدادگری نه دادگر . کاوه نمی‌ترسد !۱۳- فریاد کاوه ، ضحاک و درباریان را وحشت‌زده می‌کند : این فریاد دلیرانه شمارش معکوس سقوط ضحاک است.۱۴ - کاوه آهنگر پیشبند چرمی که هنگام کار بر تن می پوشید را بر سر نیزه میکند و این پرچم نماد قیامش میشود ، درفش کاویانی .۱۵ - با پیوستن جوانان آزاد شده از مسلخ ضحاک به کاوه ، قیام علیه ضحاک آغاز می شود .فروغ می گوید : همه می ترسند ،همه می ترسند اما من و توبه درخت و آب و آینه پیوستیمو نترسیدیم .</description>
                <category>solmaz.oskouie (سولماز اسکویی)</category>
                <author>solmaz.oskouie (سولماز اسکویی)</author>
                <pubDate>Wed, 05 Feb 2020 21:41:26 +0330</pubDate>
            </item>
                    <item>
                <title>خوابهای خاورمیانه: آیاجراحی سخت خاورمیانه آغاز شده است؟</title>
                <link>https://virgool.io/@solmaz.oskouie/%D8%AE%D9%88%D8%A7%D8%A8%D9%87%D8%A7%DB%8C-%D8%AE%D8%A7%D9%88%D8%B1%D9%85%DB%8C%D8%A7%D9%86%D9%87-%D8%A2%DB%8C%D8%A7%D8%AC%D8%B1%D8%A7%D8%AD%DB%8C-%D8%B3%D8%AE%D8%AA-%D8%AE%D8%A7%D9%88%D8%B1%D9%85%DB%8C%D8%A7%D9%86%D9%87-%D8%A2%D8%BA%D8%A7%D8%B2-%D8%B4%D8%AF%D9%87-%D8%A7%D8%B3%D8%AA-zugtaoxllq58</link>
                <description>ماهایی که در خاورمیانه زندگی می کنیم روزها و چه بسا لحظات حساسی را داریم تجربه می کنیم فارغ از اینکه فرد حساس و علاقه مند به سیاست و اقتصاد باشیم یا نه حوادث ماه های اخیر و روزهای پیش رو ناخواسته روی زندگی و سرنوشت همه ما (هم ایران هم اسرائیل هم عراق هم ترکیه هم سوریه هم کشورهای عربی و حتی افغانستان و پاکستان ) تاثیرات عمیقی گذاشته و خواهد گذاشت . صبح که از خواب بیدار می شویم با حجم وسیعی از اخبار ضد و نقیض از سمت رسانه های مختلف بمباران خبری می شویم . مهم نیست گرایش فکری - عقیدتی و سیاسی ما چه باشد برای هر کدام از ماها رسانه ای هس با دسته دسته خبرهای جهت دار و گمراه کننده.-تظاهرات مردم عراق و لبنان (رسانه ای میگه : &quot;اونا میگن امریکا از کشورمون بره &quot; رسانه دیگری میگه:  &quot;ایران و تروریسیم از کشورمون بره&quot; ) -موشک پرانی های گروه های وابسته به فلان کشور به منطقه سبز-نشست سران n کشور دنیا در فلان شهر -گرانی سیب زمینی و گوجه فرنگی در داخل-آغاز کارزار انتخابی فلان حزب برچسب دار وووهمه همه به دنبال شست شوی مغزی ما مردم عادی و به اصطلاح حاکمان  ما مردم عوام جامعه و یارکشی برای اهداف پنهان و اشکار خود هستند . در واقع هیچ اطلاعات طبقه بندی شده ای در قرن 21 وجود نداره ولی انقدر خبرهای گوناگون و ضد و نقیض و جهت دار منتشر میشه که بسیاری مون اصل مطلب رو نمی تونیم پیدا کنیم. مهم نیست در طول روز چقدر خبر منتشر بشه  وتوسط چه رسانه ای - مهم اینکه اگه بخواهیم یه فضای ابری از واژگان بکار رفته داخل این خبرها تشکیل بدهیم یک یا چند واژه باید برای ما مردم خاورمیانه خیلی بولد بشود(کاری به فرکانس و تعداد دفعات تکرار اون کلیدواژه ندارم ). خب به نظر شخص بنده این کلید واژه خیلی مهم  &quot;معامله قرن &quot; یا همان &quot; صلح خاورمیانه &quot; هست و البته این اواخر واژه &quot;چین&quot; هم به لیست این کلیدواژه های مهم اضافه شده. از چند و چون قضیه من سردرنمیارم ولی میدونم سرنوشت ما به این کلیدواژه ها شدیدا گره خورده . خوب یا بدش هنوز مشخص نیست .در پشت صحنه رفت امدها و نشست ها و قول و قرار های زیادی در جریان است حتی اپوزیسیون فیک خارج نشین ایران که تریبون شون همان بی بی سی فارسی و  رادیو فردا و منوتو و صدای امریکا و .. هستن و از داخل تغذیه می شوند هم بشدت به تکاپو افتادن برای شستن ذهن ما مردم عادی  برای داشتن سهم مهم در آینده ایران . به قول دوستی این روزها همه مخالف و اپوزیسیون هستن شما چطور ؟ما مردم عادی می تونیم مثل همیشه احساسی برخورد کنیم و با چند جمله شورانگیز و احساسی و حماسی  یار یکی از این گروهها بشویم و ناخواسته بازوی اجرایی اهداف شوم و نیت های پنهانی آنها بشویم یا اینکه  چن اصل و خط قرمز مهم برای خودمون به عنوان یک ملت که در سرزمین واحدی بنام ایران زندگی می کنیم انتخاب کنیم و برای اجرایی شدن اون اصول با هوشیاری و با احتیاط قدم برداریم تا مثل سالهای قبل ما و آرزوهامون رو مصادره و غارت نکنن خاورمیانه و ایران کهن و ثروت مند ما لایق بهترین هاست اشکال در مردمانش هست که هر بار تاریخ را تکرار می کنند . از تاریخ بیاموزیم تا دوباره با دردناکی تکرارش نکنیم  . ته نوشت یک : اگه من هنوز درگیر خبرهای مرتبط با کلیدواژه های حجاب اجباری / اختیاری و چهارشنبه های سفید هستم  یا مثلا با دیدن فیلم خصوصی  فردی مشهور نظرم مثل باد تغییر می کند و از ادمها برای خودم قهرمان و شخصیت مقدس / رهبر  می سازم  البته که باید بیشتر مطالعه کنم و با تحلیل و تعمیق بیشتر جایگاه فکری و کنشگری خودمو در  جریان تغییرات بنیادین  پیش روی خاورمیانه ای پیدا کنم . ته نوشت دو: واقعا لازم نیست وابسته سازمانی یا گروهی باشی و از حلقه نزدیکان تا از اسرار پشت پرده آگاه باشی با وجود رسانه هایی چون توییتر و  مطالعه مقالات و مصاحبه ها و خبرهای رفت امدهای مقامات  میشه با علم تحلیل داده و تشکیل گراف های معانی به تصویر بزرگی از اون چه در حال وقوع هست دست پیدا کرد. ته نوشت سه : در روزهای پیش رو افراد زیادی از جناح های مختلف داخلی و خارجی حرفهای زیادی خواهند زد درحالی که لباس خیرخواه و اپوزیسیون پوشیده اند ( تا وقتی پول و قدرت هست و انسانها قابل خریدن چرا نباشه ) اما اصل اون چیزی است که قراره تبدیل به قانون اساسی کشورهای منطقه و مانیفست اصلی حاکمیت برنده و غالب نهایی این بازی ها باشه . اونجایی که نیاز به رای ما مردم عادی دارند برای کوبیدن میخ خود بر سرنوشتهای ما برای سالها. از حالا برای اون روز آماده باشیم .بی تفاوت نباشیم لازم به داد و فریاد و هیچ شوافی نیست تو خلوت خودمون می تونیم مدام مطالعه کنیم و تا به تدریج آماده اون مرحله نهایی باشیم .چه باور کنیم چه  نکنیم  جراحی سخت خاورمیانه توسط اربابان دنیا و صاحبان منابع ثروت آغاز شده است .</description>
                <category>solmaz.oskouie (سولماز اسکویی)</category>
                <author>solmaz.oskouie (سولماز اسکویی)</author>
                <pubDate>Thu, 23 Jan 2020 23:04:56 +0330</pubDate>
            </item>
                    <item>
                <title>تولید jwt به کمک کلید نامتقارن و نحوه بررسی اصالت jwt</title>
                <link>https://virgool.io/@solmaz.oskouie/%D8%AA%D9%88%D9%84%DB%8C%D8%AF-jwt-%D8%A8%D9%87-%DA%A9%D9%85%DA%A9-%DA%A9%D9%84%DB%8C%D8%AF-%D9%86%D8%A7%D9%85%D8%AA%D9%82%D8%A7%D8%B1%D9%86-%D9%88-%D9%86%D8%AD%D9%88%D9%87-%D8%A8%D8%B1%D8%B1%D8%B3%DB%8C-%D8%A7%D8%B5%D8%A7%D9%84%D8%AA-jwt-ec0mixhvs9gq</link>
                <description>در مورد استاندارد تولید توکن jwt  مقاله های خوبی به زبان هم فارسی هم انگلیسی موجود هست نمونه های وطنیش رو از اینجا می تونید مطالعه کنید .تو اکثر قریب به اتفاق مطالب از روش تولید امضا و نیز بررسی اصالت امضا به روش الگوریتم کلید متقارن (AES ) استفاده می شود. به این معنی که برای تولید امضا شما یک کلید مخفی دست تون دارید که باز ازهمون کلید استفاده می کنید برای باز تولید امضا . این روش برای مواقعی خوب هست که پروژه شما کوچیک باشه یعنی تولید کننده توکن هم خودتونید بررسی و تایید کننده توکن هم خودتون .اما وقتی پروژه بزرگ تر میشه یا شامل مجموعه زیادی از اپلیکیشن ها میشه که همه شون هم نیاز به اعتبار سنجی و هویت سنجی کاربران دارند نیاز هست یک سروری ( منظور بیشتر یک میکرو سرویس هست ) رو برای تولید توکن ها کنار بگذارید که کارش فقط تولید توکن برای کاربران اپلیکیشن های شما ست . اما وظیفه بررسی اصالت اون توکن ها رو می خواهید بسپارید به بخش دیگر مجموعه تون . خلاصه کلام و به زبان ساده  تولید کننده توکن با چک کننده اصالت توکن یکی نیستند، این جور مواقع میروند سراغ تولید توکن به کمک کلید های نامتقارن . اما روش کار کمی با اون چیزی که تو اغلب مقاله ها می خونید فرق داره . به این صورت که سرور A  دو تا کلید تولید می کنه ( کلید خصوصی و کلید عمومی ) . کلید خصوصی رو نزد خودش نگه میداره و کلید عمومی رو میده به سرور های چک کننده امضا .روش کار به این صورت ست :1- ابتدا بخش header و payload  اون توکن jwt رو برداشته و با یک تابع hash ی هَش می کند .hashObj=Hash(header.payload);2- بعد به کمک کلید خصوصی خودش این مقدار هَش شده را رمز گذاری می کند.signature=encrypt(hashObj,privateKey)3- بعد مقدار تولید شده در مرحله دوم رو میزاره تو قسمت امضای توکن jwtjwt_token=header.payload.signatureبعد این jwt_token رو میده دست کلاینت ( کاربری که میخواد وارد یک سرورB بشود ) .کاربر به ازای هر درخواستی که به سرور B ارسال می کند این توکن رو هم ضمیمه درخواستش می کنه.در سمت سرور B وقتی این توکن دستش میرسه مراحل زیر رو طی می کنه تا بتونه اصالت کاربر و امضاش رو تایید / رد کنه .سرور A قبلا به یک طریقی کلید عمومی رو به دست سرور B رسونده ( مثل کاری که گوگل برای استفاده از سرویس هاش توصیه می کنه کاربران انجام بدن یعنی میری تو سایت گوگل مشخصات سرور خودت رو میدی و ازش یک کلید میگیری این کلید رو برمیداری تو یه جای امنی از پروژه سمت سرورت نگه میداری ) .1- سرور B ابتدا میاد به کمک کلید عمومی قسمت امضای توکن jwt رو برداشته و رمزگشایی می کنه :hashObj=decypt(signature,publicKey)با این کار به همون آبجکت هَش شده میرسه ( خروجی مرحله 1 در سمت سرورA )2- بعد قسمت header و payload توکن jwt که دستش رسیده برداشته و تابع هََش اونو تولید می کنه :tempHashObj=Hash(header.payload)3- در نهایت مقدار تولید شده در مرحله اول و دومش رو باهم مقایسه می کند اگر برابر بود یعنی اصالت توکن دریافتی تایید شد وگرنه پیام خطا به کاربر ارسال می کند ( مثلا استاتوس کد 401) if( tempHashObj==hashObj){   continue } else {error //redirect user to error page }
به این روش تایید اصالت یک چیزی ( مثلا امضا ) اصطلاحا روشهای سوال و جواب می گویند .  به این صورت که هر دو طرف روی راه حلی برای تولید جواب  توافق می کنند مثلا فرض کنید  دوستتون میگه  3 و 5 رو بگیر روش یه عملیاتی انجام بده و خروجیش رو برای من ارسال کن.فرض کنید خروجی  درست از نظر دوستتون عدد 666 است . شما و دوستتون فقط  نحوه حل مساله رو میدونید اگه نفر سومی این دو عدد 5و 3 رو بگیره اصلا معنی شو نمیدونه . توی مثال بالایی اگه سرور مخرب و فضول C حتی اگه توکن دستش بیفته نمیدونه باهاش چیکار کنه (چرا میتونه خودش رو جای کاربر  جابزنه و کارهای خیلی بدی انجام بده  همون میشه حمله csrf ).یادمون نره هدف از تولید توکن jwt این هست که کسی نتونه هویت فرد دیگه رو جعل کنه حتی اگه توکن دستش بیفته . ( برای جلوگیری از حمله csrf هم معمولا یه توکن دیگه ای اضافه می کنن بنام csrf_token که موضوع این مقاله نیست ) .</description>
                <category>solmaz.oskouie (سولماز اسکویی)</category>
                <author>solmaz.oskouie (سولماز اسکویی)</author>
                <pubDate>Tue, 20 Aug 2019 20:46:06 +0430</pubDate>
            </item>
                    <item>
                <title>اسنپ کیو ،  RabbitMq ، Massive scalability ،Performance و دیگر هیچ</title>
                <link>https://virgool.io/@solmaz.oskouie/%D8%A7%D8%B3%D9%86%D9%BE-%DA%A9%DB%8C%D9%88-rabbitmq-massive-scalability-performance-%D9%88-%D8%AF%DB%8C%DA%AF%D8%B1-%D9%87%DB%8C%DA%86-ybo44xzsg4po</link>
                <description>تقریبا حدود سه هفته پیش بود که از طریق یک دوست با اسنپ کیو آشنا شدم .در واقع ایشون کنجکاو تکنولوژی های بکار رفته در اسنپ کیو هستن .علاقه ایشون و یه سوالی که از قبل تو پس زمینه ذهنی  من (هارد ذهنم )  مونده بود باعث شد منم علاقه مند بشم به اینکه چنین سیستم هایی که در یک بازه زمانی خاص یهویی بار ترافیکی زیادی به سرور  تحمیل میشه چطوری و با چه تکنولوژی هایی پیاده سازی میشه .طبق گفته و دسته بندی های ارایه شده توسط مارتین فاولر در مورد Enterprise Application ها  چنین اپلیکیشن هایی نباید business logic پیچیده ای داشته باشند و تنها چیزی که باید در موردش بیشتر تمرکز کرد بحث scaling و هندل کردن تعداد بالای کاربران ست . قطعا با http  و request /response های ساده چنین سیستم هایی هندل نمی شوند. به عنوان برنامه نویس منو( اگه خدا قبول کنه )  و دوستم بالطبع بیشتر جنبه های نرم افزاری قضیه و تکنولوژی ها و پروتکل های بکار رفته در لایه اپلیکیشن برامون جذاب بود . به واسطه این دوستم من توی این مدت با پروتکل های AMQPو  MQTT و بروکرهایی چون  RabbitMQ آشنا شدم و در واقع ایشون بودن که نیاز به یادگیری این تکنولوژی های message base  و queue base  رو در من به وجود اوردند.به گفته این دوست   از این تکنولوژی ها برای مدیریت تعداد زیاد کاربران  استفاده می کنند  حدس فنی شون این است در اسنپ کیو هم چنین تکنولوژی هایی بکاررفته ...از اوقات فراغت این چن روزه استفاده کرده و تصمیم گرفتم کمی بیشتر روی این مدل پروژه ها مطالعه کنم .داستان از پروتکل AMQP شروع شد به یادگیری RabbitMQ رسید بعدش سوالاتی توی ذهنم ایجاد شد و منحرف شدم سمت وب سوکت و چرایی استفاده از اون و تفاوتهایی که وب سوکت با AMQP  دارند و اینکه چرا ما MQTT رو روی وب سوکت هم نیاز داریم و...قسمت طنز ماجرا سوالی بود  که صبح توی ذهنم ایجاد شد ؟چن تا tcp socket روی کامپیوترم دارم من ؟   :/اصلا سوکت چیه ؟فرقش با پورت چیه ؟و..و...یهویی همه چی تو ذهنم قاطی شد :/// پروتکل های  msg base و وب سوکت و اسنپ کیو رو بی خیال شدم رفتم سراغ مفهوم سوکت و ماکزیمم تعداد tcp conn هایی که میشه روی یه سیستم زد .نترسید نمی خوام در مورد این ها این جا حرف بزنم اما همین سوالات بدیهی باعث بشد من یکسری فاکتورهای تاثیرگذار در زمینه  پشتیبانی از تعداد زیادی کاربر رو بتونم برای خودم لیست کنم شاید برای خواننده  محترم مقاله  هم جالب باشه این فاکتورها.قبل از اینکه به فاکتور های مورد نظر خودم اشاره کنم ابتدا لازم میدونم فکتورهای سنجش کارایی و پرفورمنس یک پروژه (شامل سخت افزار و نرم افزار ) به صورت کلی بدون توجه به نوع Enterprise Application را از قول فاولر که در کتاب  Patterns of Enterprise Appllication Architecture آنها رو لیست کرده  رو اینجا بیارم در دنیای سنجش performance چندین واژه / اصطلاح است که البته رعایت همه آن‌ها با همدیگر کارایی بالای پروژه شما را تضمین نمی‌کند و ممکن است  رعایت یک فاکتور باعث قربانی شدن فاکتورهای دیگر شود.این فاکتورها از نظر فاولر این‌ها هستند :فاکتور Response time : مدت زمانی که طول می‌کشد تا یک درخواست توسط سیستم پردازش شود.فاکتور Responsiveness :  یعنی سیستم چقدر در مقابل  درخواست ها پاسخگو است . مثلاً فرایند کپی کردن فایل ممکن است چند ثانیه طول بکشد (response time ) ولی به محض اینکه کاربر  عمل کپی کردن را شروع می‌کند سیستم بهش با یک علامت / شکلک  منتظر باشید یا سیستم درحال کپی کردن فایل شماست به کاربر واکنش نشان دهد .فاکتور Latency : یعنی کمترین زمانی که طول می‌کشد تا سیستم به درخواستی واکنش نشان دهد. این موضوع توی سیستم‌های ریموت می‌تواند خیلی فاکتور تأثیر گذاری باشد مثلاً من از سیستمی خواستم کاری انجام دهد ولی وسط راه پشیمون شدم دکمه کنسل را زدم  ولی سیستم  بعد از اینکه کار را انجام داد و تموم شد اون دستور کنسلی منو لحاظ کنه و واکنش نشون بده چنین سیستمی اصلاً سیستم خوبی از نظر تأخیر (latency) نیست . باید همون لحظه که زدم هیچ کاری نکن هیچ کاری نکنه و بهم واکنش نشون بده .فاکتورThroughput : یعنی سیستم در یک واحد زمانی چند کار می‌تواند انجام دهد مثلاً یک سیستم در یک ثانیه چند تراکنش انجام دهد .یا سیستم در یک واحد زمانی چند کیلو بایت می‌تواند  کپی کند .معمولاً برای enterprise application ها چند تا از تراکنش های متداول پروژه را به عنوان معیار سنجش throughput  انتخاب می‌کنند .گاهی افزایش throughtput باعث کاهش فاکتور response time می‌شود . اما باز بستگی دارد به سیستم شما . گاهی از نقطه نظر کاربر بهبود  resposiveness باعث بالا رفتن کارایی می‌شود در حالی که فاکتورهای throughput و  یا حتی response time  قربانی شوند .فاکتور Load : معمولاً می‌گویند چه تعداد کاربر همزمان می‌توانند به سیستم وصل بشوند و سیستم به درخواست آن‌ها پاسخ مناسب بدهد.فاکتور Load sensivity : یعنی سیستم براساس تعداد کاربران  میزان response time ش چقدر تغییر می‌کند. مثلاً می‌گوییم سیستم A دارای زمان پاسخگویی 0.5 ثانیه به ازای 10-20 کاربر است .و سیستم B دارای زمان پاسخگویی 0.2 ثانیه  به ازای 10 کاربر است که وقتی تعداد کاربران به 20 عدد می‌رسد مدت زمان پاسخگویی به 2 ثانیه می‌رسد .در این حالت سیستم A  دارای load sensitivty  پایین‌تری است .فاکتور Efficiency : یعنی performance تقسیم برتعداد منابع  . به عنوان مثال سیستمی که با دو cpu  دارای 30 tps است دارای efficiency بالاتری  نسبت به سیستمی ست که داری 40 tps با 4 cpu است .فاکتور Capacity :  برابر با بشینه throughput یا load مؤثر سیستم است . این مقدار را می‌توان به صورت یک نمودار سهمی تصور کرد که در نقطه از نمودار دارای بشینه مقدار است .فاکتور Scalability : با چه تعداد افزودن منابع می‌توان performance را بهبود بخشید .دو مدل scalability داریم :مدل vertical scalability یا به عبارت دیگر scaling	up  یعنی افزودن  سخت‌افزار بیشتر به یک سرورمدل horizontal scalabilty یا 	به عبارت دیگر scaling 	out  یعنی افزودن تعداد بیشتر سروربا فرض اینکه مهمترین مساله ما در یک پروژه بحث هندل کردن تعداد زیاد کاربران  اون هست رعایت فاکتورهای زیر به گمان من ( طبق مطالعاتی که امروز داشتم )  ممکنه باعث افزایش کارایی پروژه بشه (  از نظر فاکتور Load که در بالا بهش اشاره شد ) .ما 65534 تا پورت نرم افزاری روی یک سیستم داریم( منظور روی یک سیستم عامل ) و همانطور که میدونید مفهوم port در لایه اپلیکیشن از استک tcp/ip معنی پیدا می کنه . فرض کنید ما روی سرورمون فقط  یک آدرس ip ( به آدرس x.y.z.s ) داریم و این سرور ما یک کلاینت ( کاربر ) دارد که میخواهد بهش وصل بشود . به نظرتون این کلاینت چن تا tcp conn می تواند به سرور بزند و باز کند ؟جواب : 65534 تا به این صورت که کلاینت ا 65354 تا درخواست به آدرس ip یکسان ولی با پورت های متفاوت می فرستد :x.y.z.s:0x.y.z.s:1....x.y.z.s:65354این عدد روی کاغذ درسته فاکتورهای دیگر هم هستند که باعث می شوند این عدد محدود بشود  از جمله :میزان حافظه RAM در دسترس ( برای نگهداری اطلاعات سوکتها ) تعداد و قدرت کارتهای شبکه نصب شده روی ماشین سرور سرعت اینترنت همچنین روی سیستم عامل های یونیکس بیس و لینوکس بیس  ما یک پارامتری هم داریم که ماکزیمم تعداد فایل های باز شده به صورت همزمان را مشخص می کنه این پارامتر باید در سطح کرنل باید تنظیم بشه .حال فرض کنید سرور ما یک آدرس ip دارد وکلاینتهای ما فقط با یک پورت این سرور کار دارند .  فرض کنید این بار تعداد خیلی زیادی کلاینت قصد وصل شدن به سرور رو دارند روی همان آدرس ip و همون پورت .به نظرتون چن تا tcp conn می تونیم روی سرورمون باز کنیم با فرض اینکه ما محدودیت حافظه RAM و کارت شبکه و سرعت اینترنت و اون پارامتر داخل کرنل لینوکس رو نداریم میشه گفت بی نهایت استدلالم برای این بی نهایت گفتن این توضیح و مثال زیر است ( اگه درست نیس بفرمایید ) هر packet که از سمت کلاینت به سرور ارسال میشه برای اینکه شناسایی بشه این packet از سمت چه کسی اومده و با چه اپلیکیشنی سرو کار داره به 4 پارامتر زیر نیاز داره :client_address:client_port | server_address:application_portما گفتیم بی شمار کلاینت با آدرس ip های متفاوت داریم حالا از چه پورتی برای ارسال packet استفاده کردن زیاد مهم نیس اما این ور، سمت سرور، ادرس سرور و پورت کاملا مشخص و از دید همه کلاینت ها یکسان است .وقتی packet دست سرور رسید اون فقط از tcp socketعبور میده و میده به لایه بالاتر از خودش یعنی لایه اپلیکیشن اونجا از روی پورت می فهمه  دست چه اپلیکیشنی باید برسونه پیام رو .فرض کنید چنین سیستمی از نظر زیرساخت ساخته و بهینه کانفیگ شده به نظرتون همه چی اوکیه ؟جواب : نه چون در سطح اپلیکیشن ما نیاز داریم نرم افزارهایی داشته باشیم که بتونه این حجم از پیامها / درخواستهای اومده سمتش را گرفته و پردازش کنه و اینجاست که غول هایی چون کافکا و بروکرهایی چون RabbitMQ و EMQX خودشون رو به رخ ما برنامه نویسان می کشند . و البته تا یادم نرفته بگم اگه از نرم افزارهامبتنی بر JVM و کلا ماشین های مجازی و Container استفاده می کنید اونها هم نیاز به تیون کردن بهینه دارند . حین جستجو هام توی وب به این مقاله برخوردم برام خیلی مفید بود گفتم شاید برای شما همین همین طور باشه پس به اشتراک میزارم.مطالبی که اینجا بخصوص برای بیان استدلالم  نوشتم رو از منابع زیر برداشت کردم (شاید برداشتم اشتباه باشه خوشحال میشم اشتباهاتم رو تصحیح بفرمایید چون تنها هدفم از انتشار این مطالب به چالش کشیدن دانش و درک خودمه و خب اگه مفید هم باشه برای دوستان باعث افتخار منه  :) منابع https://www.quora.com/How-many-open-TCP-connections-can-a-typical-PC-hold-at-oncehttps://www.quora.com/How-many-clients-can-connect-to-a-single-TCP-porthttps://mrotaru.wordpress.com/2013/10/10/scaling-to-12-million-concurrent-connections-how-migratorydata-did-it/https://docs.emqx.io/broker/v3/en/design.html#architecture</description>
                <category>solmaz.oskouie (سولماز اسکویی)</category>
                <author>solmaz.oskouie (سولماز اسکویی)</author>
                <pubDate>Tue, 20 Aug 2019 00:12:15 +0430</pubDate>
            </item>
                    <item>
                <title>مدیریت تشکیلات مافیایی به کمک رعایت اصول Object Oriented</title>
                <link>https://virgool.io/cafegame/%D9%85%D8%AF%DB%8C%D8%B1%DB%8C%D8%AA-%D8%AA%D8%B4%DA%A9%DB%8C%D9%84%D8%A7%D8%AA-%D9%85%D8%A7%D9%81%DB%8C%D8%A7%DB%8C%DB%8C-%D8%A8%D9%87-%DA%A9%D9%85%DA%A9-%D8%B1%D8%B9%D8%A7%DB%8C%D8%AA-%D8%A7%D8%B5%D9%88%D9%84-object-oriented-wfkr5hl3stvu</link>
                <description>مدتیه گوش دادن به پادکست Master mind  حین دوچرخه سواری و پیاده روی شروع کردم  تنها دلیلی که باعث شد سمت این پادکست برم همون برنامه نویس بودن  قهرمان اصلی این داستان یعنی پاول لرو بود :)))و اینکه چطور یه برنامه نویس گوشه گیر و درون گرا که عمری تنها پارتنرش کامپیوترش بود و بود یهویی انقدر اجتماعی و شبکه گرا میشه که این چنین تشکیلات عظیمی از کارهای خلاف رو راه اندازی و مدیریت می کنه .این جنبه ش برام جالب و تا حدودی عجیب بود تم اصلی داستان اصلا چیز جذاب و یونیکی نیس قاچاق مواد و کشتن انسانها و .... اما لابلای گوش دادن به متن اصلی داستان مدام ذهنم  نشانه ها و رد پاهای اصول Object Oriented و طراحی نرم افزار رو پیدا می کرد و جالب اینکه حین گوش دادن مدام می گفتم اینجا از فلان اصل پایه ای OO استفاده کرده اینجا دیزاین پترن مثلا template method  بکار برده اوونجا منظورش از agent ( عامل ) همون interface بوده همه جا SOLID به خوبی رعایت شده و.......ولی خب مثل خیلی از مهندسین نرم افزار عجله(بخونید Agile دی: )  و گیرافتادن تو مخمصه یا شاید هم اعتماد به نفس بالا باعث شده کثیف کاری  کنه تو  نقشه هاش و همین  کثیف کاری هاش باعث ردیابی و آشکار شدن هویت واقعیش شده !!!خلاصه که اگه از شغل برنامه نویسی پول خوبی در نمیارید یا بخاطر هزینه های روز افزون  زندگی تو ایران نمی تونید خودتو رو همچنان اون  بالای خط  فقر نگه دارید  ولی طراح خوب نرم افزار هستید و تفکر استراتژیک عالیی دارید   بدونید از این توانایی شما در چنین جاهایی هم میشه استفاده کرد :))))ته نوشت : با خودم داشتم  فکر می کردم وقتی یه نفر اینطوری می تونه با اشراف براطلاعات و نقص قوانین و تبصره های قانونی این چنین تشکیلات تبهکارانه راه بیندازد یک دولت / سیستم حکومتی بنا شده بر اصول  شیطانی و تبهکارانه  چقدر می تونه در سطح جهانی ، دنیا رو به آشوب و تباهی بکشاند به کمک  پول ،قدرت اطلاعاتی و استخدام وکلای بین المللی  ، نیروهای امنیتی و نظامی و....راستی این لیست از اصول OO رو بد نیس ته جیب مون داشته باشیم حین اداره تشکیلات مافیایی (پروژه ) :))))Single Responsibility Principle (SOLID)High Cohesion Low Coupling Open Closed Principle (SOLID)Liskov Substitution principle (SOLID)Interface Segregation Principle (SOLID)Dependency Inversion Principle (SOLID)Program to an Interface, not to an ImplementationHollywood PrinciplePolymorphism Information Expert Creator Pure Fabrication Controller Favor composition over inheritanceIndirection Demeter Principle</description>
                <category>solmaz.oskouie (سولماز اسکویی)</category>
                <author>solmaz.oskouie (سولماز اسکویی)</author>
                <pubDate>Wed, 14 Aug 2019 22:38:12 +0430</pubDate>
            </item>
                    <item>
                <title>اسباب بازی من بهتر از مال تو هست( اندر باب فاکتورهای تاثیر گذار در انتخاب  زبانها / تکنولوژی ها )</title>
                <link>https://virgool.io/@solmaz.oskouie/%D8%A7%D8%B3%D8%A8%D8%A7%D8%A8-%D8%A8%D8%A7%D8%B2%DB%8C-%D9%85%D9%86-%D8%A8%D9%87%D8%AA%D8%B1-%D8%A7%D8%B2-%D9%85%D8%A7%D9%84-%D8%AA%D9%88-%D9%87%D8%B3%D8%AA-%D8%A7%D9%86%D8%AF%D8%B1-%D8%A8%D8%A7%D8%A8-%D9%81%D8%A7%DA%A9%D8%AA%D9%88%D8%B1%D9%87%D8%A7%DB%8C-%D8%AA%D8%A7%D8%AB%DB%8C%D8%B1-%DA%AF%D8%B0%D8%A7%D8%B1-%D8%AF%D8%B1-%D8%A7%D9%86%D8%AA%D8%AE%D8%A7%D8%A8-%D8%B2%D8%A8%D8%A7%D9%86%D9%87%D8%A7-%D8%AA%DA%A9%D9%86%D9%88%D9%84%D9%88%DA%98%DB%8C-%D9%87%D8%A7-fwdifoobaq81</link>
                <description>دقیقا دو روز پیش بود که  کتاب   Patterns of Enterprise Application Architecture  مارتین فاولر رو بازم دستم گرفتم برای مطالعه ( برنامه ام مطالعه تدریجی این کتاب  مفید و حرفه ای  ست ). فاولر میگه برای شخص من بزرگترین چالش ( والبته علاقه مندی ) درهنگام طراحی یک Enterprise Application بحث سر انتخاب معماری / ابزار و بررسی اینکه کدامیک چرا مناسب تر از دیگری است . ( فکر کنم منظور فاولر مرحله Suitability باشد دراین مرحله از فرایند طراحی نرم افزار روی انتخاب معماری و ابزار و زبان برنامه نویسی و حتی فریم ورک ها بحث می شود تا براساس ماهیت پروژه و مسئله ، مجموعه ای از راه حل ها / معماری / ابزارهای مناسب را انتخاب کنند ) .فاولر میگه به هنگام انتخاب معماری / ابزار بایستی سه نکته را درنظر داشته باشید :تعداد کاربران وبحث scale 	سیستم مانند سیستم خرده فروشی آنلاین ( سیستم هایی که تعداد خیلی بالایی از کاربران را باید مدیریت کنند)  میزان پیچیدگی Domain Logic وUI مانند سیستم بستن قراردادهای لیزینگ و مالی ( در این سیستم ها ما با business logic  و rule های خیلی پیچیده ای سروکار داریم ولی تعداد کاربران در طول زمان معمولا ثابت هستند )   تعداد و تنوع فیچر ها در گذر زمان ( سیستم هایی که  خیلی ساده شروع می شوند ولی به مرور مدام بهش فیچر های آنچنانی اضافه می شود مثل سیستم پیگیری هزینه ها و درامدهای شرکت )این بحث فاولر  گوشه ذهنم بود تا اینکه دیروز با دوستی  مشغول صحبتهای  تخصصی از جنس دولوپری خودمون بودیم .برای ایشون جالب بود بدونند چرا باید هنوز زبانی مانند جاوا ( با این حجم از پیچیدگی و  سختگیری ) خواهان داشته باشد و اصلا چرا باید  تو پروژه های بزرگ   از جاوا استفاده کرد .(  منظورشون بیشتر آنجایی که تعداد بالایی از کاربران  حضوردارد و  مباحث scaling و توزیع  درخواستها و ارایه سرویس ها مطرح است ) . دعوا سر  این زبان وآن زبان ، این تکنولوژی و اون تکنولوژی همیشه خدا بین برنامه نویسان و توسعه دهندگان نرم افزار بوده و به نظر خودم بسیار هم جذاب است ( به شرطی که مسئله شخصی و  ناموسی نشود  و هدف توهین  و زیر سوال بودن  شخصیت و سواد فرد مقابل  نباشد و حدود رعایت بشود ) .من همین مطالبی که اون بالا از قول  فاولر  نوشتم رو براشون گفتم  و اینکه بحث scaling یک بحث مختص زبان نیست و خیلی عوامل دخیل است .راستش هنوز برای خودم  چندان واضح نیست چرا جاوا ؟چرا هنوز جاوا ؟قبل دست به قلم شدن برای نوشتن این مقاله کمی توی گوگل گشتم تا جوابی برای سوالم پیدا کنم یکی از  مطالب جالبی که پیدا کردم  این متن بود :https://www.slideshare.net/120bi/scaling-a-high-traffic-web-application-our-journey-from-java-to-phpاین مقاله دردسرهایی که با پلتفرم جاوایی برای Scale کردن ( یک سروررو تبدیل به دو سرور کردن ) پروژه شون داشتند و اینکه برای تامین این نیازشون مجبور شدن از جاوا به PHP مهاجرت کنند و دردسرها و پیچیدگی هایی که با افزودن ORM به پروژه شون داشتند و ... بیان می کند . اما در نهایت ... در نهایت  میگه این زبان نیست که تعیین کننده است برای scale کردن       Never let anybody tell you a language or framework does or  doesn’t scale. عوامل و فاکتورهای زیادی دخیل می شوند تا تیمی با کمترین درد و خونریزی یک پروژه با تعداد بالایی از کاربران و حجم عظیمی از ترافیک را به مرحله بلوغ و نگهداری برسانند. این عوامل چیا هستن سعی می کنم در مقاله / مقاله های بعدی  بیانشون کنم .ته نوشت : خیلی دلم میخواست زیر همین پست دوستانی که تجربه ای تو حوزه پروژه های با ترافیک بالا ومبحث scaling داشتند چالش ها و راه حل ها شون  بنویسند  :) </description>
                <category>solmaz.oskouie (سولماز اسکویی)</category>
                <author>solmaz.oskouie (سولماز اسکویی)</author>
                <pubDate>Mon, 29 Jul 2019 15:59:34 +0430</pubDate>
            </item>
                    <item>
                <title>تعریف Enterprise Application از دید مارتین فاولر بزرگ</title>
                <link>https://virgool.io/@solmaz.oskouie/%D8%AA%D8%B9%D8%B1%DB%8C%D9%81-enterprise-application-%D8%A7%D8%B2-%D8%AF%DB%8C%D8%AF-%D9%85%D8%A7%D8%B1%D8%AA%DB%8C%D9%86-%D9%81%D8%A7%D9%88%D9%84%D8%B1-%D8%A8%D8%B2%D8%B1%DA%AF-nyr54jnhhsfl</link>
                <description>مارتین فاولر می گوید :در برخی موارد Enterprise Application ها خیلی ساده تر از  نرم افزار های Telecome هستند چرا که آنها مسایل multi-threading خیلی سخت  ندارند.  آنها بحث تجمیع سخت افزار با نرم افزار ندارند ولی...ولی Enterprise Application ها داده های پیچیده دارند .از نظر فاولر منظور از Enterprise Application ها همان سیستم های اطلاعاتی هستند آنهایی که با  پردازش و ذخیره سازی بلند مدت داده سروکار دارند . فاولر در ادامه چند تا از سیستم های اطلاعاتی موردنظر را این طوری مثال می زند :Payroll, Patient records, shipping tracking, cost analysis, credit scoring, insurance, supply chain, accounting, customer service, foreign exchange tradingویژگی های  Enterprise Application ها از نظر فاولر:1- این سیستم ها معمولا با persistent data سروکار دارند 2- آنها داده های زیادی دارند 3- معمولا دسترسی به این داده ها به صورت همزمان  است بنابراین چالشهای دسترسی ایمن و جلوگیری از خرابکاری ناشی از دسترسی همزمان را در دل خود دارد و بیشتر برنامه نویس ها رو درگیر  می کند ( مدیریت تراکنشها )4- این داده ها باید به انواع شکل ها و ساختارهای مختلف درآیند تا دردسترس کاربران قرار گیرند (از طریق view های مختلف ) 5-این سیستم ها اغلب با Enterprise Application های دیگر در ارتباط و تعامل هستند بنابراین  با تکنولوژی های مختلفی سروکار دارند . اما برای تعامل و گفتگو با همدیگر نیاز به یک زبان مشترک دارند .6- مفهوم و اصطلاح business logic  در این سیستم ها خیلی زیاد شنیده و بکار برده می شود که شامل فرایند شناسایی و استخراج  قواین کسب و کار (business rules) می شود .بطوری که کلیه رفتارهای سیستم در قالب همین قوانین کنترل و مدیریت بشود و درعین حال به تمام نیازهای مشتری پاسخ داده شود .7- معمولا می گویند Enterprise Application ها سیستم های بزرگی هستند  اما باید توجه داشته باشیم که آنها را باید به sub system  های کوچک و ساده تبدیل کنیم تا کار توسعه تست و مدیریتشان آسان تر بشود معمولا  اینکار با  ساده سازی  فرایند و معماری صورت می گیرد . منبع : کتاب  Patterns of Enterprise Application Architecture   نوشته مولا مون  مارتین فاولر کبیر :)</description>
                <category>solmaz.oskouie (سولماز اسکویی)</category>
                <author>solmaz.oskouie (سولماز اسکویی)</author>
                <pubDate>Wed, 24 Jul 2019 12:22:32 +0430</pubDate>
            </item>
                    <item>
                <title>عاشقی شیوه رندان بلا کش باشد</title>
                <link>https://virgool.io/@solmaz.oskouie/%D8%B9%D8%A7%D8%B4%D9%82%DB%8C-%D8%B4%DB%8C%D9%88%D9%87-%D8%B1%D9%86%D8%AF%D8%A7%D9%86-%D8%A8%D9%84%D8%A7-%DA%A9%D8%B4-%D8%A8%D8%A7%D8%B4%D8%AF-otrffgpquicq</link>
                <description>عکس متعلق است به کافه کوخ (میدان انقلاب) که زیر نظر جمعیت امام علی اداره می شود -محل برگزاری جلسه معارفه اعضای جدید جمعیت .بعد مدتها ( حدود ۹ سال ) کارت اهدا عضو دستم رسید. کاری که با جون و دل انجامش دادم و امیدوارم  اینطوری هم سرانجامم به سر برسد ( از روی خودخواهی کامل این حرف را میزنم ولی شما اسمش را بگذارید میل به جاودانگی ) . اصلا کار سختی نیس یه ماجرایی که  بعد مرگم یا نزدیک به مرگم اتفاق خواهد افتاد ( تازه اگر اتفاق بیافتد) .حرفم چیز دیگه ای هس . قبل عید دراثرتماشای یه مستند و دنبال کردن فعالیتهای جمعیت خیریه امام علی ، فرم عضویتش رو پر کردم. از اونم چن ماهی خبر نشد تا همین دو سه روز پیش که sms اومد شما به عضویت جمعیت در اومدید اگه هنوزم مایل هستید فلان روز فلان جا بیایید برای جلسه معارفه !روز موعود رسید و من یه ربع مونده به  ساعت قرار  ،دم در یه خونه قدیمی منتظر ایستاده بودم . ذهینتم این بود من قراره به اونا معرفی بشم!!!!!اما وقتی  جمعیت حدود ۴۰-۵۰ نفری رو دیدم که مثل من برای جلسه معارفه اومده بودن ، فهمیدم  قضیه برعکسه. باری ، نشستیم و یه اقایی که از اعضای نسبتا قدیمی  جمعیت بود اومد و شروع کرد در مورد اهداف و فعالیتهای جمعیت  گفتن .هرچی اون بیشتر می گفت من بیشتر دچار تردید و ترس میشدم!اون می گفت باید صبرمون زیاد باشه در مواجه با بچه های بدسرپرست / معتاد/ اسیب دیده / خلافکار!اون از حضور در محلات بدنام و خطرناک تهران ( مثل دروازه غار و دره فرحزاد و لب خط و .... ) حرف میزد !اون از فحش رکیک شنیدن  و حتی کتک خوردن از طرف این بچه ها می گفت و اینکه  به این راحتیا به غریبه ها اعتماد نمی کنن !اون از اعزام نیروی داوطلب به مناطق سیل زده /دورافتاده برای کمک رسانی می گفت!اون از ملاقاتهای توی زندان با کودکان  قاتل ( تحت عنوان طرح طفلان مسلم برای نجات کودکان محکوم به اعدام ) می گفت !اون از زنان تن فروش / معتاد / مبتلا به ایدز می گفت ...می گفت و می گفت و می گفت و من .... من هی دچار تردید و ترس میشدم اینکه آیا در من توان و جرات این کارها هس!؟  درسته ژن خوب نیستم و تو پر قو بزرگ نشدم ولی همه این چیزایی که می گفت  برام دلهره اور و غریب  بود . به قول همکارم  یه جورایی استقبال از بلا و مصیب و غم بود .یکی از بچه های جلسه گفت من اومدم با شاد کردنشون ،تو فضای شاد، دینمو به جامعه ام ادا کنم!  که اون آقای  عضو قدیمی انجمن گفت تا تو با اونا هم درد نشی و دردشون رو با جون و دل درک نکنی محاله بتونی شادشون کنی ! اون از شارمین میمندی نژاد و انگیزه های انسانیش برای تاسیس این گروه می گفت از سختی ها و تهمت هایی که جمعیت به خود دیده ..........................من چی فکر می کردم  وچی در انتظارم بودم! من  به نیت دراختیار گذاشتن سواد تخصصی ناچیزم به اونا به نیت اینکه با یادگرفتن یه تخصص بتونن خودشون صاحب درامد و شغل بشن و دستشون تو جیب خودشون باشه  در این جمعیت خیره  ثبت نام کردم ولی ...میدونید اونجا از جلسات دعا و سفره پهن کردن  و نذری و اینا هم حرف زدن . از دور هم نشینی و  انرژی مثبت دادن و گرفتن و اشپزی و ..اینارو که می گفت هیچ دلهره و ترسی تو دلم ایجاد نمیشد !حاشیه امن من همونطور امن باقی می موند از فکر کردن بهشون حس ارامش و خلسه بهم دست میداداما بقیه اش نه!بقیه اش باعث ترس و ناامنیم می شداونجا بود که متوجه شدم چقدر مثل بقیه مردم کشورم زامبی شدم مجسمه شدممعتاد شدم!جرات بلند شدن و قیام کردن برای مبارزه عملی با بیداد و  بی عدالتی و ظلم و بدی و نامهربونی رو ندارم .دین دارم اما شده  مثل دارویی که فقط بهش معتاد شدم هیچ تاثیری نداره جز تسکین دهنده قلب و روحم . چتریه برای  سرپوش گذاشتن بر ترس های شناخته و ناشناختم .  دینی که باعث پویایی جامعه ای نشود به چه دردی می خورد؟اسطوره های دینی چه  تاثیر عملی در  زندگی و منش و روش پیروان امروزیش  دارند؟ شاید بگید باید از طرف خودم حرف بزنم !بگید من فقط اینطوریم  ما اینطوری نیستیم !درسته خودمم اینطوری فکر می کردم . فکر می کردم من ترسو و نازپرورد تنعم هستم فقط منم که می ترسم از حاشیه امن زندگی خودم بیرون بیام اما ..اما وقتی  اون عضو قدیمی جمعیت ، آمار اعضای جمعیت رو گفت  ..گفت که کل اعضای جمعیت حدود ۱۰ هزار نفر و تعداد  اعضای فعالش حدود ۲ هزار نفر در کل کشور هستن!!!!!!! وقتی اینو به کل جمعیت ۸۰ میلیونی ایران نسبت دادم  فهمیدم نه .....ماها یه چیزی مون هس !!!!ماها چمونه ؟!!!!!!!!!!!!!!تو حاشیه امن محدود زندگیمون ( که هر روز هم این حاشیه محدودتر و محدودتر میشه ) خوبیم کار ثواب می کنیم . برای امام حسین گریه و عزا داری می کنیم  مهم نیس از چه راهی روزی کسب می کنیم ولی نذری میدیم  پول به حساب فقرا میریزیم نماز می خونیم . آسه میریم آسه میاییم .احترام روزه دار رو نگه میداریم  و و و ولی ..............چرا موقع این مدل کارها میرسه خودمونو درگیر نمی کنیم؟ از کنار دیوار یواش میریم یواش میاییم !!!................اون آقای عضو قدیمی جمعیت می گفت بین حاضر بودن و حضور داشتن  خیلی فرق هس !بین گفتن اینکه &quot;من حاضرم کنارت باشم &quot; با   &quot;من اینجا حضور دارم که یارت باشم&quot; خیلی فرق هس چه فایده وقتی او  زیبا هس آراسته هس بوی خوش میده  ثروتمنده سالم و سرحال و خوش اخلاق هس کنارش باشی و باهاش دم خور بشیمهم اینه تو لحظات غصه و غم تو روزای مریضی و بی کسی و بی پولی کنارش باشی. دردش رو بفهمی و تنهاش نزاری مشکلش مشکل تو هم باشه دردش رو درد بکشی و همراهش اشک بریزی . اون آقای عضو قدیمی جمعیت می گفت من دوسال پای علی موندم تا تونست کم کم بهم اعتماد کنه که باور کنه من مثل بقیه نیستم که بیام یه چن شبی بهش رسیدگی کنم یه غذایی بهش بدم و برم می گفت علی حتی یه بار کل پیرهن منو از بالا تا پایین پاره کرد از شدت عصبانیت . بهم فحش های ناموسی داد و.... می گفت اما من پاش وایستادم کنارش موندم و تنهاش نگذاشتم و الان علی  دانشجوی تاتره و تو کار موسیقی و رقص بسیار با استعداد و هنرمند .اون آقای عضو قدیمی جمعیت تونست دست کم یک انسان رو از پرت شدن در منجلاب فساد و بی مروتی و بی اخلاقی نجات دهد . دوسال طول کشید تا اعتمادشو به خودش جلب کنه و الان ۴-۵ ساله که کنارشه راستش عاشقی کردن خیلی سخته !!خیلی سخت !عصر ما دوره انفجار فردگراییه . دوره  ی &quot; من مهم تر از تو و جامعه هستم&quot; دوره آدمهای تنهای بدبخت و منزوی دوره حسرتهای انفرادی دوره ...کی این تنهایی های همه گیر  همه ما منفردها رو یک جا ببلعه خدا میدونه !!!   </description>
                <category>solmaz.oskouie (سولماز اسکویی)</category>
                <author>solmaz.oskouie (سولماز اسکویی)</author>
                <pubDate>Thu, 16 May 2019 23:40:10 +0430</pubDate>
            </item>
                    <item>
                <title>یادداشتهایی بر رهیافت ORM با تاکید بر Hibernate – بخش ششم</title>
                <link>https://virgool.io/@solmaz.oskouie/%DB%8C%D8%A7%D8%AF%D8%AF%D8%A7%D8%B4%D8%AA%D9%87%D8%A7%DB%8C%DB%8C-%D8%A8%D8%B1-%D8%B1%D9%87%DB%8C%D8%A7%D9%81%D8%AA-orm-%D8%A8%D8%A7-%D8%AA%D8%A7%DA%A9%DB%8C%D8%AF-%D8%A8%D8%B1-hibernate-%D8%A8%D8%AE%D8%B4-%D8%B4%D8%B4%D9%85-cpz59hubqnae</link>
                <description>در بخش قبلی در مورد روشهای تولید id در JPA صحبت کردیم . در این مقاله  به بررسی روشها و استراتژی های تولید id در Hibernate خواهیم پرداخت .همانطور که در مقاله قبلی هم گفتیم یکی از ویژگی‌هایی که در مورد انتخاب یک استراتژی تولید id جذاب و مهم است تولید مقدار id برای یک entity جدید قبل از اجرای عمل واقعی insert در db است .در ادامه ۱۲ استراتژی تولید id در Hibernate را خلاصه وار بررسی می کنیم بیشتر آنها در محیطهای عملیاتی  فعلی چندان کاربردی ندارند . 1- استراتژی Native : در این روش انتخاب استراتژی را به عهده DBMS می‌گذارد که می‌تواند Sequence یا Identity  باشد ( بهتر است به مستندات DBMS  مورد استفاده نگاهی بیندازید تا دقیقتر بدانید از چه استراتژی پشتیبانی می‌کند ) این استراتژی هایبرنتی معادل با استراتژی استاندارد JPA یعنی  GenerationType.AUTO  می‌باشد .۲- استراتژی Sequence : در این روش از یک sequence دیتابیسی native بنام  HIBERNATE_SEQUENCE  استفاده می‌کنند در این حالت sequence قبل از هر عمل درج فراخوانی می‌شود . ( به مستندات کلاس  org.hibernate.id.SequenceGenerator مراجعه کنید ) .۳- استراتژی  sequence-identity :  در این روش یک جفت (key,value) تولید می‌شود با فراخوانی  یک db sequence به هنگام درج یک آیتم جدید. مثلاً به این صورت :ITEM(ID) values (HIBERNATE_SEQUENCE.nextval)در این روش مقدار id بعد از عمل درج بازیابی می‌شود درست شبیه استراتژی identity ( به مستندات کلاس org.hibernate.id.SequenceIdentityGenerator  مراجعه کنید ) .۴- استراتژی enhanced-sequence :  در مورد استراتژی  enhanced-sequence باید گفت که مقادیر عددی متوالی تولید می‌کند. اگر DBMS مورد نظر شما  از مفهوم Sequence  پشتیبانی کند، هایبرنت از یک sequence واقعی دیتابیسی استفاده می‌کند ولی اگر DBMS از sequence های native  پشتیبانی نکند هایبرنت از یک جدول sequence اضافی استفاده می‌کند که باهاش رفتار یک آبجکت sequence را شبیه سازی کند . این استراتژی به شما portability واقعی می‌دهد به این معنی که تولید کننده id همیشه می‌تواند قبل تشکیل یک عمل درج sqlی فراخوانی بشود برخلاف  ستونهای id خود افزایشی که لازم است اول عمل درج رخ دهد بعدش مقدار id  به application برگردانده شود .( به مستندات کلاس org.hibernate.id.enhanced.SequenceStyleGenerator مراجعه کنید ) . این روش معادل استراتژی GenerationType.SEQUENCE و GenerationType.AUTO  در استاندارد JPA می‌باشد .۵-  استراتژی seqhilo :  از یک sequence  دیتابیسی native  بنام  HIBERNATE_SEQUENCE استفاده می‌کند . با استفاده از الگوریتم hilo ( مقادیر hi/lo ) مقدار id را قبل از درج entity در db تولید و بهش منتسب می‌کند .۶- استراتژی hilo :اینجا از یک جدول بنام  HIBERNATE_UNIQUE_KEY استفاده می‌شود و همان الگوریتم hilo بکار می‌گیرد با این تفاوت که  این جدول یه سطر و ستون تکی دارد که درش مقدار بعدی sequence را نگه می‌دارد . مقدار پیش‌فرض این عدد  بزرگترین مقدار  32767 است.برای کسب اطلاعات بیشتر در مورد الگوریتم Hilo  به مقاله پیشین مراجعه کنید.۷- استراتژی enhanced-table : از یک جدول بنام  HIBERNATE_SEQUENCES استفاده می‌کند با یک سطر که به طور پیش‌فرض یک sequence را نشان می‌دهد برای ذخیره مقدار بعدی id .  این مقدار select و update می‌شود موقعی یک مقدار برای id تولید می‌شود . شما می‌توانید پیکربندی کنید این تولید کننده id را به طوری که  به ازای یک تولید کننده id بتوانید چندین سطر داشته باشید ( به مستندات   org.hibernate.id.enhanced.TableGenerator مراجعه کنید ) . این روش معادل با روش  GenerationType.TABLE در استاندارد JPA می‌باشد .۸- استراتژی identity : مقدار id برای کلید primary موقع انجام عمل insert‌تولید می‌شود  دارای هیچ optionی نیست . متأسفانه  به علت نواقصی در کد هایبرنت شما امکان پیکربندی اون رو درGenericGenerator  ندارید .  تنها روش برای استفاده از اون  استفاده از  GenerationType.IDENTITY می‌باشد .۹- استراتژی increment : در هر بار که یک سطر جدید می‌خواهد insert بشود مقدار ستون id یک واحد زیادمی شود . این روش برای پروژه های هاییرنتی که در محیط های non-clustered اجرا می‌شوند خیلی کاربردی است . در غیر این صورت در سناریوی دیگر ازش استفاده نکنید .۱۰- استراتژی select : در این حالت خود هایبرنت هیچ مقداری برای id تولید نمی‌کند به عبارت بهتر، موقع  تولید عبارتهای sql  معادل ،جهت  انجام عمل insert حتی ستون id  یا primary key  ضمیمه نمی‌کند. بلکه هایبرنت از DBMS‌انتظار دارد  تا یک مقداری  به ستون primary key منتسب کند بعدش هایبرت  این مقدار ستون primary key را بازیابی می‌کند . این روش چندان کارآمد نیست و فقط  با درایورهای قدیمی JDBC ازش استفاده می‌شود .۱۱- استراتژی uuid2 : یک عدد منحصربفرد ۱۲۸ بیتی UUID در لایه application تولید می‌کند  برای مواقعی خوب است که با چندین db سروکار دارید و می‌خواهید این entity دارای id منحصربفردی مابین همه دیتابیس ها باشد ( مثلاً وقتی که می‌خواهید داده را  از چندین db متمایز  در یک اجرای batch  بازیابی و  مرج کرده و آرشیوش کنید . ) . برای پیکربندی آن از استراتژی org.hibernate.id.UUIDGenerationStrategy استفاده کنید و برای اطلاعات بیشتر به مستندات کلاس org.hibernate.id.UUIDGenerator مراجعه کنید .۱۲- استراتژی guid : از یک  id منحصربفرد سراسری  استفاده می‌کند که توسط دیتابیس با یک تابع sql  قابل دسترس در Oracle,Ingres,Ms SQL و mySql تولید می شود.هایبرنت قبل از عمل درج  این تابع sql را فراخوانی کرده و مقدار با  فیلد id موجود در entity که از نوع String است نگاشت می‌کند . اگر شما نیاز به کنترل کامل این  فرایند تولید id دارید باید از @GenericGenerator استفاده کنید .بعد از مرور تیتر وار روشهای تولید id در Hibernate  نوبت می رسد به توصیه کتاب در مورد انتخاب بهترین استراتژی . در ص ۷۴ کتاب چنین توصیه ای برمی خوریم :To summarize, our recommendations on identifier generator strategies are as follows: In general, we prefer pre-insert generation strategies that produce identifier values independently before INSERT . Use enhanced-sequence, which uses a native database sequence when sup-ported and otherwise falls back to an extra database table with a single column and row, emulating a sequence.</description>
                <category>solmaz.oskouie (سولماز اسکویی)</category>
                <author>solmaz.oskouie (سولماز اسکویی)</author>
                <pubDate>Mon, 13 May 2019 22:47:42 +0430</pubDate>
            </item>
                    <item>
                <title>یادداشتهایی بر رهیافت ORM با تاکید بر Hibernate – بخش پنجم</title>
                <link>https://virgool.io/@solmaz.oskouie/%DB%8C%D8%A7%D8%AF%D8%AF%D8%A7%D8%B4%D8%AA%D9%87%D8%A7%DB%8C%DB%8C-%D8%A8%D8%B1-%D8%B1%D9%87%DB%8C%D8%A7%D9%81%D8%AA-orm-%D8%A8%D8%A7-%D8%AA%D8%A7%DA%A9%DB%8C%D8%AF-%D8%A8%D8%B1-hibernate-%D8%A8%D8%AE%D8%B4-%D9%BE%D9%86%D8%AC%D9%85-sxzg0t99lpsx</link>
                <description>معمولاً در اکثر پروژه های مبتنی بر db فرایند تولید مقدار برای ویژگی id را خودکار در نظر می‌گیرند مگر در موقعیتهای استثنایی که ما مجبور به دستی ست کردن مقدار برای فیلد id باشیم ( یکی از موارد کاربرد می‌تواند به هنگام کار با سیستم‌های قدیمی باشد. ) موقعی که بخواهیم  یک entity را  ذخیره کنیم ، معمولاً  از سیستم می‌خواهیم برای فیلد id یک مقدار را تولید کند . بنابراین روی فیلدی که به عنوان id در نظر گرفتیم ( معمولاً با علامت @Id مشخص می‌شود ) به سیستم با گذاشتن علامت @GeneratedValue روی همان فیلد اعلام می‌کنیم زحمت تولید مقدار برای فیلد Id با تو هست . در این مقاله در مورد مطالب زیر صحبت خواهیم کرد :روشهای تولید id در    JPA الگوریتم Hiloروشهای تولید id در     JPA  در این بخش در مورد روشها و استراتژی های تولید id در  JPA  صحبت می کنیم . ابتدا در مورد استراتژی های تولید id در JPA مزایا و معایب هر یک صحبت می کنیم   در مقاله بعدی سراغ استراتژی های Hibernate می رویم . قبل از اینکه سراغ معرفی استراتژی های تولید id برویم بهتر است چند نکته را مدنظر قرار داشته باشیم :یک -  بخاطر مسایل بهینه سازی ، سیاست Hibernate اغلب این است که عمل درج (insert)   موجودیت ها تا جایی که می تواند به تعویق بیندازد و عمل درج را به صف برده و در نهایت همه درخواستهای insert را به صورت یکجا و دسته ای ( batch) انجام دهد . دو - بخاطر در پیش گرفتن سیاست ذکر شده در بند یک  ترجیح ما (برنامه نویسان ) این است که مقدار id  حتی قبل از عمل insert واقعی در DB  تولید و در دست ما باشد . سه - در اغلب روشها ما با مفهومی بنام Sequence سروکار داریم  که یا در سمت DB توسط DBMS هندل می شود یا توسط Hibernate .  در واقع Sequence یک ویژگی است در دنیای DB . که وظیفه اش تولید مقادیر  منحصربفرد برای ستون های Primary key  در جدول های یک DB است . نکته مهمی که در مورد Sequence باید بهش توجه کنیم این است که فرایند تولید مقادیر id در اغلب DBMS‌ها  خارج از تراکنش رخ می دهد به عبارت دیگر transaction-less است یعنی یک مقدار تولید شده نمی تواند همزمان به چندین تراکنش همروند در حال اجرا منتسب بشود .  مطلب  بعدی در مورد Sequence این است که مقداری که برای یک id تولید می شود اگر به یک تراکنش خاصی منتسب بشود چه اون تراکنش commit گردد و چه rollback بشود مقدار منتسب شده   ازش در جای دیگر استفاده نمی شود .  بخاطر مطالب گفته شده در بندهای یک و دو ترجیح ما در انتخاب استراتژی تولید id این است که نیاز ما برنامه نویسان  از نظر مطالب گفته شده در بند دو را  تامین کند . استراتژی های تولید id در استاندارد JPA در JPA چهار روش برای تولید مقدار برای id وجود دارد :روش Autoروش Identityروش Sequenceروش Tableدر ادامه هر یک را به طور خلاصه بررسی می کنیم :روش Idnetity :این روش توسط  محصولات زیر پشتیبانی می شود :Oracle 12cSQL ServerMySQL (AUTO_INCREMENT)DB2HSQLDBدراین روش مقدار منتسب شده به id برای entity ی که می خواهد در جدول درج بشود تا زمان درج مشخص نیست به عبارت بهتر اول باید عمل درج در جدول رخ دهد بعد مقدار id بدست آید در این حالت اگر در سطح app بخواهیدبلافاصله بعد از عمل درج عمل زیر را برای بازیابی مقدار id انجام دهید ممکن است مقدار null  دریافت کنید someItem.getId()در این روش یک ستون داریم که مقدارش از نوع bigint  یا integer است و به ازای هر عمل درج مقدارش  به ترتیب یک واحد زیاد می شود . پس مقدار تولید  شده فقط در سطح همان جدول منحصر بفرد است . مثال :@Entity(name = &quot;IdentitySample&quot;)public class IdentitySample {     @Id    @GeneratedValue(strategy = GenerationType.IDENTITY)    private Long id;}تذکر : وقتی از این استراتژی استفاده کنید Hibernate عمل درج دسته ای ( batching) را غیر فعال می کند. جدای از غیر فعال شدن JDBC batching این روش با مدل ارث بری Table -per-class هم نمی تواند کار کند  زیرا اون می تواند چندین subclass داشته باشد که دارای یک id  باشند روش Sequence : این روش توسط محصولات زیر پشتیبانی می شود :OracleSQL Server 2012PostgreSQLDB2HSQLDBبرعکس روش قبلی که مقدار تولید شده برای id‌ از نظر منحصربفردی فقط محدود به یک جدول می شد ( به عنوان مثال اگر نام جدول شما student باشد و از روش Identity  برای تولید جدول استفاده کرده باشید در این صورت اگر مقداری برای id تولید بشود برابر ۴۳ باشد در این صورت این عدد فقط در داخل جدول student منحصربفرد است نه جداول دیگر ) . در روش Sequence  یک جا و مکان خاصی برای تولید مقادیر منحصر بفرد وجود دارد و نام آن جا و مکان sequence object می باشد . این روش مستقل از جدول است و مقدار تولید شده توسط این روش در کل دیتابیس منحصربفرد است . این روش معایب روش قبلی را ندارد یعنی  امکان بدست اوردن مقدار id تولید شده حتی قبل از عمل درج واقعی وجود دارد . ( بخاطر استفاده از الگوریتم Hilo که بعدا توضیحش خواهیم داد . ) عمل درج دسته ای ( JDBC batching ) را در Hibernate غیر فعال نمی کند .  همچنین  مدل ارث بری در Hibernate را محدود نمی کند . @Entity(name = &quot;sequenceSample&quot;)public class sequenceSample {    @Id    @GenericGenerator(        name = &quot;sequence&quot; ,        strategy = &quot;sequence&quot;        parameters = {            @org.hibernate.annotations.Parameter(                name = &quot;sequence&quot;,                value = &quot;sequenc&quot;            )     })    @GeneratedValue(generator = &quot;sequence&quot;)    private Long id;}این روش مستقل از DB است و توسط خود Hibernate مدیریت می شود . روش Table  :یک روش جایگزین مستقل از DB دیگری برای تولید id این روش جدول می باشد به طوری از یک یا چند جدول  استفاده می شود تا مقدار id بعدی را در این جدول ها نگهداری کند .  درحالی که دو روش قبلی فارغ از تراکنش هستند (transaction-less)  استفاده از جدول در DB مارا مجبور می کند که  اصول ACID را رعایت کنیم .  برای مدیریت هم روندی چندین درخواست تولید id . این روش بخاطر هزینه های مدیریت هم روندی بالایی که دارد توصیه نمی شود .@Entity(name = &quot;tableSample&quot;)public class TableSequenceSample {     @Id    @GenericGenerator(        name = &quot;table&quot;,        strategy = &quot;enhanced-table&quot;        parameters = {            @org.hibernate.annotations.Parameter(                name = &quot;table_name&quot;,                value = &quot;sequence_table&quot;            )    })    @GeneratedValue(generator = &quot;table&quot;, strategy=GenerationType.TABLE)    private Long id;}الگوریتم Hilo : همانطور که پیشتر گفتیم سیاست هایبرنت این است که عمل درج entity های تازه ایجاد شده تا جایی که می تواند به تاخیر بیاندازد و از طرف دیگر خواسته ما برنامه نویسان این است  بلافاصله بعد از فراخوانی متد persist بتونیم مقدار id را برای آن entity در دست داشته باشیم . برای تامین این خواسته از یک الگوریتمی بنام hilo استفاده می شود این الگوریتم نسخه ها مختلفی دارد و در کل فلسفه ان به این شرح است :به کمک دو مقدار عمل تولید اعداد متوالی منحصربفرد صورت می گیرد و در جایی نگهداری می شودهرموقع appی درخواست id  برای entity خود کرد بهش منتسب کند حتی قبل از اینکه واقعا اون entity در DB درج شده باشد . مراحل الگوریتم :۱- پایه اعداد متوالی را در متغیر high value ذخیره کن ۲- اندازه این توالی از اعداد را در متغیر low value ذخیره کن ۳- مقدار متغیر high value را  بردار  و یک واحد بهش اضافه کن ۴- حال low value را ضربدر high value کن تا کران پایین بدست اید :Lower bound= low value * high value ۵- طبق فرمول زیر کران بالا را محاسبه کن :Upper bounds=(high value * low value) + low value -1حالا اعداد داخل این دو کران را می توان به هر کسی که درخواست مقدار برای id اش می کند تخصیص  داد .در مقاله بعدی در مورد استراتژی های تولید id در خود Hibernate صحبت خواهیم کرد . </description>
                <category>solmaz.oskouie (سولماز اسکویی)</category>
                <author>solmaz.oskouie (سولماز اسکویی)</author>
                <pubDate>Sun, 12 May 2019 22:16:54 +0430</pubDate>
            </item>
                    <item>
                <title>یادداشتهایی بر رهیافت ORM با تاکید بر Hibernate – بخش  چهارم</title>
                <link>https://virgool.io/@solmaz.oskouie/%DB%8C%D8%A7%D8%AF%D8%AF%D8%A7%D8%B4%D8%AA%D9%87%D8%A7%DB%8C%DB%8C-%D8%A8%D8%B1-%D8%B1%D9%87%DB%8C%D8%A7%D9%81%D8%AA-orm-%D8%A8%D8%A7-%D8%AA%D8%A7%DA%A9%DB%8C%D8%AF-%D8%A8%D8%B1-hibernate-%D8%A8%D8%AE%D8%B4-%DA%86%D9%87%D8%A7%D8%B1%D9%85-a1mwp9y3xljw</link>
                <description> در بخش قبل ما در مورد نحوه طراحی و پیاده‌سازی domain model  صحبت کردیم و در ادامه  در مورد مفاهیم  entity و value type ها و نیز نحوه تمییز دادن آن‌ها از همدیگر از روی  UML Diagram  صحبت خواهیم کرد مطالب مورد بررسی دراین مقاله :مفهوم Fine-grained domain modelروشهای شناسایی entity ها و value type  ها در یک domain model مفهوم fined-grained domain model :یکی از اهداف اصلی Hibernate‌پشتیبانی از به اصطلاح fine-grained and rich domain model  است . در‌واقع یکی از دلایل بکارگیری  POJO‌ها همین مفهوم می‌باشد اما معنی این اصطلاح چیه ؟                     به زبان ساده کاری کنیم تعداد کلاسها بیشتر از تعداد table ها باشند !با یک مثال کاربردی منظور را بیان می‌کنیم :فرض کنید در سطح domain model ، ما یک کلاس بنام User داریم این کاربر دارای یک  آدرس محل زندگی  می‌باشد می‌توانیم  این آدرس رو به صورت تعدادی property ( فیلدهای در سطح کلاس ) نمایش دهیم  مثلاً نام شهر ، نام خیابان و پلاک  و….  و از طرف دیگر  همین فیلدها رو به صورت ستونهایی از جدول User  در سطح db   داشته باشیم . اما بجای اینکار ما می‌آییم یک کلاس بنام Address تعریف می‌کنیم که حاوی فیلدهای نام شهر و خیابان و کد پستی و…  باشد . اینکار هم اصل cohesion را بهبود می‌بخشد هم   قابلیت استفاده مجدد از کد را .  بنابراین در سطح domain model  ما دو کلاس بنامهای User و Address داریم در حالی که در سطح db فقط یک جدول User که حاوی آدرس کاربر می‌باشد.شاید این مثال چندان مفهوم را نرساند فرض کنید کلاس User دارای یک فیلد دیگری بنام email باشد شما چطور این فیلد را پیاده سازی می کنید ؟  با افزودن یک فیلد از نوع String ؟ بله ، اغلب برنامه نویسان همین کار را می کنند اما یک روش بهتر و البته کمی پیچیده تر این است که یک کلاس بنام EmailAddress تعریف کنیم و  همه مفاهیم و رفتارهای سطح بالا مرتبط با ایمیل را بهش اضافه کنیم . مانند متد  prepareMail .  البته باید توجه کنید که هیچ کدام از کلاس های domain model  نباید درگیر مفاهیم ارسال ایمیل و ... بشود . اما در سطح db  نیازی به این کارها نیست افزودن یک ستون اضافی برای email کافیست .  دو تا کلاس در سطح app‌داریم در حالی که یک جدول در سطح db . یکی از کلاس ها ( address ) موجودیتش به موجودیت کلاس دیگر (User) بستگی دارد . اگر User حذف بشود ناچارا باید address هم حذف بشود ارجاع به کلاس Address به طور مستقل  امکان پذیر نیست . برای جواب دادن به این سوالات سراغ  بخش بعدی می رویم یعنی مفهوم entity و value type .  روشهای شناسایی entity ها و value type  ها در یک domain model :برای شناسایی entity ها و value type‌ها سه ویژگی را باید بررسی کنیم :1. یک entity class در اغلب موارد نیاز به یک فیلد بنام id‌ دارد . درحالی که یک value type به چنین ویژگی نیاز ندارد . 2. یک entity class دارای چرخه زندگی مستقل به خود است با حذف زدن موجودیت دیگر موجودیت او به خطر نمی‌افتد و زیر سؤال نمی‌رود در حالی که یک value type چرخه زندگیش وابسته به چرخه زندگی یک entity class است . 3. اگر به یک کلاس چندین کلاس دیگر مراجعه می‌کنند این خود می‌تواند نشانه ای باشد که کلاس مورد نظر یک entity class  است .به عبارت دیگر اگر به یک کلاس فقط و فقط یک کلاس مراجعه می‌کند در این صورت این می‌تواند نشانه ای باشد مبنی براینکه اون یک value type است .  در جاهایی به وضوح می‌توان تشخیص داد این کلاس یک entity است یا value type ولی مواقعی  نمی‌توان به این راحتی ها entity‌ها را از value type ها تمییز داد در این موقعیت ها فرض را بر value type می‌گذارند و سعی می‌کنند با بررسی سه شرط بالایی (بخصوص دو شرط آخری )  خلاف آن را ثابت کنند (برهان خلف ) . به شکل زیر توجه کنید ( شکل کتاب ) :دیاگرام ارتباط entity ها با value type ها  در شکل بالایی  دو کلاس Item و User به وضوح مشخص است که entity می‌باشند. کلاس Address هم با توجه به اینکه موجودیتش وابسته به موجودیت User است و فقط User بهش ارجاع داده . اما در مورد Bid چی ؟ از یک طرف وجود Bid به وجود Item وابسته است (با توجه به شکل ، Item مالک bid است ) و اگر Item حذف بشود دلیلی برای نگهداری نمونه‌های bid وجود ندارد . اما اگر در آینده نیاز داشته باشیم که تعداد bid ها یی که یک User ثبت کرده چند تا بوده  در اینجا نیاز است  کمی در مورد چرخه زندگی bid تأمل کنیم . در اینجا درسته که bid چرخه زندگیش وابسته به Item است ولی از طرف دیگر کلاس User نیز نیاز دارد بهش ارجاع کند بنابراین باید برای کلاس bid یک ویژگی id در نظر بگیریم .چرا که در آینده نیاز است به نمونه‌های کلاس Bid به صورت مستقل ارجاع بشود .نکته :سعی کنید ارتباطات مابین entity ها  ساده نگه دارید و از ارتباطات از نوع collection‌های اضافی بپرهیزید .مثلا گذاشتن یک فیلد از نوع کلکسیونی از bid‌ها در داخل کلاس User اصلاً نیاز نیست می‌توانیم آن‌ها را بعداً با نوشتن کوئیری های مناسب هندل کنیم .تذکر : برای فیلد Id نباید متد setter  روی کلاس  تعریف کنیم چرا که این فیلد نباید از بیرون ست بشود . نکته : در مواردی مانند Address که از نوع value type است و وجودش وابسته به وجود یک entity‌ مانند User می‌باشد بهتر است همان لحظه اول ایجاد آبجکت address یک متد constructor تعریف کنیم که فیلد user ش را ست کند. Public class Address {    private User user;     public void Address(User user){      this.user=user;}}</description>
                <category>solmaz.oskouie (سولماز اسکویی)</category>
                <author>solmaz.oskouie (سولماز اسکویی)</author>
                <pubDate>Sun, 12 May 2019 15:47:37 +0430</pubDate>
            </item>
                    <item>
                <title>یادداشتهایی بر رهیافت ORM با تاکید بر Hibernate – بخش سوم</title>
                <link>https://virgool.io/@solmaz.oskouie/%DB%8C%D8%A7%D8%AF%D8%AF%D8%A7%D8%B4%D8%AA%D9%87%D8%A7%DB%8C%DB%8C-%D8%A8%D8%B1-%D8%B1%D9%87%DB%8C%D8%A7%D9%81%D8%AA-orm-%D8%A8%D8%A7-%D8%AA%D8%A7%DA%A9%DB%8C%D8%AF-%D8%A8%D8%B1-hibernate-%D8%A8%D8%AE%D8%B4-%D8%B3%D9%88%D9%85-mtshr3bdnsy5</link>
                <description> سلام با بخش سوم رهیافت ORM با تأکید بر Hibernate در خدمت شما هستم . برای مطالعه و درک این فصل مجبور شدم علاوه بر مطالعه مطالب خود فصل ، سراغ یک روش مدل سازی نرم‌افزار بنام Domain  Driven design  بروم . درک سه مفهوم domain model , business model و data model  کمی برام مشکل و گیج‌کننده بود . برای درک بهتر این روش مدلسازی ، کتاب  Domain Driven Design نوشته   Eric Evans پیشنهاد می‌شود خود من فرصت چندانی برای مطالعه این کتاب نداشتم بنابراین مجبور شدم با خواندن کتابچه ها و مقاله های مرتبط این سه مفهوم رو درک کنم .  در این فصل روی سه   موضوع بیشتر تأکید خواهیم کرد : بررسی سه مفهوم domain 	model , business model  و data model   بررسی بهترین روشهای برنامه نویسی entity ها( 	کلاسهایی 	که اصطلاحاً  بهشان POJO 	گفته 	می‌شود ) و 	استاندارد هایی که در مستندات JPA و Hibernate بهشان تأکید شده است .ارتباط آبجکتها در Hibernate 	  بررسی سه مفهوم domain model , business model  و data model :لطفاً  نگاهی به نمودار زیر بیندازید  ! شکل بالایی مجموعه‌ای از نمودارهای UML را نمایش می‌دهد که برای مدلسازی سیستم بکار می‌روند هریک در موقعیتها و شرایط مختلف و با اهداف و منظورهای گوناگون و مخصوص به خود .  وقتی برای اولین بار شروع به درک و مدلسازی یک سیستم می‌کنید اولین مستنداتی که در حین اینکار تولید می‌شود پایه‌های اولیه مدل سازی بیزنسی (business model ) را تشکیل می‌دهد . خیلی ساده، می‌خواهیم بدانیم این سیستم بایستی چه نیازهایی از مشتری را پاسخ دهد و چگونه / چه موقع  این نیازها را پاسخ دهد . درک سیستم همیشه کار ساده و سرراستی نیست فرض کنید شما قصد مدلسازی سیستم شبیه سازی کنترل ترافیک خطوط هوایی آمریکا را برعهده دارید یا سیستم پرداخت یک بانک را . شما یک برنامه نویس یک طراح نرم‌افزار و در یک کلام شما یک متخصص حوزه IT هستید نه مهندس هواپیما نه مهندس مکانیک نه حسابدار بانک و نه …. برای درک چنین سیستم‌های پیچیده‌ای نیاز به دو عنوان تخصصی در تیم طراحی و تحلیل است :تخصص domain 	expert تخصص business analyst   متخصص domain expert : شخصی است که تخصصصش در حوزه خاصی چون کنترل هواپیما یا حسابداری بانک یا مکانیک اتومبیل و… است کسی که برای درک و مدلسازی سیستم نرم افزاری می‌تواند به شما ( که متخصص IT هستید ) کمک کند . متخصص Business analyst : شخصی است که تخصصش در تحلیل و درک حوزه های تخصصی گوناگون و استخراج فرایندهای پیچیده  و موجودیتهای اصلی در آن حوزه تخصصی است .  شاید تعریفی که ارایه کردم مبهم باشد!  این تعریفی است که ویکیپدیا برای business analyst ارایه کرده است : A business analyst (BA) is someone who analyzes an organization or business domain (real or hypothetical) and documents its business or processes or systems, assessing the business model or its integration with technology. این شخص از نظر من باید مثل یک خبرنگار خبره و سمج و بسیار کنجکاو و باهوش و خیلی با اطلاعات عمومی بالا باشد.این دو متخصص یعنی domain expert و business analyst بایستی برای درک منظور همدیگه و ارتباط گیری باهم از یک زبان مشترک استفاده کنند . معمولاً این زبان مشترک تشکیل می‌شود از نمودارها و اسناد ( نوشتن نحوه کارکرد فرایندها و حتی ضمیمه کردن مستندات کاغذی موجود در محیط عملیاتی مثل فرم‌های ثبت نام / فرمهای گزارش گیری و... ) و حتی دموی نرم افزاری اولیه از کار است یعنی شما یک دمو از سیستمی که مشتری میخواد بسازید و در اختیارش بگذارید و ازش بخواهید به شما فیدبک بدهد که آیا این همان سیستمی است که میخواهد یا نه !برای درک نحوه ارتباط این دو متخصص به کتاب Eric evans مراجعه کنید مکالمه بین این دو شخص خیلی شبیه مصاحبه یک خبرنگار با یک شخصیت مریخی است !فرض کنید شما یه موجود فضایی ( مریخی مثلاً ) گیر انداختید و ازش می‌خواهید براتون نحوه کارکرد یه ماشین زمان دست ساز مریخی ها را توضیح دهد حین مکالمه و پیشرفت کار  انقدر فرمول ها و مفاهیم ریاضی / فیزیکی عجیب غریبی براتون میگوید که حس می‌کنید وسط کار مغزتون سوت می‌کشد و همین الانه که منفجر شود ( حالا نه انقد پیچیده ولی واقعاً کار سخت و پیچیده‌ای است ارتباط این دو متخصص باهم ) .  تذکر : business analyst موقع تحلیل و مدلسازی سیستم اصلاً رویکرد نرم افزاری ندارد به عبارت دیگر اون نباید چنین رویکردی داشته باشد وظیفه او فقط و فقط تحلیل و مدلسازی فرایندها و شناسایی موجودیتهای اصلی سیستم است اینکه بعداً با این مدل (business model ) قرار است چکاری بکنند برایش مهم نیست .خروجی این مرحله business model است این مدل بعداً دست متخصص / متخصصین دیگری می‌رسد بنام software designer / analyst . البته بین دو متخصص business analyst و  software analyst همیشه تعامل و رد و بدل کردن اطلاعات جهت درک درست تر و دقیق‌تر نیازمندهای سیستم  وجود دارد .  همانطور که گفتیم business analyst موقع مدلسازی سیستم اصلاً با رویکرد نرم افزاری جلو نمی‌رود درنتیجه مدلی که ارایه می‌دهد ممکن است با رهیافتها و تکنولوژی ها و راه حل‌های نرم افزاری  همخوانی نداشته باشد برای پر کردن این شکاف از تخصص دیگری بنام طراح نرم‌افزار استفاده می‌شود این متخصصین، سیستم را از نقطه نظر نرم افزاری باز مدلسازی میکنند اصول مهندسی نرم‌افزار را روی آن اعمال کرده، موجودیتهای اصلی سیستم و ارتباطات بین آن‌ها را شناسایی کرده و گاهی حتی نیاز دارند موجودیتهای فرعی دیگری به سیستم اضافه کنند جهت تطبیق با ملاحظات نرم افزاری .خروجی این بخش domain model  است .اگر بخواهیم domain model را تعریف کنیم می‌توانیم اینطوری بیانش کنیم :مجموعه‌ای از entity ها و رابطه بین آن‌ها به همراه ویژگی‌ها و رفتارهای آن‌ها و یکسری قوانین بیزینسی حاکم برعملکرد آن‌ها .  نکته : در رهیافت Domain driven design ما  در مورد نحوه نگاشت business model  به domain model  سروکار داریم . معرفی Anemic domain object :اصطلاح anemic domain object را  اولین بار مارتین فاولر برای  entity هایی بکار برد که فقط حاوی وضعیت (state ) هستند و نه رفتارو آن‌ها را جزو آنتی پترن ها معرفی کرد . طبق گفته فاولر این ایده مخالف  ایده طراحی شی گرایی است چرا که در دنیای شی گرایی وضعیت به همراه رفتار  در یک بسته بنام کلاس بسته بندی می‌شود . در‌واقع معصبین شی گرایی چون فاولر و اریک ایوانس معتقدند اینا object های واقعی نیستند .چرا که با هل دادن همه رفتارهای این آبجکتها به بیرون و داخل سرویس ها شما با یکسری اسکریپت ها روبرو می‌شویدکه فاولر به آن‌ها اصطلاحاً transaction script ها می‌گوید .چنین آنتی پترن هایی در جاوا در تکنولوژی هایی چون EJB entity bean ها بسیار دیده می‌شود . معایبی که برای این مدل object ها بیان می‌کنند عبارتند از :چون منطق یک آبجکت 	در جای دیگری غیر از خودش قرار دارد 	بنابراین اصل encapsulation 	پنهان سازی 	اطلاعات را نقض می‌کند . باعث می‌شود نیاز به یک لایه سرویس داشته باشیم موقعی 	که domain logic  را 	مابین مصرف کنندگان یک domain object  به اشتراک بگذاریم . همچنین باعث می‌شود objectهای domain 	model  نتوانند درستی  خودشان را در هر لحظه از زمان تضمین کنندو نیز نوشتن unit test برای بررسی صحت عمل‌کرد آن‌ها مشکل است . 	  اما از طرف دیگر طرفداران anemic domain object ها برای آن مزایایی در نظر می‌گیرند که عبارتند از :هنگامی که با ORM و تکنولوژی های مرتبط با آن سروکار داریم عمل نگاشت 	ساده‌تر می‌شود ( 	یعنی از پیچیدگی های نگاشت کاسته می‌شود ) 	. مابین data 	 و logic جداسازی رخ می‌دهد ( برنامه نویسی روالی ) . جایگاه domain model entity ها در معماری  سه لایه‌ای  application : همانطور که در شکل بالایی مشاهده می‌کنید domain model  entity ها در یک لایه خاصی ساکن نیستند بلکه توسط همه لایه ها مورد استفاده قرار می‌گیرند . اما نکته مهم اینجاست ، این entity ها به هیچوجه نباید حاوی هیچ concern ی جز قوانین بیزنسی حاکم برآنها باشد . به زبان ساده وقتی کد مربوط به این entity ها رو مشاهده کنید نباید درش هیچ کدی مربوط به باز کردن connection به دیتابیس مشاهده کنید یا باز کردن سوکت جهت  گرفتن مقادیر و ست کردن مقدار property های متعلق به یک entity .  در‌واقع به هنگام پیاده‌سازی  domain model  باید به اصل separation of concern وفادار باشیم.و همیشه مطمئن باشیم  غیر از جنبه‌های businessی ( مانند business rule ها و validation ) در entity های موجود چیز دیگری  در domain model  نشت نکند .سؤال : کی از ORM در پروژه خودمان استفاده نکنیم ؟با توجه به domain model ما می‌توانیم تصمیم بگیریم از ORM استفاده کنیم یا نه . به این ترتیب که اگر app ما business rule های پیچیده‌ای را پیاده‌سازی نمی‌کند یا برهم کنش های پیچیده مابین entity ها وجود ندارد  نیازی نیست سراغ ORM برویم و همان data model  ( همون ارتباط مستقیم با دیتا بیس و جدول ها )  کارمان را  راه می‌اندازد . نحوه پیاده‌سازی Entity های domain model :از بین entity های موجود در domain model  برخی از آن‌ها لازم است وضعیتشان در data store ذخیره شود اما رویکردی که برای ذخیره سازی در ORM و Hibernate اتخاذ می‌شود به گونه‌ای است که به کمک دو مفهوم POJO object ها و meta data‌ها  این موجودیتها را از مسایل/ مکانیسم های ذخیره سازی جدا کنیم. یعنی این آبجکتها با مسایل ذخیره سازی خود را درگیر و آلوده نکنند حتی بی‌خبر از مکانیسم های ذخیره سازی باشند .معرفی POJO ها به عنوان راهکاری برای ساخت domain object ها :POJO یا Plain Old java Object را اولین بار  Martin Fowler, Rebecca Parsons و Josh Mackenzie  در سال ۲۰۰۰ ساختند و مصطلحش کردند .  این آبجکتها حاوی تعدادی attribute هستند که وضعیت (state) جاری آبجکت را نگه میدارند  به همراه یک سری متدهای بیزنسی که رفتار این آبجکتها را توصیف می‌کنند  و در نهایت یکسری ویژگی‌ها( attribute ) که نشانگر رابطه این آبجکت با آبجکتهای دیگر است .در زیر یک مثال از همچین آبجکتی را مشاهده می‌کنید : public class User implements Serializable {protected String username;public User() {}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public BigDecimal calcShippingCosts(Address fromLocation) {// Empty implementation of business methodreturn null;}// ...}  با توجه به این نمونه مثال ویژگی‌ها و best practice هایی که موقع دادن قابلیت ذخیره سازی به آبجکتهای domain باید رعایت کنیم در زیر به صورت خلاصه ارایه می‌شود :در 	JPA ما 	نیازی نداریم آبجکتهایی که قرار است در 	data 	store ذخیره 	شوند واسط java.io.Serializable. 	را پیاده‌سازی کنند . اما اگر این آبجکتها بخواهند در  httpsession‌ 	 ذخیره 	شوند یا بوسیله پروتکل RMI منتقل شوند پیاده‌سازی چنین واسطی لازم است . خود 	این کلاسهایی که قابلیت ذخیره سازی در 	data 	store دارند 	می‌توانند abstract 	باشند 	یا از یک کلاس abstract 	یا 	interface 	ارث 	بری کنند . این کلاسها باید از نوع top 	level باشند به این معنی که ما نمی‌توانیم یک کلاس 	داخلی (inner 	class ) را 	در data 	store ذخیره کنیم . 	  این کلاسها به هیچ وجه نباید از نوع final تعریف بشوندنه خود کلاس و نه هیچ کدام از متدهایش 	. 	این 	در‌واقع یک درخواست از سمت JPA‌است برای کارهای داخلی خودش نیاز دارد این کلاسها و متدهایش final نباشند 	. این 	کلاسها باید حتماً یک constructor  بدون آرگومان ( default constructor ) داشته 	باشند. 	این 	یک نیاز برای JPA 	API‌ ها 	و Hibernate 	API ها 	است چرا که اونا به کمک java 	reflection اقدام 	به ساخت نمونه آبجکتهایی از این کلاسها 	می‌کنند برای انجام کارهای داخلی خود ( 	مثلاً 	ساخت پروکسی آبجکت از آن‌ها برای انجام عملیات بهینه سازی performanceی 	) 	. جالب است بدانید هایبرنت برای دسترسی به 	فیلدهای موجود در این کلاسها نیازی به 	متدهای به اصطلاح getter 	و 	setter 	ندارد . بلکه هایبرنت برای دسترسی به این فیلدها از دو روش استفاده می‌کند و این روشها را 	موقع پیکربندی هایبرنت در فایل پیکربندی 	می‌توانیم بهش اعلام کنیم . 	یکی از این روش‌ها دسترسی مستقیم به فیلدهاست 	روش دیگر دسترسی به فیلدها از طریق همین 	متدهای getter‌و setter می‌باشد دسترسی به وضعیت آبجکت از طریق فیلدها یا از طریق متدهای getter /setter ؟همانطور که قبلاً گفتیم هایبریت به دو طریق می‌تواند به وضعیت یک آبجکت دسترسی داشته باشد دسترسی مستقیم به فیلدها و دسترسی به اون فیلدها از طریق متدهای getter / setter مرتبط با آن‌ها . اینکه کدوم روش بهتر است جای بحث دارد . در اکثر مثال‌ها و نمونه کدهایی که من به شخصه دیدم از روش اول یعنی دسترسی مستقیم به فیلدها استفاده می‌شود ولی دسترسی از طریق متدها دارای یک سری ملاحظات است که باید رعایت بشوند آن ملاحظات به این شرح هستند :در هایبرنت یک مفهومی بنام dirty checking وجود دارد به این معنی که هایبرینت در هر لحظه وضعیت فعلی یک آبجکت ( attached object ) را رصد می‌کند و به محض مشاهده یک تغییر در وضعیت آن سعی می‌کند این تغییر را در data store ذخیره کند و با این sync کردن درستی و consistency اطلاعات را تضمین نماید . در هایبرنت  آبجکتها بوسیله مقدار شان  بررسی می‌شوند  نه بوسیله ID آن‌ها ( یعنی مکانی که در آنجا ذخیره شده است ) تا ببینید نیازی به عمل sync هست یا نه . در این حالت  با اجرای کد زیر عمل syncی با دیتابیس رخ نخواهد داد . public String getFirstname() {return new String(firstname);}	 
 
  
   چون مقدار یکسانی را بر‌می‌گرداند .ولی چنین چیزی در مورد collection ها درست نیست اونها نه با مقدارشان که با مکان ذخیره سازی شان مقایسه می‌شوند به مثال زیر توجه کنید : protected String[] names = new String[0];public void setNames(List&lt;String&gt; names) {this.names = names.toArray(new String[names.size()]);}public List&lt;String&gt; getNames() {return Arrays.asList(names);} در چنین حالتی هایبرنت موقع get کردن تشخیص می‌دهد به روز اوری رخ داده بنابراین یک عمل sync با دیتا بیس را انجام میدهد در حالی که لازم نیس ولی چرا اینکار را می‌کند بخاطر اینکه در هنگام set کردن با arrany سروکار دارد ولی موقع get کردن با list  در‌واقع آبجکت set با آبجکت get فرق دارد . این‌ها نکات ریزی هستند که در محیط های حساس (مثل نرم افزارهای بانکی و مالی ) اگر رعایت نشود ممکن است باعث ایجاد باگ هایی بشود که پیدا کردنشان شاید به این آسانی ها ممکن نباشد .  البته این مثالی که زدیم از نظر منطق هیچ مشکلی ندارد فقط با هر بار get کردن یک عمل sync‌و به روز اوری توی دیتابیس انجام خواهد داد که خب واقعاً لازم نیست .  تذکر :  البته اگر ما روش دسترسی به فیلدها را برای هایبرنت روش مستقیم ا انتخاب کرده باشیم چنین متدهایی  اصلاً تأثیری روی عمل‌کرد هایبرنت نخواهد داشت و هایبرنت این متدها را نادیده خواهد گرفت .  پیاده‌سازی رابطه بین Object ها در هایبرنت :در هایبرینت و ORM برای اینکه ارتباط بین دو آبجکت را نشان بدهیم از مفاهیم one- one ، one-many و many-many  استفاده می‌کنند.گاهی ارتباط دو آبجکت یک‌طرفه و گاهی دو‌طرفه می‌شود .  برای نمایش ارتباط  آبجکت X  با آبجکت Y ، آبجکت Y را به عنوان یکی از property های آبجکت X  اعلان می‌کنیم .  برای توصیف رابطه بین دو آبجکت از مثال کمک می‌گیریم به دیاگرام UML زیر توجه کنید : همچنین کد هریک از کلاس‌ها را در زیر مشاهده می‌کنید : public class Bid {protected Item item;public Item getItem() {return item;}public void setItem(Item item) {this.item = item;}} public class Item {protected Set&lt;Bid&gt; bids = new HashSet&lt;Bid&gt;();public Set&lt;Bid&gt; getBids() {return bids;}public void setBids(Set&lt;Bid&gt; bids) {this.bids = bids;}} رابطه بین این دو آبجکت از نوع one-many‌ است  و همچنین رابطه از نوع دوطرفه است .در کد بالایی در کلاس Item چند نکته برنامه نویسی جالبی وجود دارد بد نیست به آن‌ها اشاره کنیم : protected Set&lt;Bid&gt; bids = new HashSet&lt;Bid&gt;(); در این خط کد علاوه بر اینکه اصل OO یعنی : favor to interface over implementation رعایت شده ( با تعریف کلکسیون از نوع  واسط set ) ، ثانیاً در همان خط اعلان مقداردهی اولیه شده است این مقداردهی اولیه باعث می‌شود از خطای nullPointerException جلوگیری شود .  نکته سوم این است که ما نیاز داریم برای یک آیتم تعداد متمایزی Bid ثبت کنیم و از ثبت عناصر تکراری جلوگیری کنیم برای اینکار بجای لیست از set استفاده کردیم شاید به ذهن بیاید برای کارهای مرتب سازی در سمت UI استفاده از list بهتر باشد ولی باید بگوییم مرتب سازی جزو دغدغه های سطح ذخیره سازی نیست ثالثاً می‌توانیم برای آبجکت bid  فیلدی بنام زمان ثبت سفارش  اضافه کنیم تا بر حسب تاریخ و زمان ثبت ، آن‌ها را سمت UI مرتب کنیم .نحوه مدیریت لینک بین دو آبجکت در کد جاوایی :در جاوا برعکس Sql مدیریت لینک بین این دو آبجکت کمی مشکل و پیچیده است و بهتر است از یک best practice برای این مدل رابطه‌ها پیروی کنیم . برای مدیریت لینک بین این دو از یکسری متد استفاده می‌شود به هنگام نوشتن منطق داخل این متدها یک اصل را باید رعایت کنیم و آن این است :«فرض کن هیچ ORM‌ و Hibernate نیست برای مدیریت لینک دو آبجکت»مورد مهم دوم در مورد رابطه بین دو آبجکت این است از خودمان سؤال بپرسیم :اول مرغ بود یا تخم مرغ .  برعکس دنیای واقعی بایستی یک جواب شفاف برای این سؤال بدهیم . جواب باید یا مرغ باشد یا تخم مرغ . به زبان ساده یکی از دو ابجکت بایستی به عنوان آبجکت اصلی  که قایم به ذات است فرض شود و دیگری به عنوان آبجکتی که وابسته به آبجکت اصلی است .  در مورد مثال بالایی البته مفهوم bid بدون وجود آیتم معنی ندارد . اول باید آیتمی به وجود بیاید تا برای آن bidی ثبت بشود . در چنین سناریو هایی باید موقع نوشتن متدهایی که  لینک بین این دو را مدیریت می‌کند این موضوع را مد نظر قرار دهیم مثلاً وقتی دستور ثبت bid صادر می‌شود باید اول سراغ موجود آیتم برویم ببینم هست و اگر هس براساس آن و از طریق آن آبجکت عمل افزودن bid جدید به لیستش را انجام دهیم . با کد این موارد را نشان میدهیم . anItem.getBids().add(aBid);aBid.setItem(anItem); کد زیر در کلاس item گنجانده می‌شود : public void addBid(Bid bid) {if (bid == null)throw new NullPointerException(&quot;Can&#039;t add null Bid&quot;);if (bid.getItem() != null)throw new IllegalStateException(&quot;Bid is already assigned to an➥ Item&quot;);getBids().add(bid);bid.setItem(this);} یعنی به هنگام مدیریت روابط دو‌طرفه دو موضوع را در کد مد نظر قرار می‌دهیم :اول آن آبجکت bid را به کلکسیون bid های اون آیتم اضافه 	می‌کنیم   دوم اون آیتم را به proerty آن bid ست می‌کنیم   این فرایند کنترلی را مقایسه کنید با آن کاری که در سطح db‌انجام میدهید در آنجا فقط کافیست این قید را اعلان کنید ( حتی به صورت ویزاردی اینکار می‌تواند صورت گیرد ) ولی  همین قید را باید در سطح کد به صورت یک روال پیاده‌سازی کنید .به هنگام تعریف getter و setter  معمولاً برای فیلد  Set&lt;Bid&gt; bids هم این متدها ساخته میشه ولی در اینجا لازم است  کمی با احتیاط رفتار کنیم . به این معنی که ما نباید اجازه بدهیم از بیرون کسی چنین کلکسیونی را ساخته و بی هیچ کنترلی آن را به این فیلد ست کند اصلاً متد کنترلی public void addBid(Bid bid) را برای این ساختیم تا عمل افزودن bid به کلکسیون به صورت کنترل شده صورت گیرد بنابراین نیاز به این متد یعنی setBids(set bids)  نداریم می‌توانیم آن را از سطح کلاس حذف کنیم همچنین برای  متد getter . در مورد این متد نیاز داریم کمی محتاطانه رفتار کنیم بجای اینکه خود کلکسیون را  برگردانیم می‌توانیم کپی آن را  به دنیای بیرون برگردانیم تا مطمين بشیم از بیرون کسی این کلکسیون را تغییر نخواهد داد .  مثلاً با استفاده از این چنین کدی : Collections.unmodifiableSet(bids) Collections.unmodifiableCollection(bids)
 البته این روش و این مدل نوشتن متد getter موقعی مناسب و بهینه است که موقع پیکربندی هایبرنت بهش گفتیم نحوه دسترسی تو به فیلدهای ما از نوع دسترسی مستقیم است نه از طریق متدهای getter , setter .  روش دیگری که می‌توانیم بکار ببریم این است که همان لحظه اول که آبجکت bid ساخته می‌شود مجبورش کنیم حتماً آبجکت item را هم بگیرد با منطق زیر : public class Bid {protected Item item;public Bid(Item item) {this.item = item;item.getBids().add(this);}public Item getItem() {return item;}}
 البته باید توجه کنیم که فیلد های ما نبایستی final تعریف بشوند همچنین  در کلاس bid بایستی صراحتاً یک constructor بدون آرگومان برایش تعریف کنیم.نحوه بکارگیری متادیتا ها برروی persitent object ها :برای اینکه ابزارها و کتابخونه های ORM ی چون هایبرنت بتوانند آبجکتها را به جدول ها نگاشت کنندو حین این نگاشت ملاحظاتی را رعایت کنند نیاز است  از یکسری متادیتا ها استفاده کنیم  استفاده از متادیتا ها راهکار هوشمندی است تا دغدغه هایی که اصلاً مرتبط به domain object ها نیستند وارد حوزه کاری آن‌ها نکنیم بلکه این متا دیتا ها شبه حاشیه نویسی در گوشه کنار کتابهاست و شما اصل متن را مطالعه می‌کنید هر جایی نیاز به توضیح و راهنمایی بیشتر باشد سراغ این حاشیه ها می‌روید .  در هایبرنت دو روش حاشیه نوسی برای این افزودن این متادیتا ها در نظر گرفته :روش افزودن annotation  به 	خود کلاسهای ذخیره شدنی   روش استفاده از فایل‌های خارجی xml ی </description>
                <category>solmaz.oskouie (سولماز اسکویی)</category>
                <author>solmaz.oskouie (سولماز اسکویی)</author>
                <pubDate>Thu, 02 May 2019 18:48:37 +0430</pubDate>
            </item>
                    <item>
                <title>یادداشتهایی بر رهیافت ORM با تاکید بر Hibernate – بخش دوم</title>
                <link>https://virgool.io/@solmaz.oskouie/%DB%8C%D8%A7%D8%AF%D8%AF%D8%A7%D8%B4%D8%AA%D9%87%D8%A7%DB%8C%DB%8C-%D8%A8%D8%B1-%D8%B1%D9%87%DB%8C%D8%A7%D9%81%D8%AA-orm-%D8%A8%D8%A7-%D8%AA%D8%A7%DA%A9%DB%8C%D8%AF-%D8%A8%D8%B1-hibernate-%D8%A8%D8%AE%D8%B4-%D8%AF%D9%88%D9%85-pc3ftqfortcm</link>
                <description> فصل دوم کتاب  Java persistence with Hibernate  به معرفی اجمالی ساخت یک پروژه Hibernateی ساده  می‌پردازد . نمونه کدهایی که در این فصل کتاب آورده شده  بیشتر برای کسانی  قابل فهم  و درک است که چندین و چند سال با Hibernate از همان اوان کودکی و نوجوانی این تکنولوژی همراه بوده و در کنارش رشد کرده‌اند و از نزدیک تغییرات را پیگیری نموده اند . اما برای کسی که یادگیری این تکنولوژی را با  حداقل نسخه ۴ آغاز کرده‌ شاید چندان این نمونه کدها  قابل درک نباشد . هر چند هدف این فصل  ارایه و معرفی ساختار اصلی یک پروژه Hibernateی ساده است که البته در حین سادگی به شما آدرس مفاهیمی چون Distributed Transaction ها  و JTA API ها و پیکربندی یک پروژه Hibernate ی با ماژول نرم افزاری چون Bitronix رو هم میدهد .  در این نمونه کدها شما  اثری از ویژگی‌های یک Data source را نخواهید دید بلکه  فقط در فایل پیکربندی Persistence.xml  شما المنت jta-data-source را مشاهده خواهید کرد ( رجوع به ص ۲۱ کتاب  بخش ۲-۲-۱) .  اگر در اینترنت لابلای کدهای نمونه بچرخید انواع روشهای پیکربندی پروژه Hibernateی را خواهید دید .  و اگر  کل داستان یا دست کم آغاز داستان و دسته بندی های مختلفی که روی پروژه های Hibernate ی و کلاً JPAی اعمال شده را ندانید خیلی زود گیج خواهید شد .  عجیب هم نیست اگر حین مطالعه این کدها سؤالاتی به ذهنتان می‌رسد و دنبال جواب آن‌ها در اینترنت جستجو می‌کنید و می‌بینید دقیقاً و عیناً همان سؤال شما در مثلاً stackoverflow یا بقیه سایتها پرسیده شده ، نشان میدهد این سردرگمی و نامفهومی برامده از کدها  برای اغلب برنامه نویسان تازه کار و حتی کهنه کار قبلاً پیش اومده .  من قبل از اینکه سراغ  ادامه مطالعه این کتاب بروم  ابتدا نشستم برای اولین و آخرین بار این سؤالات و سردرگمی های خودم را برطرف کردم با مطالعه و جستجو در اینترنت . در ادامه همه اون چیزی که  دستگیرم شده را با شما به اشتراک می‌گذارم امیدوارم برای شما هم مفید باشد.  شما برنامه نویس با تجربه عزیز خواهشمندم اگر جایی در متن بنده یا در دسته بندی های ارایه شده توسط بنده اشکالی مشاهده نمودید لطفاً  بهم تذکر بدهید تا هم من متوجه بشم و هم متن را اصلاح کنم .در ادامه ابتدا این دسته بندی ها و مفاهیم ارایه خواهد شد و بعد یک نمونه پروژه ساده Hibernate را مشاهده خواهید کرد سوروس کدش رو هم در github  قابل دسترس دوستان قرار می‌دهم . انواع فایل‌های پیکربندی در پروژه های Hibernate :  وقتی وارد دنیای ORM و بخصوص Hibernate می‌شوید با سه واژه بیشتر برخورد می‌کنید :واژه JPA واژه Hibernate واژه native 	Hibernate بهتر است  معنی دقیق این سه تا را بدانیم بعد سراغ روشهای پیکربندی یک پروژه Hibernate برویم .  عمر پروژه Hibernate خیلی بیشتر از JPA است  اما JPA یک استاندارد است برای دسترسی به  دیتابیس های رابطه‌ای از درون دنیای Object oriented .   یکی از پیاده‌سازی های مشهور این استاندارد Hibernate است  دیگر پیاده سازی مشهورش EclipseLink  می باشد .وقتی جایی سخن از native Hibernate می‌شود باید بدانیم منظور چیست همانطور که گفتیم عمر Hibernate خیلی بیشتر از استانداردJPA است حتی می‌توان گفت ظهور تکنولوژی بنام Hibernate باعث تولد استاندارد JPA شد . اما در خود Hibernate امکاناتی است که خیلی بیشتر و فراتر از ویژگی‌های گفته شده در مستندات JPA می‌باشد (مثلاً orphan removal ) . اگر نیاز به چنین قابلیتها و امکاناتی دارید که فقط در native Hibernate پیاده‌سازی شده است  باید سراغ بسته نرم افزاری Hibernate -core بروید  اما امروزه امکان استفاده از قابلیتهای هر دو  یعنی هم Hibernate ی که استاندارد JPA را پیاده‌سازی می‌کند و هم native Hibernate در یک پروژه وجود دارد .  به طور کلی نیاز نیست از هر دو API استفاده کنید با این همه  اگر درحال استفاده از  Hibernate API ها و فایل پیکربندی hibernate.cfg.xml هستید و همچنین در پروژه شما فایل‌های mappingی چون hbm.xml ها وجود دارد .اما بنابه دلایلی نیاز دارید تا سراغ JPA بروید . خیلی راحت می‌توانید از همان فایل‌های پیکربندی موجود استفاده کرده  تنها کاری که باید انجام بدهید  این است که در فایل persistence.xml  و در داخل المنت hibernate.ejb.cfgfile  به اون فایل پیکربندی موجود یعنی hibernate.cfg.xml ارجاع بدهید .نکته : سعی کنید بسته نرم افزاری hibernate-entitymanager را در داخل پروژه خود استفاده کنید چرا که خود این بسته از بسته نرم افزاری hibernate-core استفاده کرده است .اگر به کدهای نمونه نگاهی بیاندازید دو نوع فایل پیکربندی را زیاد مشاهده خواهید کرد:فایل پیکربندی 	hibernate.cfg.xml   فایل پیکربندی 	persistence.xml   از اولی موقعی که از خود native hibernate بخواهید بهره ببرید باید این فایل را بکار بگیرید و از دومی موقعی که بخواهید از پیاده‌سازی های مرتبط به JPA  مثلاً hibernate استفاده کنید .   در داخل یک فایل پیکربندی Hibernate چه چیزهایی پیدا می‌شود ؟اولین چیزی که در یک فایل پیکربندی باید اقدام به config ش کنیم موجودیتی بنام SessionFactory ( در native Hibernate )  یا EntityManager ( در پیاده‌سازی JPA ) ست .  به ازای هر data-source موردنیاز در یک پروژه ما معادلش به یک sessionFactory / entityManager نیاز داریم که پیکربندیش کنیم .   مورد دیگری که  در داخل فایل پیکربندی بایستی مشخص کنیم نحوه اتصال به یک data-source می  باشد آیا به صورت مستقیم از داخل خود برنامه می‌خواهیم به دیتابیس وصل بشویم یا نه از یک واسطی میخواهیم از یک به اصطلاح حوضچه connection خود به ما یک کانکشن فیزیکی تخصیص دهد .  داخل پرانتز : برقراری اتصال با دیتابیس و کلاً منابع داده‌ ای کار هزینه بری است  ما باید به صورت بهینه  اینکار را انجام دهیم طوری  که یک کانکشن بیهوده باز نماندیا مدت زمان زیادی به صورت idle رها نشود . برای اینکه این موضوع را بهتر درک کنیم بهتر است به چرخه زندگی یک کانکشن دیتابیسی از نزدیک نگاهی بیاندازیم :یک کانکشن به 	دیتابیس از طریق database 	drive  ایجاد 	می‌شود . یک tcp 	socket برای 	خواندن / نوشتن 	داده باز می‌شود . اطلاعات روی اون 	سوکت خوانده / نوشته 	می‌شود . کانکشن ایجاد 	شده بسته می‌شود   سوکت ایجاد شده 	بسته می‌شود . همین باز و بسته شدن سوکت خودش کلی هزینه بر است علاوه بر این اگر فرض کنیم به ازای هر کانکشن یک thread جدیدی ایجاد می‌شود برای مدیریت کارها  میزان این هزینه خیلی زیادتر هم می‌شود . برای صرفه جویی در کار و بهبود performance  برای مدیریت کانکشن ها معمولاً از یک سری واسط هایی استفاده می‌شود بنام connection pool  از معروفترین connection pool ها می‌توان به :فریم ورک HikariCP 	   فریم ورک C3PO اشاره کرد . همانطور که در بالا اشاره کردیم برای بدست آوردن یک کانکشن ما یا از داخل خود پروژه اقدام به اینکار می‌کنیم یا اینکه از یک واسط می‌خواهیم این کانکشن را برای ما فراهم کند  اسم این واسط اغلب اوقات یک application server است بسیاری از application server ها به صورت توکار  از connection pooling پشتیبانی می‌کنند .اگر بخواهیم از application server تا برای ما کانکشن را برقرار کند یکی از روشهای رایج  استفاده از مکانیسم JNDI است . معرفی  کوتاه JNDI :مخفف JNDI یا  Java Naming and Directory  Interface  مکانیسمی است  که به کلاینتهای جاوایی امکان می‌دهد به یک سرویس / آبجکت فقط از طریق نامش  مستقل از مکان دسترسی داشته باشند . یکی از رایج ترین موارد کاربرد آن در تنظیم یک db connection pool روی یک java EE Appliation server  است . اینطوری هر application جاوایی که روی application server به اصطلاح deployا  بشود  می‌تواند به دیتا سورس  از طریق نامشان رجوع کند و درنتیجه با آن‌ها ارتباط برقرار نماید . بدون  اینکه app ما هیچ معلوماتی از دیتابیس  و نحوه کانکشن به آن‌ها  داشته باشد .همین مکانیسم باعث می‌شود وابستگی پروژه ما به یک دیتابیس خاص از بین برود ( البته نه کاملاً بلکه این روش کمک می‌کنید میزان تغییرات در پروژه خیلی کم باشد و تنها قسمتهای خاصی از پروژه تحت تأثیر قرار بگیرد ) .یک پروژه Hibernate ساده همراه با بررسی فایل پیکربندی و نحوه تنظیم و تعریف یک data-source از طریق JNDI :  در ادامه یک پروژه hibernate ساده را مشاهده می‌کنیم که از مکانیسم JNDI برای برقراری ارتباط با  data-source استفاده می‌کند .  بیزنس پروژه :این پروژه  ساده یک رکورد را از دیتا بیس خونده و روی ص وب  نمایش خواهد داد .  تکنولوژی های بکار رفته در این پروژه :بسته maven بسته hibernate 	-core  نسخه 	5-4-1 بسته servlet-api 	 نسخه ۴-۰-۱ دیتا بیس postgres 	  وب سرور tomcat 	نسخه ۹ ابتدا نگاهی به محتویات فایل hibernate.cfg.xml می‌اندازیم : &lt;!DOCTYPE hibernate-configuration PUBLIC&quot;-//Hibernate/Hibernate Configuration DTD 3.0//EN&quot;&quot;http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd&quot;&gt;&lt;hibernate-configuration&gt;&lt;session-factory&gt;&lt;!-- Database Connection Settings --&gt;&lt;property name=&quot;hibernate.connection.driver_class&quot;&gt;org.postgresql.Driver&lt;/property&gt;&lt;property name=&quot;hibernate.connection.datasource&quot;&gt;java:comp/env/jdbc/TestDb&lt;/property&gt;&lt;property name=&quot;show_sql&quot;&gt;true&lt;/property&gt;&lt;!-- SQL Dialect --&gt;&lt;property name=&quot;hibernate.dialect&quot;&gt;org.hibernate.dialect.PostgreSQL9Dialect&lt;/property&gt;&lt;!-- Specifying Session Context --&gt;&lt;property name=&quot;hibernate.current_session_context_class&quot;&gt;org.hibernate.context.internal.ThreadLocalSessionContext&lt;/property&gt;&lt;property name=&quot;packagesToScan&quot;&gt;home.solmaz.hibernatePlusJndi.model&lt;/property&gt;&lt;!-- Mapping With Model Class Containing Annotations --&gt;&lt;mapping class=&quot;home.solmaz.hibernatePlusJndi.model.Employee&quot; /&gt;&lt;/session-factory&gt;&lt;/hibernate-configuration&gt; به این قسمت نگاه کنید :&lt;property name=&quot;hibernate.connection.datasource&quot;&gt;java:comp/env/jdbc/TestDb&lt;/property&gt; مقدار : java:comp/env/jdbc/TestDb در‌واقع از مکانیسم JNDI استفاده می‌کند برای دسترسی به data-source نامی که به این data-source تخصیص داده شده است  jdbc/TestDb می‌باشد . حال بیایید ببینم این اسم چطوری داخل Tomcat تنظیم شده است : برای تنظیم این اسم به دو فایل داخل پوشه Tomcat مراجعه می‌کنید :tomcat home/conf/server.xmltomcat home/conf/context.xml  ابتدا در داخل فایل server.xml در داخل تگ GlobalNamingResources  مقدار زیر را وارد می‌کنیم :&lt;Resource name=&quot;jdbc/TestDb&quot;auth=&quot;Container&quot;type=&quot;javax.sql.DataSource&quot;driverClassName=&quot;org.postgresql.Driver&quot;url=&quot;jdbc:postgresql://localhost:5432/tutorialdb&quot;username=&quot;user123&quot; password=&quot;&quot; /&gt;در مرحله بعدی  در داخل فایل context.xml در داخل تگ context مقدار زیر را وارد می‌کنیم :&lt;Context&gt;&lt;!-- Default set of monitored resources --&gt;&lt;WatchedResource&gt;WEB-INF/web.xml&lt;/WatchedResource&gt;&lt;ResourceLink name=&quot;jdbc/TestDb&quot;global=&quot;jdbc/TestDb&quot;type=&quot;javax.sql.DataSource&quot; /&gt;&lt;/Context&gt;همانطور که می‌بینید همه جا ما براساس نام  jdbc/TestDb  به این data-source مراجعه می‌کنیم . کاری به این که کجا و چطوری تنظیم شده و چطوری ساخته می‌شود نداریم . هر موقع خواستیم با اسمش صداش می‌زنیم و اون آبجکت / سرویس در اختیارمون است .لزومی نمی‌بینم بقیه کدها رو اینجا لیست کنم چیزی عجیب یا جالب و نویی برای توضیح دادن نمی‌بینم کدی ست مثل خیلی از نمونه کدهای موجود در سطح وب . سورس کدها رو روی گیت هاب می‌گذارم تا اگر خواستید clone کرده و روی سیستم خودتون اجراش کنید اگرم سؤالی داشتید من در خدمتم .  لینک کدها در گیت هاب منابع مورد استفاده در این نوشتن و فهم این مقاله :https://www.baeldung.com/java-connection-poolinghttps://stackoverflow.com/questions/20820880/hibernate-native-vs-hibernate-jpahttps://www.baeldung.com/jee-jtahttps://dzone.com/articles/hibernate-5-xml-configuration-examplehttps://stackoverflow.com/questions/3807503/what-is-the-purpose-of-two-config-files-for-hibernatehttps://examples.javacodegeeks.com/enterprise-java/hibernate/hibernate-jndi-example/https://stackoverflow.com/questions/5153556/understanding-jta-spring-and-bitronixhttps://stackoverflow.com/questions/4051273/what-to-put-into-jta-data-source-of-persistence-xmlJPA Tutorial – Setting Up JPA in a Java SE Environmenthttps://docs.oracle.com/javase/tutorial/jdbc/basics/transactions.htmlhttps://www.baeldung.com/jee-jta</description>
                <category>solmaz.oskouie (سولماز اسکویی)</category>
                <author>solmaz.oskouie (سولماز اسکویی)</author>
                <pubDate>Mon, 22 Apr 2019 22:21:35 +0430</pubDate>
            </item>
                    <item>
                <title>آنکه مست آمد .....حکایت این روزهای همه ما انسانها</title>
                <link>https://virgool.io/shojazan/%D8%A2%D9%86%DA%A9%D9%87-%D9%85%D8%B3%D8%AA-%D8%A2%D9%85%D8%AF-%D8%AD%DA%A9%D8%A7%DB%8C%D8%AA-%D8%A7%DB%8C%D9%86-%D8%B1%D9%88%D8%B2%D9%87%D8%A7%DB%8C-%D9%87%D9%85%D9%87-%D9%85%D8%A7-%D8%A7%D9%86%D8%B3%D8%A7%D9%86%D9%87%D8%A7-dgaem4wjypkr</link>
                <description>شازده کوچولو گفت: «اهلی کردن» یعنی چه؟ روباه گفت: این چیزی است که امروزه دارد فراموش می شود. یعنی «پیوند بستن»... - پیوند بستن؟ روباه گفت: البته. مثلاْ تو برای من هنوز پسربچه ای بیشتر نیستی، مثل صدهزار پسربچه ی دیگر. نه من به تو احتیاج دارم و نه تو به من احتیاج داری. من هم برای تو روباهی بیشتر نیستم، مثل صدهزار روباه دیگر. ولی اگر تو مرا اهلی کنی، هردو به هم احتیاج خواهیم داشت. تو برای من یگانه ی جهان خواهی شد و من برای تو یگانه ی جهان خواهم شد... شازده کوچولو گفت: کم کم دارم می فهمم. یک گل هست... که گمانم مرا اهلی کرده باشد...  ...روباه گفت: زندگی من یکنواخت است. من مرغ ها را شکار می کنم و آدم ها مرا شکار می کنند. همه ی مرغ ها شبیه هم اند و همه ی آدم ها شبیه هم اند. این زندگی کسلم می کند. ولی اگر تو مرا اهلی کنی، زندگی ام چنان روشن خواهد شد که انگار نور خورشید بر آن تابیده است. آن وقت من صدای پایی را که با صدای همه ی پاهای دیگر فرق دارد خواهم شناخت. صدای پاهای دیگر مرا به سوراخم در زیر زمین می راند. ولی صدای پای تو مثل نغمه ی موسیقی از لانه بیرونم می آورد. علاوه بر این نگاه کن! آن جا، آن گندم زارها را می بینی؟ من نان نمی خورم. گندم برای من بی فایده است. پس گندم زارها چیزی به یاد من نمی آورند. و این البته غم انگیز است! ولی تو موهای طلایی رنگ داری. پس وقتی که اهلی ام کنی معجزه می شود! گندم که طلایی رنگ است یاد تو را برایم زنده می کند. و من زمزمه ی باد را در گندم زارها دوست خواهم داشت... اگر دوست می خواهی بیا و مرا اهلی کن! شازده کوچولو گفت: چه کار باید بکنم؟ روباه جواب داد: باید خیلی حوصله کنی. اول کمی دور از من این جور روی علف ها می نشینی. من از زیر چشم به تو نگاه می کنم و تو هیچ نمی گویی. زیان سرچشمه ی سوءتفاهم هاست. اما تو هر روز کمی نزدیک تر می نشینی... ... پس شازده کوچولو روباه را اهلی کرد. و چون ساعت جدایی نزدیک شد روباه گفت: آه!... من گریه خواهم کرد... سپس گفت: برو دوباره گل ها را ببین. این بار خواهی فهمید که گل خودت در جهان یکتاست. بعد برای خداحافظی پیش من برگرد تا رازی به تو هدیه کنم. شازده کوچولو رفت و دوباره گل ها را دید. به آن ها گفت:  شما هیچ شباهتی به گل من ندارید. شما هنوز هیچ نیستید. کسی شما را اهلی نکرده است و شما هم کسی را اهلی نکرده اید. روباه هم مثل شما بود. روباهی بود شبیه صدهزار روباه دیگر. ولی من او را دوست خودم کردم و حالا او در جهان یکتاست. و گل ها سخت شرمنده شدند. شازده کوچولو باز گفت:  شما زیبایید، ولی جز زیبایی هیچ ندارید. کسی برای شما نمی میرد. البته گل هم مرا رهگذر عادی شبیه شما می بیند. ولی او یک تنه از همه ی شما سر است، چون من فقط او را آب داده ام، چون فقط او را زیر حباب گذاشته ام، چون فقط برای خاطر او کرم هایش را کشته ام (جز دو سه کرم برای پروانه شدن)، چون فقط به گله گزاری او یا به خودستایی او یا گاهی هم به قهر و سکوت او گوش داده ام. چون او گل من است. سپس پیش روباه برگشت. گفت: خداحافظ. روباه گفت: خداحافظ. راز من این است و بسیار ساده است: فقط با چشم دل می توان خوب دید. اصل چیزها از چشم سر پنهان است. شازده کوچولو تکرار کرد تا در خاطرش بماند: - اصل چیزها از چشم سر پنهان است. روباه باز گفت: - همان مقدار وقتی که برای گلت صرف کرده ای باعث ارزش و اهمیت گلت شده است. شازده کوچولو تکرار کرد تا در خاطرش بماند:  - همان مقدار وقتی که برای گلم صرف کرده ام... روباه گفت:  آدم ها این حقیقت را فراموش کرده اند. اما تو نباید فراموش کنی: تو مسؤول همیشگی آن می شوی که اهلیش کرده ای. تو مسؤول گلت هستی... شازده کوچولو تکرار کرد تا در خاطرش بماند: - من مسؤول گلم هستم. </description>
                <category>solmaz.oskouie (سولماز اسکویی)</category>
                <author>solmaz.oskouie (سولماز اسکویی)</author>
                <pubDate>Mon, 22 Apr 2019 12:28:44 +0430</pubDate>
            </item>
                    <item>
                <title>یادداشتهایی بر رهیافت ORM با تاکید بر Hibernate – بخش اول</title>
                <link>https://virgool.io/@solmaz.oskouie/%DB%8C%D8%A7%D8%AF%D8%AF%D8%A7%D8%B4%D8%AA%D9%87%D8%A7%DB%8C%DB%8C-%D8%A8%D8%B1-%D8%B1%D9%87%DB%8C%D8%A7%D9%81%D8%AA-orm-%D8%A8%D8%A7-%D8%AA%D8%A7%DA%A9%DB%8C%D8%AF-%D8%A8%D8%B1-hibernate-%D8%A8%D8%AE%D8%B4-%D8%A7%D9%88%D9%84-sza9tj3tzg1d</link>
                <description> سلام  بعد مدتها فرصت شد شروع به مطالعه یک کتاب تخصصی در مورد ORM کنم. یکی از بهترین کتاب‌هایی که تو این حوزه نوشته شده است کتاب Java persistence with Hibernate می باشد. قبلاً براساس نیاز و وقتم مقالات پراکنده‌ای در مورد ORM به‌خصوص Hibernate خونده بودم ولی هیچ‌ موقع  فرصت / قسمت / اراده  نشد تا به صورت مفهومی و عمیق در مورد این حوزه مطالعه‌ای داشته باشم.  چند روزی است مطالعه کتاب مذکور را شروع کردم  با مرور سرفصل هاش انتظار داشتم خیلی زود  چند فصل اول را تمام کرده  و به مباحث مورد نظرم برسم ولی از همان فصل اول کتاب ، انقدر مفاهیم  مفهومی و عمیق و چرایی ضرورت رفتن سراغ این رهیافت ( ORM ) برایم جذاب آمد که تصمیم گرفتم قلم برداشته و نکات مهم و جالبش را یادداشت کنم .  وسطهای نوشتن روی کاغذ به ذهنم رسید چرا این مطالب را با دوستان همکار و علاقه مندم به اشتراک نگذارم  شاید حین مطالعه ،من مفاهیمی را درست متوجه نشده  یا از چندین جنبه بررسی نکرده و ندیده باشم، اینطوری می‌توانم از دیدگاه‌ها و تجربیات دوستان هم صنفی خودم استفاده کنم!  خیلی خوشحال میشم  نظرات خودتون را با من به اشتراک بگذارید اشتباهات لفظی / معنایی و تفسیریم را تذکر دهید .من نیت و قصدم این است با مطالعه هر فصل کتاب ، مقاله‌ گونه‌ای  تهیه کرده و با شما به اشتراک بگذارم .  این مقاله  اولین نوشته از سلسله نوشتارهای من در مورد ORM و بخصوص Hibernate است .  لطفاً منو همراهی کنید….در هر پروژه نرم افزاری تصمیم گیری در مورد نحوه ذخیره سازی  داده‌ها  یک تصمیم گیری از جنس طراحی ست . البته صرف ذخیره سازی داده  مهم نیست  بلکه  بحث  integrity و یکپارچگی داده و اطلاعات نیز مطرح است( اگر قصدمان فقط ذخیره داده است همون سیستم  فایل کافیست  اگر  از دروس و کتاب‌های دوره کارشناسی و درس پایگاه داده‌ها یادمان باشد سیستم‌های مدیریت پایگاه داده‌ها برای این به وجود آمدنده اند تا یکسری از مشکلاتی که در سیستم ذخیره سازی فایلی بود برطرف و راهکارهای جدیدی برای مدیریت داده ارایه دهند طوری که کل داده‌ها و اطلاعات برامده از آن‌ها دارای دو ویژگی integrity و  consistency باشند و همچنین با مطرح کردن مباحثی مثل نرمال سازی  مشکل افزوونگی داده‌ها ( redunduncy ) را نیز برطرف یا کمینه کنند ) .  اما چرا ORM ؟قبل از اینکه سراغ ORM برویم بیاید نحوه ذخیره سازی / بازیابی داده‌ها در/ از پایگاه داده را در یک زبان برنامه نویسی شی گرا مرور کنیم :۱- اول از همه نوع پایگاه داده را مشخص می‌کنید مثل Mysql یا Postgres یا …  ۲- براساس انتخابتون در مرحله اول سراغ دانلود و گرفتن کتابخونه API های اون پایگاه داده جهت استفاده در زبان برنامه نویسی انتخابی خود می‌روید ( در‌واقع به ازای هر سیستم مدیریت پایگاه داده‌ها  یک کتابخانه معادلی  در اکثر زبانهای برنامه نویسی رایج دنیا وجود دارد که امکان ارتباط  با یک پایگاه داده از داخل یک زبان برنامه نویسی فراهم می‌کند).۳- بعداز افزودن و معرفی این کتابخانه به ClassPath پروژه خودتون ، سراغ معرفی کردن مشخصات دیتابیس موردنظرتون به پروژه  می‌روید از جمله اینکه نام بانک اطلاعاتی مورد نظر شما در DBMS  چیست ( آدرس Url اون بانک اطلاعاتی را معمولاً می نویسید طبق سینتکس مشخص مثلاً student_db ) ،  با چه نام کاربری و رمزی  و روی چه  سرور و  پورتی باید به این بانک اطلاعاتی  وصل بشوید  و اگر سیستم DBMS شما از نوع رابطه‌ای است اصطلاحاً لهجه (dialect ) SQL ی اون DBMS چی هست  در همون جا اعلام می‌کنیدو یکسری اطلاعات اضافی دیگری برحسب اینکه پروژه شما چقدر بزرگ و پیچیده باشد، ولی اطلاعات پایه‌ای  تقریباً این‌ها هستند.  ۴- ساخت یک کانکشن با دیتابیس جهت بازیابی / ذخیره اطلاعات  ۵- نوشتن کوئیری های مورد نظر و انجام دونه دونه  عمل نگاشت ویژگی‌های آبجکت خود به ستون‌های جدول   ۶-  اجرای کوئیری و گرفتن نتایج و  این بار نگاشت  ستونهای جدول به ویژگی‌های آبجکت موردنظرتون ( در داخل یک حلقه ).۷- بستن کانکشن۸- مدیریت خطاها و exception ها در صورت لزوم  ببینید همه این ۸ مرحله  تقریباً در همه زبانهای برنامه نویسی  شی گرا تکرار می‌شود مهم نیست پروژه شما در چه حوزه ای باشد و بیزنس کار چطوری باشد یا ساختار به اصطلاح  domain model شما چیست و چقدر بزرگ یا کوچک است  این کارهای تکراری در تمامی پروژه ها توسط برنامه نویسان شی گرا باید تکرار بشود.  در دنیای مهندسی نرم‌افزار و کلاً طراحی سیستم یک اصلی است بنام Separation of concerns  به این معنی که سیستم را طوری باید طراحی کنید که هرکس بر حسب تخصص خود در هر مرحله از کار فقط روی یک موضوع تمرکز کند این کارهای تکراری هم مستقل از بیزنس کار هستند و می‌توان انجام آن‌ها را به یک ناظر بیرونی و سطح بالاتر (مثلاً کتابخانه / فریم ورک ) تخصیص داد و لازم نباشد برنامه نویس درگیر باز و بسته  کردن کانکشن و نگاشت آبجکت /ستونهای جدول و … باشد در ثانی برنامه نویس شی گرا نباید درگیر  مباحث زبانهای دیتابیسی مثل Sql باشد آن هم در این سطح وسیع .تذکر :  داخل پرانتز باید یادآور بشوم اول به خودم بعد به مخاطبین این مقاله که دروغه این حرف! برای یک برنامه نویس خوب شدن برای یک معمار و طراح نرم‌افزار خوب شدن باید به حوزه وسیعی ازتخصص ها و فیلدها وارد بشوید در حد لزوم از هرکدام اطلاعاتی داشته باشید به عنوان مثال  در همین برنامه نویسی شی گرایی هنوز سناریوهایی پیش میاد که راهکارهای ORM نه تنها کمکی به ما نمی‌کند بلکه دست و پای ما رو هم از نظر فنی هم از  نظر Performance ی می‌بندد و ما ناچاریم با همان Sql خام در داخل محیط برنامه نویسی شی گرایی خودمان  با دیتابیس ارتباط بگیریم .  همچنین برای tune کردن performance پروژه های Hibernate نیاز به داشتن دانش عمیقی  در حوزه SQL هستیم .مطالبی که عنوان شد  درو واقع اولین انگیزه برای رفتن سراغ رهیافت ORM است.  همچنین یکی از دلایل روی آرودن به ORM این است که  این روش کمک می‌کند نگهداری و قابلیت استفاده مجدد کد آسان تر صورت گیرد .  اما  این‌ تنها دلیل نیست بین پارادایم Relational و Object-oriented یکسری عدم تطبیق هایی ظاهر می‌شود که خود دلیل مهمی دیگری است جهت رفتن به سراغ تکنولوژی های مبتنی بر ORM .در‌واقع مشکل در جایی خودش را نشان میدهد که در سطح domain model ( جایی که شما یکسری entity دارید برای ذخیره سازی در سطح دیتابیس )  تعداد زیادی entity دارید با سلسله مراتب مختلف و روابط زیاد بین آن‌ها .  حال این عدم تطبیق ها چیا هستن  عدم تطبیق ها  عبارتند از :عدم تطبیق در 	سطح دانه بندی (granularity) 	  عدم تطبیق در 	سطح سلسله مراتب و مبحث ارث بری   عدم تطبیق در 	حوزه Identity عدم تطبیق در 	رابطه با مفهوم association عدم تطبیق در 	حوزه پیمایش داده‌ها   حال به نوبت هر یک را بررسی می‌کنیم :عدم تطبیق در سطح دانه بندی (granularity)مفهوم granularity :گاهی به هنگام نگاشت  آبجکت ↔ جدول  نیاز است  یک آبجکت به چندین جدول  نگاشت بشود یا چندین آبجکت به یک جدول . در اینجا یک رابطه یک به یک بین تعداد و اندازه آبجکتها و جدولها وجود ندارد  برای حل این مشکل راه حل‌های مختلفی ارایه شده است . به مثال زیر توجه کنید    در سطح پروژه ما دو تا موجودیت داریم  بنام های User و billingDetails . همچنین در سطح دیتابیس نیز دوتا جدول به همین نام داریم اما حین کار فرض کنید ما یک موجودیت دیگری بنام Address  لازم داریم تعریف کنیم  تا آدرسهای  یک کاربر را درش نگه داریم. بزارید طور  دیگری این موضوع را  بیان کنم  درسطح کلاس طراح ما به هردلیل منطقی نیاز دارد  یک موجودیتی بنام address تعریف کند تا هر موجودیت مستقل دیگری که نیاز به ذخیره آدرس داشت بتواند این موجودیت فرعی ( موجودیتی که به خودی خود در bussiness model ما و در domain model ما  وجود ندارد بلکه بخاطر نیاز موجودیتهای اصلی این موجودیت عینیت و وجود پیدا می‌کند ) را مورد ارجاع قرار داده و ازش استفاده کند .  public class User {	String username;	Set&lt;Address&gt; addresses;	Set&lt;BillingDetails &gt; billingDetails;	// Accessor methods (getter/setter), business methods, etc.}public class BillingDetails {	String account;	String bankname;	User user;	// Accessor	 methods (getter/setter), business methods, etc.}حال سؤالی که مطرح است اینکه آیا چون در سطح برنامه  ما سه تا موجودیت داریم ( دو موجودیت اصلی و یک موجودیت فرعی )  باید همین تعداد هم در سطح دیتابیس ، جدول  داشته باشیم ؟جواب مسلماً خیر است . روشهای مختلفی برای حل این موضوع است یک روش این است که تمام فیلدهای موجودیت آدرس رو در همان جدول User  کنار بقیه فیلدها کپی کنیم  چون واقعاً نیازی نداریم این رکوردهای آدرس را جدا از موجودیت اصلی شان یعنی user بازیابی / ذخیره سازی کنیم . این روش به نظر روش بهتری است اما روشهای دیگری هم وجود دارد ازجمله اینکه بیاییم از امکانات ارایه شده در سطح DBMS ها  بنام User  defined datatype ها استفاده کنیم . یعنی در سطح دیتابیس بیاییم یک نوع داده بنام address تعریف کنیم بعد یک ستون به جدول user اضافه کرده و نوع داده اش را از نوع address قرار بدیم . اشکالی که این روش دارد این است که کاملاً وابسته به محصول DBMS ی است که ازش درحال حاضر استفاده می‌کنیم و همه vendor ها این موضوع را به یک روش استاندارد پیاده نمی‌کنند .  روشهای نگاشت رو در ادامه و در مقاله های آتی ( اگر عمری باقی باشد ) با جزییات  بیشتری بررسی خواهیم کرد.نکته : در جاوا سطوح  مختلفی از دانه بندی وجود دارد از دانه درشتهایی بنام کلاس گرفته  تا دانه‌های متوسطی به اصطلاح value object ها  تا دانه‌های ریزی  چون enum ها و مجموعه های  شمارشی . . این درحالیست که در سطح دیتابیس ما دو سطح دانه بندی بیشتر نداریم .  دانه درشتی بنام جدول  و دانه‌های ریزی بنام انواع داده‌های توکار مثل number و char و varchar و datetime و…  عدم تطبیق در سطح سلسله مراتب و مبحث ارث بری :در سطح برنامه نویسی ما در حوزه data model ها  مفهومی بنام inheritance داریم  درحالی که چنین چیزی در سطح db مشاهده نمی‌کنیم .  از طرف دیگر وقتی مبحث inheritance  مطرح می‌شود بلافاصله به دنبالش  مفهوم polymorphism  هم به میان می‌آید  به مثال توجه کنیم :در سطح برنامه نویسی در زمان اجرا  یک نمونه آبجکت از کلاس user می‌تواند به  یک نمونه از زیرنوع های BillingDetails مراجعه کند ( که این می‌شود polymorphism در سطح آبجکت ). به طور مشابه شما می‌خواهید قادر به نوشتن  polymorphic query هایی  باشید  که به کلاس BillingDetails ارجاع کرده و آن query بتواند نمونه‌هایی از زیر کلاس هایش برگرداند .در سطح دیتابیس ما مفهومی بنام کلید خارجی داریم که ارتباط دو جدول را نمایش میدهد  ولی فعلاً قادر نیستیم روش استانداردی و مستقل از DBMS خاص  در پیش بگیریم بطوری که اون کلید خارجی  موجود در جدول user علاوه بر اینکه به جدول BillingDetails ارجاع می‌کند بتواندبه هر کدام از زیرکلاس های اون BillingDetails نیز مراجعه کند . به عبارت دیگر کلید خارجی فقط می‌تواند به یک جدول خاص ارجاع کند نه چندین جدول . از طرف دیگر باید مکانیسمی داشته باشیم تا بتوانیم ساختار سلسله مراتبی مانند تصویر بالایی رو بدهیم به RDBMS و اون موقع بازیابی وjoin بتواند تشخیص دهد که الان باید جدول user را با مثلاً BillingDetail  جوین کند یا با bankAccountعدم تطبیق در حوزه Identity :در زبان جاوا برابری دو obj ( اینکه بدانیم آیا a همان  b است و نیز b همان a است ) دو روش وجود دارد:a==b   a.equals(b) یعنی a و b هر دو به یک مکان حافظه heap اشاره کنند و همچنین از نظر دو متد equals و hash مقدار true برگرداند یعنی ویژگی هاشون نظیر به نظیر مقدار یکسانی داشته باشند و کد hash تولیدشان برابر با هم .  این موضوع درسیستم های مالی خیلی اهمیت دارد .  در سطح دیتابیس ولی برابری دو آبجکت فقط از طریق مفهومی بنام primary key تعریف می‌شود . یعنی اگر هر دو آبجکت دارای primary key یکسانی باشند در نتیجه یکی هستند . Primary key ها در محیط های multi threading نقش حیاتی بازی می‌کنند بخصوص در مباحث caching و transaction ها .  عدم تطبیق در رابطه با مفهوم association :در domain model  مفهوم  association  رابطه بین entity ها را نمایش میدهد . عمل نگاشت association و مدیریت ارتباط بین entity ها جزو مفاهیم مهم در هر رهیافت ذخیره سازی آبجکت است . در زبانهای شی گرایی  مفهوم association با object reference نمایش داده می‌شود. در سطح دیتابیس این مفهوم با قید کلید خارجی .  این قیدها و بخصوص قید کلید خارجی  یکپارچگی ارتباط بین جداول و موجودیتها را تضمین می‌کند . در سطح زبان این ارتباط بین موجودیتها ذاتاً جهت دار است  و اگر در موقعیتهایی نیاز باشد  این رابطه دو جهته باشد  به صورت زیر تعریف می‌کنیم :public class User {set&lt;BillingDetails&gt; billingDetails;}public class BillingDetail {User user;}اما در سطح دیتابیس اینکه ارتباط دو موجودیت در چه جهتی باشد اصلاً چنین چیزی مفهوم و معنی ندارد .درآنجا با عملگرهای join و projection می‌توانیم این association را معنی می‌کنیم (حتی نیازی نیست بین دو جدول حتماً از طریق کلید خارجی ارتباطی وجود داشته باشد ) . د رمقاله های بعدی نحوه مدیریت ارتباط موجودیتها در سطح زبان و چگونگی نگاشت آن‌ ارتباط ها در سطح دیتا بیس بیشتر خواهیم آموخت .عدم تطبیق در حوزه پیمایش داده‌ها :شاید مشکل‌ترین  مسأله در حوزه  ذخیره سازی آبجکت  مسأله پویایی باشد  اینکه چطور  یک داده در زمان اجرا مورد دستیابی قرار گیرد .  در سطح زبان برنامه نویسی  نحوه دسترسی به یک آبجکت به این صورت است :someUser.getBillingDetail().iterator().next();یعنی دسترسی به یک آبجکت به صورت پشت سرهم و به روش پیمایشی در یک شبکه مفهومی از آبجکتهاست . اما چنین روشی در سطح db امکان‌پذیر نیست . در سطح دیتابیس تنها راهی که شما به هنگام دسترسی به داده‌ها باید انجام دهید این است که تعداد درخواستهای کمتری به سمت دیتابیس بفرستید تا performance سیستم بالا برود .  اما اینکار مستلزم این است که شما همه آبجکتهایی که لازم دارید را با تعداد join های بیشتری بازیابی  کنید و این کار باعث هدر رفت حافظه می‌شود البته با روشهای پیچیده‌ای چون حاغظه کش ثانویه می‌توان تاحدودی این موارد را بهبود بخشید . اما اینکار یعنی شما علاوه بر داده / آبجکتهای مورد نیاز  داده‌های  غیر ضروری زیادی هم بازیابی می‌کنید . بهترین کار این است که دقیقاً بدانید  چه بخشی از شبکه  آبجکتها رو می‌خواهید مورد دسترسی قرار دهید.   در مقاله های بعدی در مورد مفهوم Lazy loading و مسأله  n+1 select  بیشتر خواهیم آموخت .  پا نوشت :  تئوری CAP  :طبق تئوری  Consistent ,Available, Partition tolerant   (CAP)  یک سیستم توزیع شده نمی‌تواند همزمان هر سه فاکتور consistency ، availablity و tolerancy را  تأمین کند .  Consistent : یعنی همه نودها در شبکه داده‌های یکسانی را ببینید  Available :  همه درخواست های ارسال به سرور حتماً یک جوابی مبنی بر موفقیت آمیز بودن یا نبود درخواستشان دریافت کنند  Partition tolerant :  حتی در صورت پیش آمد شکست سیستم بتواند به کار خودش ادامه دهد .  مثلاً اگر سیستم در حال تحمل بار زیادی است و امکان ارایه سرویس به کاربر نیست  واضح به کاربر اعلان کند که لطفاً چند دقیقه دیگر  مراجعه فرمایید سیستم در حال حاضر قادر به پاسخگویی نیست ( سایت فروش خودروها و اغلب سایتهای دولتی  و دانشگاهی خوشبختانه این اصل را  کاملاً رعایت می‌کنند!!!!! ) .بخش دوم مقاله بخش سوم مقاله بخش چهارم مقالهبخش پنجم مقاله  بخش ششم مقاله </description>
                <category>solmaz.oskouie (سولماز اسکویی)</category>
                <author>solmaz.oskouie (سولماز اسکویی)</author>
                <pubDate>Wed, 17 Apr 2019 14:43:43 +0430</pubDate>
            </item>
            </channel>
</rss>