نظرات نظرسنجی‌ها
کدامیک از روش‌های زیر را برای تولید App های موبایل ترجیح می‌دهید؟ چرا؟
با فرض این که یک تیم با تجربه به هر سه روش مسلط باشند، این انتخاب کاملا به کاربرد اپلیکیشن مورد نظر بستگی دارد. ضمننا در هزینه تمام شده (تولید، توسعه، نگهداری) نرم افزار هم موثر است.
در صورتی که یک برنامه نویس بخواهد روشی انتخاب کند بسته به شرایط برنامه نویس متغییر است. 
  • پس زمینه برنامه نویسی
  • تکنولوژی هایی که مسلط است
  • چقدر وقت دارد چیز جدید یاد بگیرد
Cross-platform خودش چند مدله (معروف‌تر هاش این موارد):
  • HTML+JS +WebView (Cordova)
  • C#+ XAMARIN
  • HTML+JS+ Native Run (Native Script)
...
نظرات نظرسنجی‌ها
شما بودید چی کار می‌کردید؟

رفته سراغ جاوا. احتمالا از همین رانتی‌ها هست که این توانایی رو داره هر چند ماه یکبار بودجه‌ای رو بگیره، درصد عمده‌ای رو پورسانت خودش مصرف کنه (*)، دوباره سیستم رو از نو بده بنویسن. دوباره این فرآیند تکرار میشه تا روزی که این شخص بره به یک سازمان دیگر. نرم افزار هم بیشتر در این جاها جنبه‌ی تزئینی داره.

(*) این شیوه که سابقا بهش رشوه می‌گفتن در این نوع کارهای رانتی زیاد معمول هست. مثلا پروژه x میلیون تومن هست. همین x میلیون هم دقیقا در قرارداد ذکر میشه اما شما زمانی به این قرار داد می‌رسی که نزدیک به 30 درصد یا بیشتر پول دریافتی رو تقدیم طرف امضاء کننده کنی.

خیلی‌ها درگیر این مسایل هستند متاسفانه.

نظرات مطالب
مدیریت فایلهای یک پروژه نرم افزاری با استفاده از Subversion
با تشکرهای نامتنناهی برای تهیه این جزوه که اتفاقا این روزها خیلی برای من مفید بوده . ما توی شرکت همراه با اس وی ان . از این دوتا هم استفاده میکنیم :
http://en.wikipedia.org/wiki/FishEye_(software)

http://en.wikipedia.org/wiki/Crucible_(software)
مطالب
#Defensive Code in C - قسمت چهارم
 Automated Code Test

با توجه به فاکتور‌های موجود در Defensive Coding، یکی از مواردی که کیفیت کد شما را تضمین خواهد کرد، استفاده کردن از (ACT) Automated Code Test می‌باشد. در این قسمت قصد داریم مزایای تست اتوماتیک و Unit Test را به عنوان یکی دیگر از ابعاد Defensive Coding ذکر کنیم.


به عنوان برنامه نویسی که در حال توسعه کد هستید و قابلیت‌های جدیدی را به کد خود اضافه می‌کنید، باید کدی را که در آن تغییر ایجاد می‌کنید، مرتب تست کنید، تا بررسی کنید که آیا به هدف خود رسیده‌اید و توانسته‌اید قابلیت جدیدی را در نرم افزار اضافه کنید. روشی که توسط اکثر برنامه نویسان انجام می‌شود به این صورت است که به‌صورت متوالی برنامه را اجرا می‌کنند، اجرا می‌کنند، اجرا می‌کنند و باز هم اجرا می‌کنند، تا اینکه مطمئن شوند همه چیز درست است. بیشتر زمانیکه در این فرآیند صرف می‌شود، صرف کارهای تکراری می‌شود. این مسئله بدون شک برای بسیار از برنامه نویسان پیش آمده است و ممکن است بعضی از این برنامه نویسان به دنبال راه چاره‌ای بوده باشند و بعضی‌ها هم با انجام دادن این روش تست، هیچ مشکلی نداشته باشند. اما مسئله‌ای که غیر قابل چشم پوشی است، این است که این روش انرژی و زمان بسیار زیادی را از برنامه نویسان می‌گیرد؛ راه حل چیست؟ راه حل همان ACT می‌باشد.

ACT به معنی نوشتن کد، جهت تست قابلیت‌های نرم افزار می‌باشد. به این معنی که شما جهت تست کد خود، یکسری کد می‌نویسید که این کدها وظیفه دارند کد‌های جدیدی را که به نرم افزار خود اضافه کرده اید، تست کنند و اجرای آنها توسط زیرساخت‌های موجود (Test Frameworks) به صورت اتوماتیک انجام می‌شود.

حال قصد داریم اجزای ACT را که در شکل ذیل نمایش داده شده‌اند، تشریح کنیم.


· structured: برای بیان این مسئله، از مفهوم AAA استفاده می‌شود. A اول به معنی Arrange اطلاعاتی است که برای تست مورد نیاز است. A دوم به معنی Act یا اجرای متد در حالت تست است و A سوم بمعنی Assert یا بررسی نتایج تست می‌باشد. این ساختار، ساختاری است که در ادامه برای ایجاد تست‌ها از آن استفاده می‌کنیم.

· Self-documented: ساختار تست به گونه‌ای است که خود مستند می‌باشد و با بررسی کلی ساختار آن می‌توان به هدف تست پی برد.

· Automatic: با استفاده از Test Framework ها، فرآیند تست اتوماتیک می‌شود.

· Repeatable: یکی از مزیت‌های ACT این است که می‌توان آن را برای دفعات مکرر تکرار کرد.

· TARDIS: مخفف  Time And Relative Dimension In Space می‌باشد؛ با توجه به این مسئله ACT از کد شما در میان زمان و فضا محافظت می‌کند. ACT  عملکرد اصلی کد شما را در حال حاضر و در زمانی در آینده  تایید می‌کند؛ زمانیکه کد شما در حال توسعه می‌باشید و هر لحظه قابلیت‌های جدیدی به آن اضافه می‌شود، ACT تضمین می‌کند که این تغییرات، قابلیت‌های موجود در سیستم را تحت تاثیر قرار نمی‌دهند. بنابراین ACT از کد شما در مقابل زمان و فضا محافظت می‌کند.

روشهای مختلفی برای انجام دادن ACT وجود دارند که در این مقاله بر روی Unit Test تمرکز خواهیم کرد. Unit Test یکسری تست‌ها هستند که توسط برنامه نویس نوشته و اجرا می‌شود. هدف این روش این است که کد به قسمت‌های کوچکی تقسیم شود و بررسی شود که این قسمت‌ها آن گونه که انتظار می‌رود، عمل می‌کنند.

برای رسیدن به این هدف باید کد را به صورت متدهای Clean و Testable نوشت. این متد‌ها قسمت‌های مستقلی از کد هستند که می‌توانند تست شوند. همان طور که در شکل زیر مشاهده می‌کنید، برای هر متد می‌توان تست‌های مختلفی نوشت و حالت‌های مختلف مربوط به ورودی‌های معتبر، ورودی‌های نامعتبر و بروز Exception را تست کرد.


بسیاری از برنامه نویسان و مدیران  پروژه درمقابل مسئله استفاده از Unit Test در توسعه نرم افزار حساسیت‌های خاصی نشان می‌دهند. بسیاری از آنها اظهار می‌کنند که برای این کار زمان کافی نداریم و استفاده کردن از این روش برای ما هزینه بر می‌باشد. اما ما در جواب این دسته از افراد باید موارد زیر را که بیشتر هم بر جنبه زمانی تاکید دارند، بیان کنیم.


· Save time:
  استفاده کردن از Unit Test از هدر رفتن زمان شما جلوگیری می‌کند. هر برنامه نویسی می‌داند که حتی چند خط کد ساده هم نیاز به تست و باز بینی دارد. بنابراین برنامه نویس مجبور است آن ماژول اصلی از نرم افزار را که چند خط کد در آن نوشته است، به گونه ای اجرا کرده و فرآیند بیزینسی این ماژول را برای سناریو‌های مختلف، بصورت دستی تست کند. حال فرض کنید در ادامه‌ی این کار، شخص برنامه نویس مجبور شود کد را بطور مرتب تغییر دهد. بنابراین در این حالت مجبور است این فرآیند را چندین و چند بار تکرار کند (نرم افزار را اجرا کند، به منوی X برود، فرم Y را باز کند، حالت‌های مختلف را در فرم بررسی کند).
راه حلی که Unit Test برای حل این مشکل ارئه می‌دهد این است که برای انجام این فرآیند می‌توان کد نوشت و آن را بارها و بارها اجرا کرد. وظیفه‌ی Unit Test ها این است که اطلاعات مورد نیاز متد یا واحدی که می‌خواهند آن را تست کنند، فرآهم می‌آورند، متد را با اطلاعات فرآهم شده زیر تست می‌برند و سپس نتایج بدست آمده را بررسی خواهند کرد. شما می‌توانید در صورت تغییراتی در متد‌ها یا واحد‌ها، Unit  Test را بارها و بار‌ها برای تست عملکرد صحیح آن متد، بعد از تغییرات اجرا کنید. همان طور که می‌بینید تبدیل کردن این فرآیند دستی به یک فرآیند سیستمی و اتوماتیک می‌تواند در جلوگیری از هدر رفت زمان بسیار تاثیر گذار باشد.

· Find Bugs Faster:
با استفاده از Unit Test شما می‌توانید فرآیند پیدا کردن خطاها را بسیار سریعتر انجام دهید. برای مثال فرض کنید که شما گزارش یکسری خطا‌ها را در نرم افزار، دریافت کرده‌اید. به جای اینکه سعی کنید بصورت دستی، فرآیند‌ها را در نرم افزار مرور کنید تا دوباره شرایط بروز خطا یا شرایطی را که خطا در آن رخ داده است، جهت درک دلیل خطا یا خطا‌ها ایجاد کنید،  با استفاده از Unit Test می‌توانید به راحتی و در سریع‌ترین زمان ممکن و بصورت اتوماتیک خطا‌ها را پیدا کنید.

· Refactor Safely:
Unit Test به شما اجازه می‌دهد که به راحتی کد خود را Refactor کنید. فرض کنید که می‌خواهید کدی را که دارای یکسری پیچیدگی‌ها می‌باشد و نگهداری و توسعه آن سخت است، Refactor کنید. بدون استفاده از Unit Test، این Refactor کردن دارای ریسک بسیار زیادی است و ممکن است منجر به بروز خطاهای زیادی شود؛ در حالیکه با استفاده از Unit Test، بعد از Refactor کردن کد، می‌توان Test ها را اجرا کرده و از عدم وجود خطا در کدها به راحتی مطمئن شد.

· Enhance Your Value:
با نوشتن Unit Test برای کد‌های خود می‌توانید یک ارزش افزوده را به کد‌های خود اضافه کنید. به دلیل اینکه نوشتن Unit Test ویژگی Self-documented کد شما را افزایش می‌دهد و به افرادی که در تیم هستند کمک می‌کنند Business نرم افزار را بهتر درک کنند.

· Minimize Interruptions:
داشتن مجموعه‌ای مناسب از Unit Test ها باعث می‌شود تا Interrupt های ناخواسته در Code شما بوجود نیاید. برای مثال حالتی را در نظر بگیرید که بدلیل ورود داده‌های ناخواسته، نرم افزار دچار خطا می‌شود. دراین وضعیت در صورتیکه از Unit Test استفاده شود، هندل کردن این شرایط ناخواسته و Interrupt، بسیار راحت‌تر خواهد بود.
مطالب
آموزش مهندسی نرم افزار و UML - جلسه اول
آموزش مهندسی نرم افزار و UML
جلسه اول:

اولین قدم در تولید و توسعه نرم افزار داشتن یک نگرش سیستمی به بسته یا محصول نرم افزاری می‌باشد. اما چرا ما باید نرم افزار را به عنوان یک سیستم در نظربگیریم ؟
جواب این سئوال را باید از تعریف تئوری سیستم و خصوصیاتی که یک سیستم دارا می‌باشد استخراج کنیم.

تئوری سیستم‌ها

  دانشی برای سهولت کار با سیستم‌ها و بررسی دقیق این مفهوم است ؛ در واقع تئوری سیستم‌ها روشی برای شناخت محیط اطراف یا روشی برای شناخت  دنیای واقع می‌باشد .

از تعریف فوق می‌توان نتیجه گرفت :
برنامه نویسان برای ساخت برنامه هایی که با نیاز کاربران همسو باشد ، نیاز به شناخت محیطی دارند که کاربران در آن فعالیت می‌کنند پس برای شناخت محیط باید با دید سیستمی به مسئله نگاه کرد.


خصوصیات مهم سیستم :

1.   محیط – Environment: هر سیستم در یک محیط قرار دارد. 
2.   مرز – Boundary : سیستم‌های موجود در یک محیط توسط مرز‌ها از یکدیگر جدا می‌شوند.
3.   ورودی و خروجی – I/O : هر سیستم ورودی هایی را از محیط می‌گیرد و خروجی هایی را به محیط پس می‌دهد.
4.   واسط – Interface : امکان محاوره سیستم‌ها در یک محیط را فراهم می‌کند.
5.   زیر سیستم – Sub System : هر سیستم می‌تواند حاوی چندین زیرسیستم باشد . زیر سیستم‌ها تمام خصوصیت‌های یک سیستم را دارا می‌باشند.
6.   مکانیزم کنترلی – Controller : مهمترین بخش یک سیستم می‌باشد. مکانیزم کنترلی در واقع کنترل کننده تمامی فعالیت‌های انجام شده توسط یک سیستم است . ورودی‌ها از طریق مکانیزم کنترلی دریافت می‌شود و بر اساس آن خروجی هایی به محیط پس داده می‌شود.


نتیجه گیری :

با توجه به خصوصیاتی که در مورد سیستم‌ها مطرح شد به راحتی می‌توانیم دلیل علاقه مندی برنامه -نویسان به نوع نگرش سیستمی را در یابیم ، و جود محیط پیرامون یک سیستم و نحوه تبادل اطلاعات این سیستم با سایر سیستم‌ها در این محیط ، شکستن یک سیستم به چند زیر سیستم برای راحتی مسئله و پیاده سازی آسانتر آن و نیز وجود اینترفیس‌ها برای برقراری محاوره ای استاندارد بین زیر سیستم‌های یک سیستم و همچنین وجود ورودی هاو تصمیم گیری براساس ورودی هاو تولید یک خروجی همه و همه از نکات مورد توجه برنامه نویسان در تولید یک بسته نرم افزاری هستند که هماهنگی کاملی با مفاهیم تئوری سیستم‌ها دارند.  
نظرات مطالب
معرفی Xamarin و مزیت‌های استفاده از آن
این که عرض کردم حجم 3 الی 4 مگابایتی از نظر کاربران زیاد قابل قبول نیست به دلیل آماری است که از دوستان و آشنایانی که نرم افزار را برایشان جهت تست ارسال می‌نمودم بدستم رسیده است(در نسخه‌های بعدی با اندروید استودیو حجم کاهش زیادی پیدا نمود و یک سری باگ عجیب و غریب که منشا آنها را هنوز هم نمیدانم رفع شدند). که صد البته جامعه آماری بزرگی نیست و نتیجه آنرا براحتی نمی‌توان به کل جامعه تعمیم داد. بنده چندین app در مارکتهای داخلی منتشر نمودم که همگی زیر 2.3 مگابایت حجم دارند و اتفاقا بیشتر هم Game هستند و با گرافیک خوب. برای مثال اگر سودوکو 2 را در بازار(امیدوارم تصور نشود که قصد تبلیغ دارم) مشاهده نمایید میبینید که نرم افزار با این کیفیت و با این حجم نمی‌تواند خروجی Xamarin باشد. اگر تصور شود که از روی تعصب صحبتی میکنم باید بگویم که اتفاقا اگر تعصبی هم وجود داشته باشد نسبت به سی شارپ است نه جاوا. 
در مورد بحث CrossPlatform و کاهش هزینه‌ها برای شرکتهای کوچک و با بودجه محدود به طور حتم Xamarin برنده است. اما شرکتهای بزرگ اغلب رغبتی به استفاده از Xamarin ندارند. برای مثال تلگرام...
البته استفاده بنده از Xamarin قبل از خریداری آن توسط مایکروسافت هست و امیدوارم با کار مایکروسافت روی این تکنولوژی دیگر خبری از باگهای عجیب و غریبی که بنده را فراری دادند نباشد و بتوانم با زبان بسیار عالی و دوست داشتنی سی شارپ هم app موبایل تولید نمایم.(برای نرم افزارهای موبایل سازمانی انتخاب مناسبی هست)
مطالب
آشنایی با Feature Toggle - بخش اول
فرض کنید میخواهید برای بخش‌هایی از نرم افزاری که طراحی کرده‌اید ، امکانی را در نظر بگیرید که بتوانید زمانیکه نرم افزار در حال استفاده‌است، قابلیت‌هایی از آن‌را فعال یا غیرفعال نمایید؛ بدون اینکه نرم افزار از دسترس خارج شود. Feature Toggle که تحت عنوان Feature Flag هم شناخته می‌شود همین امکان را برای ما به ارمغان می‌آورد و ما را قادر می‌سازد تا قابلیت‌هایی را از نرم افزار، فعال یا غیرفعال کنیم، بدون اینکه نیاز باشد نرم افزار از دسترس مشتریان خارج شود و یا نیاز باشد نسخه‌ی جدیدی از نرم افزار  منتشر شود. برای مثال قابلیت ثبت نام کاربران را در بازه‌های خاصی غیرفعال کنیم و یا فرض کنید قابلیت جدیدی به نرم افزار اضافه کرده‌اید و میخواهید بعد از پابلیش، در یک بازه زمانی که نرم افزار شما بازدید کننده‌های کمتری دارد، آن‌را موقتا فعال کنید، نتیجه خروجی را ببینید و سپس آن را غیر فعال نمایید. در ادامه این مقاله سعی خواهیم کرد ابتدا با یک مثال ساده با این قابلیت آشنا شویم و سپس به معرفی یکی از کتابخانه‌های محبوب در این زمینه بپردازیم.
Feature Toggle چیزی بیشتر از یک دستور IF نیست، اگر شرط مورد نظر برقرار بود، کد را اجرا میکند، در غیر اینصورت از اجرای آن بخش صرف نظر میکند.
IF (currentYear<2023){
alert('Wear a mask!');
}
در قطعه کد فوق، سال جاری را چک کرده‌ایم و گفته‌ایم اگر سال جاری کمتر از سال 2023 بود، به بازدید کننده یک پیغام را نمایش دهیم. حال فرض کنید بیماری کرونا، پیش از سال 2023 از بین برود، ولی طبق این شرط همچنان پیغام به کاربران نمایش داده میشود. میتوانیم فعال و غیر فعال بودن نمایش این پیغام را یا از دیتابیس و یا از فایل appsetting.json  بخوانیم که در این حالت  به صورت زیر می‌باشد :
var showCoronaAlert=_cofiguration.GetValue<bool>("Features:showCoronaAlert"); // or read this from Database
If(showCoronaAlert){
alert(Wear a amask!);
}
در این روش بجای اینکه تاریخ را چک کنیم و بر اساس آن تصمیم بگیریم که آیا پیغامی نمایش داده شود یا نه، وضعیت نمایش آن را از فایل تنظیمات و یا دیتابیس خوانده‌ایم. در این حالت دیگر نیازی به تغییر و انتشار نسخه‌ی جدیدی از نرم افزار نیست و فقط کافی‌است مقدار مربوط به نمایش پیغام را در دیتابیس و یا فایل تنظیمات، به روزسانی نماییم.

 کتابخانه  Microsoft.FeatureManagement
کتابخانه  Microsoft.FeatureManagement  توسط تیم اژور پیاده سازی و نوشته شده‌است و برای خواندن اطلاعات، از همان IConfiguration استفاده میکند که ما را قادر می‌سازد تنظیمات را از منابع مختلفی بخوانیم  و همچنین  قابلیت‌های آن فراتر از تنظیم یک مقدار با true/false می‌باشد که در ادامه با بعضی از آنها آشنا خواهیم شد.
ابتدا نیاز هست این کتابخانه را به صورت زیر نصب نماییم :
Install-Package Microsoft.FeatureManagement

سپس نیاز هست در متد ConfigureService، سرویس مربوطه را اضافه نماییم :
using Microsoft.FeatureManagement;
public void ConfigureServices(IServiceCollection services)
{
    services.AddFeatureManagement();
}

این کتابخانه به صورت پیش فرض، اطلاعات feature‌ها را از بخشی (section) تحت عنوان FeatureManagement  از فایل appsetting.json می‌خواند. پس نیاز داریم این بخش را در appsetting.json تعریف نماییم  ( لیست تمامی قابلیت‌هایی را که قصد داریم به صورت داینامیک فعال/غیرفعال کنیم، در این بخش اضافه خواهیم کرد):
"FeatureManagement": {
   
}
اگر تمایل داشتید از اسم دیگری برای بخش تنظیمات، در فایل appsetting. json  استفاده نمایید، می‌توانید به صورت زیر این کار را انجام دهید :
public void ConfigureServices(IServiceCollection services)
{
 services.AddFeatureManagement(Configuration.GetSection("MyFeatureManagement"))
}
در این مقاله از همان اسم پیش فرض استفاده شده است.
افزودن یک قابلیت جدید
"FeatureManagement": {
   "MaskAlert":true
}

همان مثال بالا را  در بخش FeatureManagement  اضافه کرده‌ایم  و مقدار true را به معنی فعال بودن، برای آن در نظر گرفته‌ایم. این حالت، ساده‌ترین روش ثبت یک قابلیت با استفاده از این کتابخانه می‌باشد. برای بررسی وضعیت هر کدام از قابلیت‌ها باید اینترفیس  IFeatureManager   را به کلاس مربوطه تزریق نماییم و سپس بر اساس نام قابلیت، وضعیت آن را بررسی نماییم:
 public class HomeController : Controller
    {
        private readonly IFeatureManager _featureManager;

        public HomeController(IFeatureManager featureManager)
        {
            _featureManager = featureManager;
        }
        public async Task<IActionResult> Index()
        {
            if(await _featureManager.IsEnabledAsync("MaskAlert"))
            {
                // show messeage
            }

            return View();
        }
    }
اگر نیاز هست از اسم دیگری برای بخش (section)

فعال سازی بر اساس تاریخ (TimeWindowsFilter)
یکی از قابلیت‌های این کتابخانه، فعال سازی بر اساس بازه زمانی هست. اگر نیاز دارید یک قابلیت در یک بازه‌ی خاص فعال شود، میتوانید از این قابلیت استفاده کنید. برای فعال سازی این امکان، باید فیلتر TimeWindowFilter را که به صورت توکار به همراه کتابخانه وجود دارد، به صورت زیر در متد configureServices ثبت نماییم:
public void ConfigureServices(IServiceCollection services)
{ 
    services.AddFeatureManagement().AddFeatureFilter<TimeWindowFilter>();
}

و سپس یک Feature را در بخش FeatureManagement همانند زیر تعریف میکنیم که توسط آن مشخص کرده‌ایم این قابلیت در بازه‌ی زمانی بین دو تاریخ تعریف شده، فعال باشد :
 "FeatureManagement": {
    "EmergencyBanner": {
      "EnabledFor": [
        {
          "Name": "Microsoft.TimeWindow",
          "Parameters": {
            "Start": "01 Mar 2021 12:00:00 +00:00",
            "End": "01 Apr 2021 12:00:00 +00:00"
          }
        }
      ]
    }
  }
و نحوه‌ی بررسی فعال بودن آن، همانند روش قبل می‌باشد و فقط کافیست اسم Feature را به متد IsEnabledAsync بدهیم:
if(await _featureManager.IsEnabledAsync("EmergencyBanner")){
// show Emergency banner 
}

 پارامتر‌های Start و End میتوانند به صورت تکی هم استفاده شوند؛ به این معنا که میتوانید فقط پارامتر start را مقدار دهی کنید و در این حالت از تاریخ مورد نظر به بعد، Feature مورد نظر فعال می‌باشد و یا اگر فقط پارامتر End مقدار دهی شود، Feature مورد نظر فقط تا تاریخ تعیین شده فعال هست و بعد از آن برای همیشه غیرفعال می‌شود.
در زیر، نمونه‌ای از این حالت تنظیم شده‌است :
"FeatureManagement": {
    "EmergencyBanner": {
      "EnabledFor": [
        {
          "Name": "Microsoft.TimeWindow",
          "Parameters": {
            "End": "01 Apr 2021 12:00:00 +00:00"
          }
        }
      ]
    }
  }

فیلتر‌های سفارشی
از دیگر مزایای این کتابخانه این هست که محدود به فیلترهای توکار خود آن نیستیم و امکان توسعه و نوشتن فیلتر‌های سفارشی را به ما میدهد. برای مثال اگر یک قابلیت را در نرم افزار پیاده سازی کرده‌ایم که میخواهیم فقط بر روی مرورگر‌های خاصی در دسترس باشد، میتوانیم به صورت زیر این کار را انجام دهیم:
ابتدا در appsetting.json قابلیت (Feature) مورد نظر را به صورت زیر تعریف می‌کنیم :
"FeatureManagement": {
    "ChatV2": {
      "EnabledFor": [
        {
          "Name": "BrowserFilter",
          "Parameters": {
            "AllowedBrowsers": [ "Chrome" ]
          }
        }
      ]
    }
  }
سپس فیلتر سفارشی را به صورت زیر پیاده سازی میکنیم :
[FilterAlias("BrowserFilter")]
public class BrowserFilter:IFeatureFilter
    {
        private readonly IHttpContextAccessor _httpContextAccessor;

        public BrowserFilter(IHttpContextAccessor httpContextAccessor)
        {
            _httpContextAccessor = httpContextAccessor ?? throw new ArgumentNullException(nameof(httpContextAccessor));
        }

        public Task<bool> EvaluateAsync(FeatureFilterEvaluationContext context)
        {
            var userAgent = _httpContextAccessor.HttpContext.Request.Headers["User-Agent"].ToString();
            var settings = context.Parameters.Get<BrowserFilterSettings>();
            return Task.FromResult(settings.AllowedBrowsers.Any(userAgent.Contains));
        }
    }

کلاس BrowserFilter :
  public class BrowserFilterSettings
    {
        public string[] AllowedBrowsers { get; set; }
    }
بعد از پیاده سازی فیلتر فوق نیاز هست فیلتر سفارشی را که در بالا نوشتیم، در متد ConfigureServices ثبت نماییم. با توجه به اینکه برای تشخیص نوع مروگر کاربر نیاز هست  هدر درخواست را بررسی کنیم، پس نیاز هست IHttpContextAccessor را هم ثبت نماییم:
public void ConfigureServices(IServiceCollection services)
        {
            services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();
            services.AddFeatureManagement()
                .AddFeatureFilter<BrowserFilter>();
        }
و برای بررسی فعال بودن قابلیت مورد نظر فقط کافیست مانند قبل، اسم قابلیت مورد نظر را به صورت زیر بررسی کنیم :
if(await _featureManager.IsEnabledAsync("ChatV2")){
// do something 
}

* از دیگر قابلیت‌های این کتابخانه، فعال و غیر فعال کردن کنترلر و اکشن متدها بر اساس وضعیت Feature‌ها می‌باشد که در بخش دوم این مقاله به توضیح این موارد خواهیم پرداخت.
مطالب
آموزش MDX Query - قسمت چهارم –آشنایی با AdventureWorksDW2008R2 و آشنایی با محیط BIMS

در این قسمت تلاش می‌کنم در خصوص محیط BIMS (Business Intelligence Management Studio)  و همچنین AdventureWorksDW2008R2 توضیحاتی را ارائه کنم. در ابتدا در خصوص طراحی انجام شده در Data Warehouse  مربوط به پایگاه داده‌ی Adventure Works 2008 توضیحاتی ارایه می‌گردد.

شاید بهترین کار در خصوص آشنایی با یک پایگاه داده نگاه کردن به دیاگرام کلی آن پایگاه داده باشد. بنابر این در ابتدا می‌بایست یک دیاگرام از پایگاه داده‌ی AdventureWorksDW2008R2 بسازیم (این کار را در SQL Server Management Studio انجام می‌دهیم) . قبل از ساخت دیاگرام می‌بایست کاربر Sa را به عنوان Owner پایگاه داده معرفی کنیم.

برای این منظور ابتدا Properties پایگاه داده‌ی AdventureWorksDW2008R2  را گرفته و به قسمت Files رفته و با انتخاب دکمه‌ی ... در مقابل Owner و جستجوی کاربر Sa ، اقدام به مشخص کردن مالک پایگاه داده می‌کنیم. و سپس دکمه‌ی Ok را می‌زنیم.  

مطابق شکل زیر 


سپس یک دیاگرام کلی از پایگاه داده تولید می‌کنیم. مانند شکل زیر 


با یک نگاه اجمالی مشخص می‌گردد که نام تمامی جداول پایگاه داده‌ی DW یا با کلمه‌ی Dim یا با کلمه‌ی Fact شروع شده‌اند. 

همان طور که در مقاله‌ی شماره‌ی یک نیز عنوان شد، چندین روش طراحی DW وجود دارد :

1. ستاره ای

2. دانه برفی

3. کهکشانی

دقت داشته باشید که جداول Fact دارای فیلد‌های عددی نیز می‌باشد که توسط مراحل ETL پر شده‌اند و جداول Dimension دارای ابعادی هستند که به شاخص‌های موجود در یک جدول Fact معنا می‌دهند. به عبارت دیگر شاخص میزان فروش اینترنتی، یک Measure می‌باشد. اما با ارایه دو دایمنشن، به یک واکشی، عملا ما یک Measure داریم که بر اساس آن دو بعد، ماهیت پیدا کرده است. به عنوان مثال میزان فروش اینترنتی بر اساس سال و ماه و روز و براساس کشور خریدار مشخص می‌شود.

یکی از روش‌های تهیه‌ی DW این می‌باشد که کاربران خبره در هر سیستم، مشخص نمایند چه گزارشاتی مورد نظر آنها می‌باشد. سپس توسط تیم پشتیبانی آن سیستم‌ها، جداول Fact,Dimension  مورد نیاز برای حصول گزارش مربوطه تهیه گردد.

شاید ذکر این نکته جالب باشد که برای توسعه‌ی یک پایگاه داده‌ی Multidimensional توسط Solution ‌های ماکروسافت نیازی به آشنایی با یک محیط کار ( IDE ) جدید نمی‌باشد. همان طور هم که در مقاله‌ی قبلی اشاره شد، برای Deploy کردن یک پایگاه داده‌ی چند بعدی ( Multidimensional ) از خود محیط   Visual Studio .Net استفاده می‌شود. بنابر این آن دسته از برنامه نویسانی که با این محیط آشنا می‌باشند به راحتی می‌توانند به توسعه‌ی پایگاه داده‌ی چند بعدی بپردازند.

لازم به ذکر می‌باشد که اساسا هدف من از شروع این سری مقالات ، آموزش MDX Query ‌ها می‌باشد و نه آموزش BIMS ، با این وجود در این قسمت و در قسمت بعدی، توضیحات مقدماتی کار با BIMS ارایه می‌گردد و همچنین در فرصت مناسب در خصوص BIMS یک مجموعه مقاله‌ی جامع ارایه خواهم کرد.

در ابتدا اجزا BIMS را برای شما توضیح می‌دهم و سپس در خصوص ساخت هر کدام از آنها و ترتیب ساخت آنها توضیحاتی ارایه خواهم داد.

مسیر باز کردن برنامه‌ی  SQL Server Business Intelligence Development Studio = BIDS در زیر آمده است:

C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Microsoft SQL Server 2012\ SQL Server Data Tools

دقت داشته باشید که در صورت استفاده از نسخه‌ی Sql Server 2008 می‌بایست مسیر زیر را جستجو نمایید:

C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Microsoft SQL Server 2008 R2

با نگاه کردن به محیط BIMS  می توانید پنجره‌ی Solution Explorer  را مشاهده کنید .(در صورت عدم مشاهده، می‌توانید این پنجره را از منوی View باز کنید)



در پنجره‌ی Solution Explorer ابتدا نام Solution و در زیر آن، نام پروژه را خواهیم دید (نام پروژه و نام پایگاه داده‌ی چند بعدی، مشابه یکدیگر می‌باشند) و در زیر نام پروژه، موارد زیر را می‌بینیم:

1. Data Source

2. Data Source View

3. Cubes

4. Dimensiones

5. ….

Data Source  : عملا برقرار کننده‌ی پروژه با Data Warehouse می‌باشد. دقت داشته باشید که امکان تهیه یک پایگاه داده‌ی چند بعدی از چندین DW وجود دارد و حتا نوع DW ‌ها می‌تواند متفاوت باشد (به عبارت دیگر ما می‌توانیم چندین DW در RDBMS ‌های متفاوت داشته باشیم و همه‌ی آنها را در یک Multidimensional Database تجمیع کنیم). برای انجام چنین کاری باید چندین Data Source  تعریف کنیم. 


Data Source View : هر Data Source می‌تواند دارای چندین تقسیم بندی با مفاهیم Business ی باشد. برای هر کدام از این دسته بندی‌ها می‌توانیم یک یا چند Data Source View  ایجاد کنیم . به عبارت دیگر ایجاد Data Source View ‌ها سبب خلاصه شدن تعداد جداول Fact , Dimension براساس یک بیزینس خاص می‌باشد و در ادامه راحت‌تر می‌توانیم Cube ‌ها را تولید کنیم. 


نکته: جداول Fact , Dimension در ساختار D ata Warehouse ساخته می‌شوند.

Cubes : محل تعریف Cube ‌ها در این قسمت می‌باشد. در سری آموزش SSAS در خصوص نحوه‌ی ساخت Cube ‌ها شرح کاملی ارایه خواهم کرد. 


Dimensions : با توجه به این که در روال ساخت Cube ما مشخص می‌کنیم چه Dimension هایی داریم، یک سری از Dimension ‌ها به صورت پیش فرض در این قسمت قرار می‌گیرند و البته در صورت تغییر در Data Source View   می‌توانیم یک Dimension را به صورت دستی در این قسمت ایجاد نماییم و سپس آن را به Cube مورد نظر اضافه نماییم. 


دقت داشته باشید که برای ساخت یک پروژه می‌بایست بعد از ساخت Data Warehouse در برنامه‌ی BIMS اقدام به ساخت یک Data Source کنیم و سپس با توجه به Business‌های موجود در سیستم‌های OLTP اقدام به ساخت Data Source View‌های مناسب کرده و در نهایت اقدام به ساخت Cube کنیم. بعد از انجام تنظیمات مختلف در Cube مانند ساخت Hierarchy , KPI و ... نیاز می‌باشد که پروژه را Deploy کنیم تا پایگاه داده‌ی چند بعدی (MDB) ساخته شود. 

در قسمت بعدی نحوه‌ی ساخت یک پروژه در SSAS و چگونگی باز کردن یک پایگاه داده را بررسی خواهیم کرد. 

مطالب
مایکرو سرویس‌ها - قسمت 2 - بررسی ویژگی‌ها
در قسمت قبل با مفهوم مایکرو سرویس‌ها آشنا شدیم. سرویس‌های کوچک و مجزایی که بصورت مستقل، قابلیت توسعه و استقرار دارند و در راستای انجام یک قابلیت کسب و کار در اختیار دیگران قرار می‌گیرند.

ویژگی‌های یک مایکرو سرویس چیست؟

بعد از آشنایی با معماری مایکرو سرویس‌ها می‌خواهیم با ویژگی‌های آن آشنا شویم. البته باید به این نکته توجه داشت که همه‌ی معماری‌های مایکروسرویس‌ها این ویژگی‌ها را ندارند؛ ولی میتوان انتظار داشت اکثر آن‌ها این ویژگی‌ها را از خود به نمایش بگذارند.

Componentization via Services 

تعریف ما از component، واحدی از نرم افزار می‌باشد که به تنهایی قابل جایگزینی و به‌روز رسانی می‌باشد.
همانطور که گفته شد، مایکرو سرویس‌ها یک نرم افزار را به سرویس‌های (business component) کوچکتری تقسیم میکنند که به تنهایی قابل توسعه و استقرار می‌باشند. ما کتابخانه‌ها را به عنوان component در نظر میگیریم که به نرم افزار ما پیوند خورده‌اند و به وسیله فراخوانی توابع در پروسه نرم افزار قابل استفاده می‌باشند. در حالیکه سرویس‌ها componentهایی هستند که خارج از پروسه نرم افزار ما می‌باشند و به وسیله مکانیزم‌های ارتباطی مانند Web Service Request و Remote Procedure Call قابل دسترسی هستند.
در سیستم های یکپارچه که از چندین  component تشکیل شده‌اند و این componentها در جریان یک پروسه با هم در ارتباط هستند، اگر بخواهیم در یک component تغییر ایجاد کنیم، این تغییر نیازمند استقرار مجدد کل سیستم می‌باشد. در حالیکه در معماری مایکرسرویس، کافی است شما  component (سرویس) ای را که تغییر کرده‌است، دوباره مستقر کنید و سایر بخشهای سیستم از این تغییر تاثیر نمی‌پذیرند.

Technology Heterogeneity 

یک سیستم را در نظر بگیرید که از همکاری  چندین سرویس تشکیل شده‌است. ما میتوانیم تصمیم بگیریم که برای هر کدام از سرویسها از تکنولوژی متفاوتی استفاده کنیم. این امر به ما اجازه می‌دهد برای حل هر مشکل، از بهترین ابزار و تکنولوژی استفاده کنیم. این امر بر خلاف سیستم‌هایی که تنها باید از تکنولوژی بکار رفته در سیستم استفاده کنند، انعطاف پذیری سیستم را بسیار بالا می‌برد.
برای روشن شدن موضوع فرض کنید می‌خواهیم در بخشی از سیستم، performance را افزایش دهیم. برای این امر میتوانیم از هر تکنولوژی که به ما کمک میکند، استفاده کنیم. برای نمونه در یک سیستم شبکه اجتماعی، می‌توانیم اطلاعات مربوط به کاربران و ارتباطات آن‌ها را در یک دیتابیس مبتنی بر گراف و اطلاعات مربوط به پست‌ها و نظرات کاربران را در یک دیتابیس سندگرا ذخیره کنیم. به این ترتیب مشاهده میکنیم که وابسته‌ی به تکنولوژی خاصی نمی‌باشیم و می‌توانیم بر اساس نیاز خود، از تکنولوژی مورد نظر بهره ببریم.


مایکرو سرویسها به ما این اجازه را میدهند تا در انتخاب تکنولوژی‌ها نهایت دقت را انجام دهیم و متوجه شویم که تکنولوژی‌های جدید چگونه میتوانند به ما کمک کنند.
یکی از بزرگترین موانع در استفاده و انتخاب یک تکنولوژی جدید، ایجاد وابستگی سیستم به آن می‌باشد. در یک سیستم یکپارچه چنانچه قصد تغییر زبان مورد استفاده یا دیتابیس یا فریمورک مورد استفاده را داشته باشیم، سیستم هزینه‌ی سنگینی را متحمل می‌شود. در حالیکه در مایکرو سرویسها می‌توانیم این تغییرات را با کمترین هزینه انجام دهیم. البته باید توجه داشت که استفاده از تکنولوژی جدید چالش‌ها و سربار‌های خودش را دارد و انتخاب یک تکنولوژی جدید نیازمند بررسی کارشناسانه و دقیق می‌باشد.

Resilience 

چنانچه یکی ازسرویسها دچار اشکال شود و این مسئله بصورت زنجیروار برای تمام سرویس‌ها رخ ندهد، با جدا شدن آن سرویس، درروند کار سیستم خللی بوجود نمی‌آید و سیستم بدون کمترین مشکلی به ادامه کار خود می‌پردازد. یعنی محدوده یک سرویس، دیوار حائلی می‌شود تا سایر بخشها تاثیر نپذیرند. در سیستم‌های یکپارچه چنانچه یک سرویس دچار اشکال شود، سایر بخش‌های سیستم نیز غیر قابل استفاده می‌شوند. البته می‌توان با نصب نسخه‌های متفاوتی بر روی ماشین‌های متفاوت (Scale out)، تاثیر اینگونه اختلالات را تا حدودی کاهش داد. اما بوسیله مایکرو سرویسها می‌توانیم سیستم‌هایی را بسازیم که قادرند با خطاهای بوجود آمده در سرویس‌ها به‌درستی رفتار کنند؛ تا خللی در کار سیستم ایجاد نشود.

Scaling

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


Gilt  یک خرده فروش آنلاین در صنعت مد می‌باشد که  بخاطر مسائل Performance به معماری مایکروسرویس‌ها روی آورد. آنها در سال 2007 با یک نرم افزار یکپارچه شروع به کار کردند. اما بعد از دوسال سیستم آنها قادر به مقابله با ترافیک سایت نبود. آنها با تقسیم بندی قسمت‌های اصلی سیستم خود به مایکرو سرویسها، توانستند خیلی بهتر و موثرتر با ترافیک رسیده مقابله کنند و قابلیت دسترسی پذیری سیستم را افزایش دهند. در حال حاضر سیستم  آنها از حدود 450 مایکرو سرویس تشکیل شده که هر کدام روی چندین ماشین مختلف در حال اجرا می‌باشند.


Ease of Deployment 

تغییر حتی یک خط کد، در برنامه‌ای که از چندین میلیون خط تشکیل شده است، ما را ملزم به استقرار مجدد کل سیستم  و انتشار نسخه جدید می‌کند. این استقرار می‌تواند تاثیر و ریسک بالایی را داشته باشد و ما را مجبور به تغییرات بیشتر و انتشار نسخه‌های دیگر کند که این حجم زیاد تغییرات ممکن است به محصول ما ضربه بزند.
اما در مایکرو سرویس‌ها یک تغییر کوچک، تمام سیستم را تحت تاثیر قرار نمی‌دهد. بلکه تنها تغییرات مربوط به سرویس مورد نظر می‌باشد که به صورت مستقل قابلیت استقرار را دارد و چنانچه سیستم دچار مشکل شود، منشاء تغییرات کاملا مشخصی می‌باشد و می‌توان سریعتر سیستم را به وضعیت قابل اطمینان بازگرداند. این ویژگی یکی از مهمترین دلایلی می‌باشد که شرکت‌هایی مانند Netflix و Amazon  به پیاده سازی این معماری روی آورده‌اند.

Organizational Alignment 

بسیاری از ما مشکلات مربوط به پروژه‌های بزرگ و تیم‌های بزرگ را تجربه کرده‌ایم و این مشکلات زمانیکه اعضای تیم به‌صورت متمرکز در کنار هم نباشند، افزایش پیدا می‌کند. ما میدانیم که اگر یک تیم کوچک، بر روی قطعه کد کوچکتری کار کند، می‌تواند بسیار موثرتر باشد تا زمانیکه یک تیم بزرگ، درگیر یک کد بزرگ شود.
مایکرو سرویس‌ها این امکان را به ما می‌دهند تا معماری خود را با ساختار سازمانی خود هم راستا کنیم  و به ما کمک میکنند تا با تقسیم ساختار نرم افزار به بخش‌های کوچکتر وایجاد تیم‌های کوچکتر مختص هر بخش، بازدهی و تاثیر تیم‌ها را در سازمان، افزایش دهیم.

Composability

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


Optimizing for Replaceability

اگر شما در یک سازمان متوسط و یا بزرگ، مشغول به کار باشید، ممکن است با یک سیستم بزرگ و قدیمی مواجه شده باشید که در گوشه‌ای از سازمان در حال استفاده می‌باشد و هیچ کسی رغبت نزدیک شدن به آن و دست بردن در آن را ندارد و اگر کسی از شما بپرسد «چرا نمی‌توان آن را تغییر داد؟» خواهید گفت این کار، بسیار پرریسک و پردردسر است.
با استفاده از معماری مایکروسرویس، هزینه این تغییرات به مراتب کمتر و تغییرات با ضریب اطمینان بالاتری انجام می‌شوند.
اشتراک‌ها
Paper Cut یک ایمیل سرور دسکتاپ
If you ever send emails from an application or web site during development, you're familiar with the fear of an email being released into the wild. Are you positive none of the 'test' emails are addressed to colleagues or worse, customers? Of course, you can set up and maintain a test email server for development -- but that's a chore. Plus, the delay when you are waiting to view new test emails can radically slow your development cycle 
Paper Cut یک ایمیل سرور دسکتاپ