تغییر پلتفرم از Desktop به Tablet و SmartPhoneها تهدید بسیار جدی برای مایکروسافت و اینتل میتونه باشه. از عمده دلایل User Friendly بودن خانواده ویندوز برای عموم کاربران نرم افزارهای متعدد و با کیفیت است که در این زمینه هم مایکروسافت شدیدا عقب مونده(کمی و کیفی). به نطرم شیفت دادن ابزارها و کاربران به پلتفرم جدید توسط مایکروسافت بهتر بود چیزی شبیه اوبونتو باشه نه حرکت رادیکالی مثل این کارها(هنوزم بابت سرنوشت سیلورلایت از مایکروسافت دلخورم!).البته زیاد موافق نویسنده نیستم و قضاوت زودهنگامی برای شکست ویندوز8 هستش و در ثانی برای تمامی دلایلش جوابهای قانع کننده ای میشه داد با اینهمه به قول معروف Numbers don't lie
- بله. مفهوم یک سیستم «مرکزی» همین هست. نمونهاش اکتیو دایرکتوری در دومینهای سرورهای ویندوزی است که کار مدیریت کاربران و سطوح دسترسی آنها را یک یا چند نفر کارمند تمام وقت به نام مدیر شبکه انجام میدهد و این تعاریف به صورت مجزایی در کلاینتهای متصل، انجام نمیشوند. در این سری در انتهای آن روشی برای ثبت اطلاعات کاربران در بانک اطلاعاتی پیشنهاد شده. علاوه بر آن چند پیاده سازی کنندهی سورس باز مدیریت IDP هم معرفی شدهاند.
- در اینجا هر کلاینت ASP.NET Core هم میتواند سطوح دسترسی سفارشی و پیچیدهتر خاص خودش را بر اساس ترکیب Claims و نقشهای دریافتی از IDP، تعریف و تنظیم کند.
باسلام؛ بنده از این سیستم برای طراحی یک سایت فروش استفاده میکنم، سناریو به این شکل میباشد که تنها مدیر سیستم میتواند کاربران جدیدی را به وجود بیاورد، بنده به دنبال ملغی کردن استفاده از ایمیل میباشم، با وجود حذف خاصیت ایمیل در register veiwmodel و همچین حذف ستون ایمیل در بانک کاربران باز هم خطای اعتبار سنجی وارد کردن ایمیل را دریافت میکنم، با دنبال کردن جریان برنامه به تابع base.CreateAsyc توکار میرسم که نام کاربری را به صورت آدرس ایمیل مورد بررسی قرار میدهد، حتی با تغییر مقدار return در تابع IsEmailAddress باز هم با خطا مواجه میگردم. خواهش میکنم راهکاری ارائه نمایید که بدون دریافت ایمیل ادمین قادر به افزودن کاربر جدید باشد.
نظرات مطالب
مدیریت سفارشی سطوح دسترسی کاربران در MVC
مبحث مربوط به مدیریت کاربران و گروه کاربران و پروفایل از طریق سه کلاس پایه System.Web.Security.MembershipProvider
System.Web.Security.RoleProvider
System.Web.Profile.ProfileProvider
همونطور که از کلاسها مشخص هست به صورت Provider مدیریت میشود. این به این معنی است که اگر شما بخواید Provider خودتون با هر Datasource جدید یا منطق جدید داشته باشید مجاز هستید نسخه جدید از این Providerها رو پیاده سازی و با تنظیمات مربوطه در Web.Config استفاده کنید . در این قسمت شما مجاز به تغییر ورودی یا خروجی متدهای abstract classهای گفته شده نیستید .
پیاده سازیهای مختلفی از این سه کلاس به صورت EF , ODBC , .. وجود داره که لینک زیر مربوط به پیاده سازی odbc است .
پیاده سازی MembershipProvider
پیاده سازی RoleProvider
پیاده سازی ProfileProvider
موفق باشید
System.Web.Security.RoleProvider
System.Web.Profile.ProfileProvider
همونطور که از کلاسها مشخص هست به صورت Provider مدیریت میشود. این به این معنی است که اگر شما بخواید Provider خودتون با هر Datasource جدید یا منطق جدید داشته باشید مجاز هستید نسخه جدید از این Providerها رو پیاده سازی و با تنظیمات مربوطه در Web.Config استفاده کنید . در این قسمت شما مجاز به تغییر ورودی یا خروجی متدهای abstract classهای گفته شده نیستید .
پیاده سازیهای مختلفی از این سه کلاس به صورت EF , ODBC , .. وجود داره که لینک زیر مربوط به پیاده سازی odbc است .
پیاده سازی MembershipProvider
پیاده سازی RoleProvider
پیاده سازی ProfileProvider
موفق باشید
بله دوست عزیز ، استفاده از Session مزایا و معایب خودش را به همراه دارد.
اما در یک سیستم فروشگاهی حذف و اضافه شدن کالا در سبد خرید بصورت مکرر انجام میشود و برای اینکه شما چه کاربران مهمان و چه کاربران عضو را مدیریت نموده و بتوانید ترافیک روی بانک اطلاعاتی خود را کاهش دهید میتوانید از Session استفاده نمایید . ( بطور مثال اگر 1000 نفر دریک سایت فروشگاهی که حداقل 100 کالا ارائه شده است را به سبد خرید خود اضافه یا تعداد و ... آنها را ویرایش نمایند در بهترین حال 100000 درخواست به بانک اطلاعاتی ارسال و دریافت خواهد شد)
اما در یک سیستم فروشگاهی حذف و اضافه شدن کالا در سبد خرید بصورت مکرر انجام میشود و برای اینکه شما چه کاربران مهمان و چه کاربران عضو را مدیریت نموده و بتوانید ترافیک روی بانک اطلاعاتی خود را کاهش دهید میتوانید از Session استفاده نمایید . ( بطور مثال اگر 1000 نفر دریک سایت فروشگاهی که حداقل 100 کالا ارائه شده است را به سبد خرید خود اضافه یا تعداد و ... آنها را ویرایش نمایند در بهترین حال 100000 درخواست به بانک اطلاعاتی ارسال و دریافت خواهد شد)
راه حلهای زیادی برای محاسبه و نمایش تعداد کاربران آنلاین یک برنامه وب وجود دارند و عموما مبتنی بر کار با متغیرهای سشن یا Application و امثال آن هستند. این روشها عموما دقیق نبوده و خصوصا قسمت قطع اتصال کاربر را نمیتوانند دقیقا تشخیص دهند. به همین جهت نیاز به یک تایمر دارند که مثلا اگر در 5 دقیقه قبل، کاربری درخواست مشاهده آدرسی را به سرور ارسال نکرده بود، از لیست کاربران آنلاین حذف شود.
در ادامه بجای این روشها، از SignalR برای محاسبه تعداد کاربران آنلاین و همچنین به روز رسانی بلادرنگ این عدد در سمت کاربر، استفاده خواهیم کرد.
تشخیص اتصال و قطع اتصال کاربران در SignalR
زیر ساختهای کلاس Hub موجود در SignalR، دارای متدهای ردیابی اتصال (OnConnected)، قطع اتصال (OnDisconnected) و یا برقراری مجدد اتصال کاربران (OnReconnected) هستند. با بازنویسی این متدها میتوان به تخمین بسیار دقیقی از تعداد کاربران آنلاین یک سایت رسید.
پیشنیازهای بحث
پیشنیازهای این بحث با مطلب «مثال - نمایش درصد پیشرفت عملیات توسط SignalR» یکی است. برای مثال نحوه دریافت وابستگیها، تنظیمات فایل global.asax و افزودن اسکریپتها، تفاوتی با مثال یاد شده ندارند.
تعریف هاب کاربران آنلاین برنامه
کدهای کامل هاب شمارش کاربران آنلاین را در اینجا ملاحظه میکنید؛ به همراه نکتهی نحوهی دریافت IP کاربر متصل شده به سایت، در یک هاب. کار افزودن یا حذف این کاربران به ConcurrentDictionary تعریف شده، در روالهای بازنویسی شده اتصال، قطع اتصال و اتصال مجدد یک کاربر، انجام شده است.
در اینجا، هم به IP کاربر و هم به ConnectionId او نیاز است. از این جهت که هر ConnectionId، معرف یک برگه جدید باز شده در مرورگر کاربر است. اگر صرفا IPها را پردازش کنیم، با بسته شدن یکی از چندین برگه مرورگر او که اکنون به سایت متصل هستند، آمار او را از دست خواهیم داد. این کاربر هنوز چندین برگه باز دیگر را دارد که با سایت در ارتباط هستند، اما چون IP او را از لیست حذف کردهایم (در نتیجه بسته شدن یکی از برگهها)، آمار کلی شخص را نیز از دست خواهیم داد. بنابراین هر دوی IP و ConnectionIdها باید پردازش شوند.
اگر برنامه شما دارای اعتبارسنجی است (یک صفحه لاگین دارد)، بهتر است بجای IP از this.Context.User.Identity.Name استفاده کنید.
کدهای سمت کلاینت نمایش آمار کاربران
با توجه به اینکه در هاب تعریف شده، متد پویای updateUsersOnlineCount، آمار تعداد کاربران متصل را (تعداد آی پیهای منحصربفرد متصل را) به کلاینتها ارسال میکند، بنابراین در سمت کلاینت نیز با تعریف callback ایی به همین نام، میتوان این آمار دریافتی را به کاربران سایت نمایش داد. آماری که به صورت خودکار با کم و زیاد شدن کاربران به روز شده و نیازی نیست کاربر به صورت دستی، صفحه را به روز کند.
کدهای کامل این مثال را از اینجا نیز میتوانید دریافت کنید:
SignalR05.zip
در ادامه بجای این روشها، از SignalR برای محاسبه تعداد کاربران آنلاین و همچنین به روز رسانی بلادرنگ این عدد در سمت کاربر، استفاده خواهیم کرد.
تشخیص اتصال و قطع اتصال کاربران در SignalR
زیر ساختهای کلاس Hub موجود در SignalR، دارای متدهای ردیابی اتصال (OnConnected)، قطع اتصال (OnDisconnected) و یا برقراری مجدد اتصال کاربران (OnReconnected) هستند. با بازنویسی این متدها میتوان به تخمین بسیار دقیقی از تعداد کاربران آنلاین یک سایت رسید.
پیشنیازهای بحث
پیشنیازهای این بحث با مطلب «مثال - نمایش درصد پیشرفت عملیات توسط SignalR» یکی است. برای مثال نحوه دریافت وابستگیها، تنظیمات فایل global.asax و افزودن اسکریپتها، تفاوتی با مثال یاد شده ندارند.
تعریف هاب کاربران آنلاین برنامه
using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNet.SignalR; namespace SignalR05.Common { public class OnlineUsersHub : Hub { public static readonly ConcurrentDictionary<string, string> OnlineUsers = new ConcurrentDictionary<string, string>(); public void UpdateUsersOnlineCount() { // آی پی معرف یک کاربر است // اما کانکشن آی دی معرف یک برگه جدید در مرورگر او است // هر کاربر میتواند چندین برگه را به یک سایت گشوده یا ببندد var ipsCount = OnlineUsers.Select(x => x.Value).Distinct().Count(); this.Clients.All.updateUsersOnlineCount(ipsCount); } /// <summary> /// اگر کاربران اعتبار سنجی شدهاند بهتر است از /// this.Context.User.Identity.Name /// بجای آی پی استفاده شود /// </summary> protected string GetUserIpAddress() { object environment; if (!Context.Request.Items.TryGetValue("owin.environment", out environment)) return null; object serverRemoteIpAddress; if (!((IDictionary<string, object>)environment).TryGetValue("server.RemoteIpAddress", out serverRemoteIpAddress)) return null; return serverRemoteIpAddress.ToString(); } public override Task OnConnected() { var ip = GetUserIpAddress(); OnlineUsers.TryAdd(this.Context.ConnectionId, ip); UpdateUsersOnlineCount(); return base.OnConnected(); } public override Task OnReconnected() { var ip = GetUserIpAddress(); OnlineUsers.TryAdd(this.Context.ConnectionId, ip); UpdateUsersOnlineCount(); return base.OnReconnected(); } public override Task OnDisconnected() { // در این حالت ممکن است مرورگر کاملا بسته شده باشد // یا حتی صرفا یک برگه مرورگر از چندین برگه متصل به سایت بسته شده باشند string ip; OnlineUsers.TryRemove(this.Context.ConnectionId, out ip); UpdateUsersOnlineCount(); return base.OnDisconnected(); } } }
در اینجا، هم به IP کاربر و هم به ConnectionId او نیاز است. از این جهت که هر ConnectionId، معرف یک برگه جدید باز شده در مرورگر کاربر است. اگر صرفا IPها را پردازش کنیم، با بسته شدن یکی از چندین برگه مرورگر او که اکنون به سایت متصل هستند، آمار او را از دست خواهیم داد. این کاربر هنوز چندین برگه باز دیگر را دارد که با سایت در ارتباط هستند، اما چون IP او را از لیست حذف کردهایم (در نتیجه بسته شدن یکی از برگهها)، آمار کلی شخص را نیز از دست خواهیم داد. بنابراین هر دوی IP و ConnectionIdها باید پردازش شوند.
اگر برنامه شما دارای اعتبارسنجی است (یک صفحه لاگین دارد)، بهتر است بجای IP از this.Context.User.Identity.Name استفاده کنید.
کدهای سمت کلاینت نمایش آمار کاربران
<html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title></title> <script src="Scripts/jquery-1.6.4.min.js" type="text/javascript"></script> <script src="Scripts/jquery.signalR-1.1.3.min.js" type="text/javascript"></script> <script type="text/javascript" src='<%= ResolveClientUrl("~/signalr/hubs") %>'></script> </head> <body> <form id="form1" runat="server"> online users count: <span id="usersCount"></span> </form> <script type="text/javascript"> $(function () { $.connection.hub.logging = true; var onlineUsersHub = $.connection.onlineUsersHub; onlineUsersHub.client.updateUsersOnlineCount = function (count) { $('#usersCount').text(count); }; $.connection.hub.start(); }); </script> </body> </html>
کدهای کامل این مثال را از اینجا نیز میتوانید دریافت کنید:
SignalR05.zip
نظرات مطالب
سفارشی کردن ASP.NET Identity در MVC 5
لازم نیست تمام این آبجکتها رو به context نگاشت کنید. قالب پروژههای VS 2013 بصورت خودکار در پوشه Models کلاسی بنام IdentityModels میسازه. این کلاس شامل کلاسی بنام ApplicationDbContext میشه که تعریفی مانند لیست زیر داره:
این کلاس رو کلا حذف کنید، چون قراره از یک DbContext برای تمام موجودیتها استفاده کنید.
کلاس ApplicationUser که معرف موجودیت کاربران هست رو در لایه دامنهها تعریف کنید و دقت کنید که باید از IdentityUser ارث بری کنه، حال با نام پیش فرض یا با نام دلخواه. سپس باید کلاسی بسازید که از <UserManager<T مشتق میشه. با استفاده از این کلاس میتونید به موجودیتهای کاربران دسترسی داشته باشید. بعنوان مثال:
همونطور که میبینید کلاس موجودیت کاربر در اینجا AppUser نام داره، پس هنگام استفاده از UserManager نوع داده رو بهش نگاشت میکنیم. کد کلاس AppUser هم مطابق لیست زیر خواهد بود.
همونطور که مشخصه کلاس کاربران سفارشی سازی شده و سه فیلد به جدول کاربران اضافه کردیم. فیلدهای بیشتر یا موجودیت پروفایل کاربران هم باید به همین کلاس افزوده بشن. اگر پستها رو بیاد بیارید گفته شد که ASP.NET Identity با مدل EF Code-First کار میکنه.
public class ApplicationDbContext : IdentityDbContext<ApplicationUser> { public ApplicationDbContext() : base("DefaultConnection") { } }
این کلاس رو کلا حذف کنید، چون قراره از یک DbContext برای تمام موجودیتها استفاده کنید.
کلاس ApplicationUser که معرف موجودیت کاربران هست رو در لایه دامنهها تعریف کنید و دقت کنید که باید از IdentityUser ارث بری کنه، حال با نام پیش فرض یا با نام دلخواه. سپس باید کلاسی بسازید که از <UserManager<T مشتق میشه. با استفاده از این کلاس میتونید به موجودیتهای کاربران دسترسی داشته باشید. بعنوان مثال:
public class AppUserManager : UserManager<AppUser>{ public AppUserManager() : base(new UserStore<AppUser>(new ShirazBilitDbContext())) { } }
همونطور که میبینید کلاس موجودیت کاربر در اینجا AppUser نام داره، پس هنگام استفاده از UserManager نوع داده رو بهش نگاشت میکنیم. کد کلاس AppUser هم مطابق لیست زیر خواهد بود.
public class AppUser : IdentityUser { public string Email { get; set; } public string ConfirmationToken { get; set; } public bool IsConfirmed { get; set; } }
همونطور که مشخصه کلاس کاربران سفارشی سازی شده و سه فیلد به جدول کاربران اضافه کردیم. فیلدهای بیشتر یا موجودیت پروفایل کاربران هم باید به همین کلاس افزوده بشن. اگر پستها رو بیاد بیارید گفته شد که ASP.NET Identity با مدل EF Code-First کار میکنه.
مطالب دورهها
الگوی Matching
الگوی Matching در واقع همون switch در اکثر زبانها نظیر #C یا ++C است با این تفاوت که بسیار انعطاف پذیرتر و قدرتمندتر است. در برنامه نویسی تابع گرا، هدف اصلی از ایجاد توابع دریافت ورودی و اعمال برخی عملیات مورد نظر بر روی مقادیر با استفاده از تعریف حالات مختلف برای انتخاب عملیات است. الگوی Matching این امکان رو به ما میده که با استفاده از حالات مختلف یک عملیات انتخاب شود و با توجه به ورودی یک سری دستورات رو اجرا کنه. ساختار کلی تعریف آن به شکل زیر است:
راحتترین روش استفاده از الگوی Matching هنگام کار با مقادیر است. اولین مثال رو هم در فصل قبل در بخش توابع بازگشتی با هم دیدیم.
در تابع بالا ورودی ما اگر false باشد "False" و اگر true باشد "True" برگشت داده میشود. _ در مثال بالا دقیقا همون default در switch سایر زبان هاست.
در این مثال (دقیقا بر عکس مثال بالا ) ابتدا یک string دریافت میشود اگر برابر "True" یا "true" بود مقدار true برگشت داده میشود و اگر برابر "False" یا "false" بود مقدار false برگشت داده میشود در غیر این صورت یک FailureException پرتاب میشود. خروجی مثال بالا در حالات مختلف به شکل زیر است:
خروجی :
هم چنین علاوه بر اینکه امکان استفاده از چند شناسه در این الگو وجود دارد، امکان استفاده از And , Or نیز در این الگو میسر است.
خروجی برای کدهای بالا به صورت زیر است:
استفاده از عبارت و شروط در الگوی Matching
در الگوی Matching اگر در بررسی ورودی الگو با یک مقدار نیاز شما را برطرف نمیکند استفاده از فیلترها و شروط مختلف هم مجاز است. برای مثال
مثال بالا برای تعیین علامت هر عدد ورودی به کار میرود. -1 برای عدد منفی و 1 برای عدد مثبت و 0 برای عدد 0.
عبارت if … then … else
استفاده از if در #F کاملا مشابه به استفاده از if در #C است و نیاز به توضیح ندارد. تنها تفاوت در else if است که در #F به صورت elif نوشته میشود.
ساختار کلی
برای مثال الگوی Matching پایین رو به صورت if خواهیم نوشت.
#با استفاده از if
در پایان یک مثال مشترک رو به وسیله دستور swith case در #C و الگوی matching در #F پیاده سازی میکنیم.
match expr with | pat1 -> result1 | pat2 -> result2 | pat3 when expr2 -> result3 | _ -> defaultResult
let booleanToString x = match x with false -> "False" | _ -> "True"
let stringToBoolean x = match x with | "True" | "true" -> true | "False" | "false" -> false | _ -> failwith "unexpected input"
printfn "(booleanToString true) = %s"
(booleanToString true)
printfn "(booleanToString false) = %s"
(booleanToString false)
printfn "(stringToBoolean \"True\") = %b"
(stringToBoolean "True")
printfn "(stringToBoolean \"false\") = %b"
(stringToBoolean "false")
printfn "(stringToBoolean \"Hello\") = %b"
(stringToBoolean "Hello")
(booleanToString true) = True
(booleanToString false) = False
(stringToBoolean "True") = true
(stringToBoolean "false") = false
Microsoft.FSharp.Core.FailureException: unexpected input
at FSI_0005.stringToBoolean(String x)
at <StartupCode$FSI_0005>.$FSI_0005.main@()
let myOr b1 b2 = match b1, b2 with | true, _ -> true //b1 true , b2 true or false | _, true -> true // b1 true or false , b2 true | _ -> false
printfn "(myOr true false) = %b" (myOr true false) printfn "(myOr false false) = %b" (myOr false false)
(myOr true false) = true (myOr false false) = false
در الگوی Matching اگر در بررسی ورودی الگو با یک مقدار نیاز شما را برطرف نمیکند استفاده از فیلترها و شروط مختلف هم مجاز است. برای مثال
let sign = function | 0 -> 0 | x when x < 0 -> -1 | x when x > 0 -> 1
عبارت if … then … else
استفاده از if در #F کاملا مشابه به استفاده از if در #C است و نیاز به توضیح ندارد. تنها تفاوت در else if است که در #F به صورت elif نوشته میشود.
ساختار کلی
if expr then expr elif expr then expr elif expr then expr ... else expr
let result = match System.DateTime.Now.Second % 2 = 0 with | true -> "heads" | false -> "tails"
let result = if System.DateTime.Now.Second % 2 = 0 then box "heads" else box false printfn "%A" result
نظرات اشتراکها
درس خوندن، ارزشش رو داره؟
گذشته از بحث مدرک محوری که متاسفانه کشور رو به جهت نامناسبی کشونده و باعث خیلی بی عدالتیها و عقب ماندگیها و ... در کشور شده (به خصوص در سیستم هایی که مستقیم یا غیر مستقیم دولتی هستند!)، ماهیت دانشگاه بسیار مهم است.
در دانشگاه چیزهایی مثل نحوه یادگیری، کارگروهی، بالا بردن انگیزه، حس رقابت، حس پیشرفت، اعتماد به نفس و خیلی چیزهای دیگه به طور عادی یا اجباری یاد داده میشود که کسی که دانشگاه نرفته قطعا این موارد رو هم تجربه نخواهد کرد بنابراین دیدگاه یک شخص تحصیل کرده از زمین تا آسمان با نمونه دانشگاه نرفته آن تفاوت دارد. (صد البته رتبه دانشگاه نیز در یادگیری و میزان این تجربیات تاثیر فراوان دارد یعنی نمیشه دو تا فارغ التحصیل دانشگاه رو که مثلا یکی در صنعتی اصفهان درس خونده رو با دانشگاه غیر انتفاعی فلان شهرستان(!) مقایسه کرد که از لحاظ وسعت اندازه یک مدرسه هم نیست و هر دو هم کارشناس تربیت میکنند.)
اما برای بچههای نرمافزار به نظرم قضیه حتی مهمتر از مابقی رشتهها هم هست. یعنی عقیده دارم دانشگاه رفتن برای کسایی که دوست دارند تو حوزه نرمافزار کارآفرین، کارشناس، یا هرچیزه دیگه ای بشن خیلی مهمه. چرا؟
(برای مثال) تو دانشگاه اسمبلی به شما یاد میدهند به همراه ریزپردازنده و معماری کامپیوتر که با ترکیب نظریه زبانها و کامپایلر دانشجو میفهمه از زمانی که یک خط در کامپیوتر به عنوان برنامه در هر زبانی نوشته میشه این یک خط چطور توسط کامپایلر از لحاظ نحو، دستور بررسی میشه و چطور کد معادل سطح پایین ایجاد میشه و کد رو پردازنده چطوری با کمک چه ثباتهایی و چه دستوراتی در سطح ماشین اجرا میکنه.
یا درسی مثل طراحی الگوریتمهاست که انواع و اقسام الگوریتمهای مختلف که تا الان ارائه شدند بررسی میکنه و از لحاظ سرعت و زمان (Order) مورد تحلیل قرار میده که مثلا الگوریتم Quick Sort در چه زمانی یک لیست رو مرتب میکنه و Bubble Sort در چه زمانی و یا اینکه ضرب یک ماتریس n*n در حالت تک پردازنده و یا بصورت موازی چطور انجام میشه و چقدر زمان نیاز داره؟
یا شبیه سازی پنجره ویندوز در مد گرافیک در زبان C چه کتابخانهها و سختافزارهایی رو درگیر میکنه و یا منظور از نرمال سازی در سطح 3NF در مفاهیم پایگاه داده رابطهای چی هست و چطور میشه به اون رو در واقعیت رسید. (که خیلی از مدعیان کار با MS SQL SERVER یا ... هستند که حتی اصول و مفاهیم ساده پایگاه داده رو هم نمیدونند.)
اینها چیزهایی هستند که کسانی که دانشگاه نرفتن و صرفا با یادگیری یک زبان برنامه نویسی وارد این حوزه شدند و حتی مدعی هم هستند(!)، نمیدانند.
ممکنه فکر کنید خوب دونستن اینها چه فایدهای داره؟
زمانی که سرباز بودم از مافوقم پرسیدم با وجود اینهمه سلاح اتوماتیک و سبک و کوچک و جدید چرا ما باید از کلاشینکف صد سال پیش روسی استفاده کنیم؟ جواب این بود که با یادگیری کامل این سلاح میتونید تقریبا با همه سلاحهای موجود کار کنید و کلیات ماجرای همه این سلاحها از همین کلاشینکف و ژ-۳ ارث بریمیکند(!) و یادگیری بقیه با دونستن اطلاعات پایه تنها یادگیری بخش جدیدی که به این سلاحها اضافه شده وگرنه پایه همان است.
شبیه همین جواب را زمانی شنیدم که از استادم پرسیدم یادگیری ساختار پردازنده 80X86 زمانی که الان پردازنده با ساختار چند هستهای توسط اینتل تولید میشه چه فایدهای داره؟
بنابراین کسی که واقعا این مسائل پایهای رو خوب یاد گرفته باشه توانایی فوقالعادهای در درک مسائل جدید در آینده خواهد داشت و قطعا محصول بسیار باکیفیتتر و بهینهتری تولید خواهد کرد و ذهن بسیار خلاقتری خواهد داشت و اگر شرایط اجتماعی برایش فراهم باشد موجب افتخار یک کشور نیز خواهد شد.
نکته آخر:
اگر فیلم The Social Network رو دیده باشید حتما اون بخشی رو که مارک زاکربرگ وارد کلاس دانشگاه هاروارد میشه و با بیحوصلگی تمام سرکلاس به مطالب استاد گوش میده و میخواد کلاس رو ترک کنه که استاد ازش یک سوال درسی میپرسه (برای مسخره کردنش!) و مارک ایستاده و روی پلهها جواب استاد رو میده که هیج ، کمی جلوتر از فکر استاد پیش میره و جواب میده که کلاس هنوز به اون بخش نرسیده و همه مات و مبهوت موندهاند...
بله، درسته خیلی از بزرگان این رشته دانشگاه نرفتهاند و یا ترک تحصیل کردهاند ولی علت این بوده که درسهای ارائه شده در دانشگاه اونها رو سیراب نمیکرده و اونها نیاز به چیزی فرای درسهای ساده دانشگاه داشتند که در دانشگاه هیچ وقت به اون نمیرسیدند.
این افراد رو نمیشه با کسانی که در دانشگاه برای پاس کردن فلان درس به هر دری میزنند تا به مدرک برسن یا ذهنشون توانایی حل یک معادله ساده درجه ۲ رو نداره که بخوان براش برنامه بنویسن، یکی کرد.
بنابراین امثال جابز و گیتس نوابغ بشری بودند و هستند که تونستند در جامعهای که زمینه براشون مهیا بوده بدون نیاز به دانشگاه موفق بشن و شهرت جهانی پیدا کنند.
موفق باشید.
یکی از دغدغههای جدی امروزه توسعه دهندگان نرم افزار در سمت Front end، توسعه برنامههای Cross Platform است. در این سری آموزشی به صورت قدم به قدم و پروژه محور میخواهیم برنامهای را برای Android/iOS/Windows توسعه دهیم که روی کامپیوتر، تبلت و موبایل به خوبی کار کند.
انتخاب ابزار درست برای شروع به کار از اهمیت شایانی برخوردار است و بد نیست در ابتدا به بررسی دلایل انتخاب ابزارهایی بپردازیم که قرار است در این دوره از آنها استفاده شود.
۱- زبان برنامه نویسی: CSharp
CSharp با وجود امکاناتی مانند Generics، Lambda Expressions، Linq، Async و ... که تا حدودی در سایر زبانها هم هستند، زبانی خوش ساختار و کاربردی است. همچنین اضافه شدن امکانات جدیدی مانند ref returns و ... نشان دهنده این است که این زبان رو به جلو در حرکت و در برخی موارد پیشرو است. اما در توسعه یک برنامه Cross Platform مواردی اهمیت پیدا میکنند که شاید توسعه دهنده نرم افزار مستقیما با آنها درگیر نشود، ولی از آنها تاثیر میپذیرد. در زبان CSharp مواردی مانند P/Invoke ،Pointers، Extern و ... جزء این دست از موارد هستند که کمک میکنند CSharp به یکی از لذت بخشترین زبان هایی تبدیل شود که قابلیت فراخوانی 100% امکانات زبانهای دیگر را بدون اما و اگرهای فراوان داشته باشد.
در سایر زبانهای Cross Platform اگر کتابخانههای توسعه داده شده و ترکیب زبانهای برنامه نویسی استفاده شده در آنها را بررسی کنید، میبینید که اگر قرار است کتابخانه مربوطه مثلا در JavaScript استفاده شود، توسعه دهنده کد، درصدی از کد را با Java، درصدی را با Swift و درصدی را با JavaScript توسعه داده است! اگر معادل همان کتابخانه را برای CSharp پیدا کنید، میبینید که تمامی قسمتهای مربوط به اندروید، iOS و ویندوز به زبان CSharp است.
برای مثال در ادامه کدهای مربوط به پروژهای را میبینید که هدف آن، ارائه متدهایی ساده برای کار با امکانات مختلف دستگاه، به صورت Cross Platform هست. مثلا برای بررسی وضعیت باطری بنویسید:
var state = Battery.State; // Charging, Full, Discharging, ...
که تماما با CSharp توسعه داده شده است.
اما معادل چنین پروژهای در هیچ زبان دیگری به صورت 100% با خود آن زبان توسعه داده نشدهاست و بیشتر مواقع با چنین چیزی مواجه میشوید:
این مسئله وقتی حائز اهمیت میشود که در پروژهتان به سمت کارهایی حرکت کنید که کمی خاص باشند و نتوانید کتابخانهای را پیدا کنید که نیازهای شما را پوشش دهد و یا از کیفیت خوبی برخوردار نباشد و ... و خلاصه بخواهید کمی بیشتر دست به کد شوید. در چنین مواقعی شما عملا درگیر چندین زبان و محیط توسعه و سیستم عامل و Debugger و ... میشوید. به هر میزان که برنامه شما خاص باشد، این هزینه افزایش پیدا میکند تا جایی که ممکن است ادامه توسعه نرم افزار را غیر ممکن کند.
در CSharp شما به صد در صد امکانات سیستم عاملها (Android/iOS/Windows/Linux/Mac/Tizen) دسترسی دارید.
۲- اجرا کننده برنامه: NET.
انتخاب NET. و کتابخانههای آن مانند Task Parallel Library - Entity Framework(Sqlite) - Noda - JSON.NET که در هر زمینهای بالاترین کیفیت ممکن را به شما ارائه میکنند به خودی خود منطقی به نظر میرسد. اما تمامی اینها در کنار سرعت اجرای NET. به صورت Native و همچنین قابلیت اجرای NET. در تمامی سیستم عاملها و همچنین امکان اجرای آن در مرورگر به کمک استاندارد Web Assembly آن را به انتخابی فوق العاده بدل میکند. سرعت گسترش محبوبیت و استفاده از NET. در دنیا نیز دلیل دیگری است برای اطمینان خاطر از انتخاب درست.
۳- Xamarin forms
Xamarin forms همه آن چیزهای پایهای است که برای نوشتن یک برنامه لازم داریم. کنترل هایی مانند ListView، Button و ...به همراه Binding - Navigation و ...
در عمل میتوانید آن را معادل Angular & Angular Material بدانید. وقتی شما فرمی را با Xamarin Forms توسعه میدهید و درون آن دکمهای است که از فرم اول، شما را به فرم دوم میبرد، میتوانید آن را در هر جایی که Xamarin forms پشتیبانی میکند، استفاده کنید. پشتیبانی Xamarin forms برای Android/iOS/Windows خوب و برای Linux/Mac/Tizen و Web در مراحل اولیه است.
در Xamarin forms شما UI کاملا Native خواهید داشت.
۴- Prism Patterns & practices
Prism همه آن چیزی است که برای نوشتن یک برنامه با کیفیت، با قابلیت نگهداری بالا و تست پذیر احتیاج داریم.
با نقش Bit و کمکهای آن در طول مسیر آموزش بیشتر آشنا خواهیم شد.
در قسمتهای بعدی به آموزش نصب و نحوه دیباگ کردن کد و ارائه پابلیش در Android-iOS-Windows خواهیم پرداخت و سپس وارد کدنویسی شده و پروژه اولیه را خواهیم ساخت و در قسمتهای بعد از آن هم کار با دیتابیس کلاینت ساید، ارتباط با سرور و ... را آموزش میبینیم.
اگر قبلا Xamarin Forms را تست کردهاید و به علت مسائلی مانند حجم بالای خروجی برنامه و یا کندی در توسعه برنامه یا اجرای آن در دستگاه مشتری آن را کنار گذاشتهاید، توصیه میکنم بار دیگر آن را با ما تست کنید و با رعایت چند نکته ساده از نوشتن برنامه Cross Platform به بهترین شکل لذت ببرید و خروجی خوبی را در نهایت به مشتریان سیستم ارائه کنید.