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

۱۳۸۹ دی ۱, چهارشنبه

زندگی آسان تر: با یا بدون .Net؟

13 فوریه سال 2002 میلادی، مایکروسافت نسخه ابتدایی .Net را روانه بازار کرد. شاید از همان ابتدا و با توجه با ساختار و معماری کم نقص لایه ای آن می شد حس زد که این پلت فرم، پایه بخش بزرگی از نرم افزارهای کاربردی تولید شده در جهان خواهد شد و شاید بسیاری از برنامه نویسان .Net هم اکنون نیز معتقد باشند که بهترین گزینه برای طراحی نرم افزارهای کاربردی تحت ویندوز همین پلت فرم است. من هم به عنوان کسی که از سال 2004 به طور جدی برنامه نویسی بر پایه این کتابخانه بزرگ را آغاز کردم کم و بیش با این مسئله موافق هستم اما بارها شده است که در شرایط خاصی با خود گفته ام "اینجا را نمی خواهم تحت .Net بنویسم! چکار کنم؟!"
بی شک .Net یکی از قوی ترین و غنی ترین کتابخانه های برنامه نویسی در جهان است که در دسترس عموم برنامه نویسان قرار دارد. تقریبا هر کاری که بخواهید در یک نرم افزار کاربردی تحت ویندوز انجام دهید، توسط آن ممکن است و نیازی نیست که ذهن خود را درگیر جزئیات دست و پا گیر کنید. برای انجام هر کاری تنها باید 2-3 لایه آخر کلاسهای نرم افزار را طراحی کنید و ده ها لایه پشت آن را مایکروسافت برایتان نوشته است! کلاسهای بسیار زیادی در دسترستان قرار دارد به طوری که گاهی برای انجام یک کار و نوشتن بخشی از نرم افزار چندین کلاس مختلف وجود دارند که بسته به نوع نیاز نرم افزار و بسته به سطح دسترسی که می خواهید به منابع سیستم و لایه های پایین تر داشته باشید، می توانید یکی از آنها را انتخاب کنید. البته اگر این شانس را داشته باشید که همه این راهها را بشناسید. صرف نظر از برخی کلاسها و فضا های نام پیشرفته تر که کمی اصول مهندسی نرم افزار را زیر سوال می برند (برای نمونه Reflection) و از نظر من از این جهت انتقاداتی به آنها وارد است، به طور کلی معماری .Net این اصول را به خوبی رعایت کرده است. اگر از Visual Studio .Net استفاده کنید، برای یافتن کلاسهای مورد نظر خود از بین این هزاران کلاس موجود، Object Browser گزینه خوبی است و اگر جواب نگرفتید، MSDN!
اما برای مثال این وضعیت را تصور کنید:
قسمتی از برنامه ای را می نویسید، تست می کنید، به خوبی کار می کند فقط کمی کند است. به کد خود نگاه می کنید و کمی الگوریتم را دستکاری می کنید، بهبود چندانی به چشم نمی خورد. دیگر چیزی برای دستکاری وجود ندارد ولی هنوز مشخص نیست که چرا کند است! از Profiler استفاده می کنید و با کمال تعجب می بینید که دلیل اصلی کندی، الگوریتمی است که مایکروسافت در متدی که برای مثال در کلاس ساختمان داده خاصی بکار گرفته است. شاید در ابتدا عصبانی شوید ولی با کمی فکر کردن به این نتیجه می رسید که طراحان آن شاید راه دیگری جز نوشتن کد به این شکل نداشتند. مثلا یک الگوریتم درج ساده در یک لیست مرتب شده (Sorted List) را در نظر بگیرید. با درج هر عنصر جدید الگوریتم مرتب سازی لیست یک بار اجرا می شود و شاید رویدادی (Event) هم به اصطلاح راه اندازی (Trigger) شود. شاید طراحان این کلاس به دلیل دید کلی و عمومی که به آن داشته اند و به دلیل موارد استفاده گوناگونی که برای آن می دیدند راه دیگری برای طراحی آن نداشتند اما به هر حال در مورد خاص شما این مسئله باعث کندی نرم افزار شده است. البته برای این مثال خاص و مواردی از این دست مهندسین راه حلی به نام درج گروهی یا همان متد (.AddRange) را در نظر گرفته اند که به ازای درج یک آرایه بزرگ از عناصر عمل مرتب سازی تنها یک بار انجام می شود اما اولا این راه حل همه این مشکل را برطرف نمی کند و ثانیا این تنها مشکل نیست!
گاهی مسئله به نوع دیگری خود نمایی می کند. دسترسی های سخت و گاهی عجیب به برخی متدها برای انجام کاری خاص. البته شاید این جمله درستی نباشد، شاید بهتر باشد بگوییم وجود راه حلهای عجیب برای انجام کاری خاص! این مسئله با تعجب فراوان گاهاً به مرور زمان و ظهور تکنولوژی های جدید در قالب .Net پیچیده تر هم می شود. مثلا در WPF برای دسترسی به یک سلول از یک DataGrid کمی دردسر خواهید داشت. کاری که پیش از آن و برای برنامه های مبتنی بر Windows Forms بسیار راحت تر بود. البته شاید این مسئله را بتوان به همان دلیل کلی نگری که پیشتر ذکر کردم، توجیه کرد زیرا اساساً توانایی های DataGrid در WPF تغییرات زیادی کرده است اما بهر حال دردسر، دردسر است!
مشکلاتی از این دست در .Net کم نیستند اما تا جایی که به نوشتن برنامه های کاربردی (Application) مرتبط می شود، چندان مهم هم نیستند. مشکل اساسی، اقلاً برای خود من این است که گاهی از فکر کردن زیاد به این مشکلات و راه های ممکن برای حل و گاهاً دور زدن آنها آنقدر خسته می شوم که به شدت تحریک می شوم تا با سریعترین و شاید غیر اصولی ترین روش ممکن از شر آنها خلاص شوم که این مسئله شاید در نوشتن برنامه های کوچک زیاد مهم نباشد اما برای نوشتن برنامه های بزرگ قطعا مشکل زا خواهد بود. این نکته را می دانم که هیچ چیز نمی تواند بهانه ای برای غیر اصولی نوشتن کد آنهم با وجود آگاهی از این مسئله باشد اما واقعا گاهی هیچ راه دیگری وجود ندارد، شاید هم من راه دیگری پیدا نمی کنم و یا همانطور که گفتم حوصله جستجوی بیشتر را ندارم و می دانم که این مسئله تنها مختص من نیست!
یک مثال کوچک این است که گاهی مجبور به استفاده از کلاسهای فضای نام Reflection و Reflection.Emitمی شوم که برخی از آنها واقعا از نظر اصول مهندسی نرم افزار غیر استاندارد هستند، اما انگار طراحان .Net می دانستند که باید راه فراری برای برخی مشکلات احتمالی در آن می گذاشتند که Reflection و زیر مجموعه های آن یکی از آنهاهستند که البته در عین حال همین فضاهای نام کلاسهایی هم در خود دارند که به نظر من جزئی از زیبایی های .Net هستند.
با وجود این همه به نظر من .Net آنقدر امکانات در اختیار می گذارد و آنقدر راهها را کوتاهتر می کند که این مشکلات حتی اگر شما را مجبور به تفکر و کمی کد نویسی بیشتر از انتظار کنند،  ارزشش را دارد. اما همیشه وجود امکان کمی برنامه نویسی سطح پایین تر هم خوب است.
در پست آینده از دنیای .Net فاصله می گیریم و کمی به دنیای زیبای کد نویسی سیستمی خواهیم رفت...
با تشکر

۱۳۸۹ آذر ۱۶, سه‌شنبه

سیستم عامل چیست؟

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

سیستم عامل در واقع نرم افزاری است که همین فعالیت را به صورت خودکار انجام می دهد. با گذشت زمان و افزایش سرعت و توانایی کامپیوتر ها، وجود یک انسان برای تغییر برنامه ها و اختصاص زمان و منابع کامپیوتر به آنها باعث اتلاف بسیار زیاد وقت می شد و شاید در بسیاری مواقع مسئول نمی توانست بهترین و بهینه ترین ترتیب را برای اجرا به برنامه ها اختصاص دهد و این باعث بوجود  آمدن سیستم عامل (Operating System) شد. 

سیستم عامل ها به مرور زمان رشد کرده و به توانایی های آنها افزوده شد ولی همه آنها کم و بیش همان وظیفه ای را به عهده دارند که اجداد آنها به عهده داشتند یعنی اختصاص منابع محدود سیستم به بهینه ترین شکل به برنامه ها.

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

اما در واقع هسته اصلی این سیستم عامل نرم افزار نه چندان بزرگی است که ثانیه هایی پس از روشن شدن کامپیوتر روی حافظه اصلی (RAM) آن قرار می گیرد و امکان اجرای سایر برنامه ها را به کامپیوتر می دهد. این هسته که کرنل (Kernel) نام دارد  پایه ای ترین وظایف سیستم عامل را انجام می دهد و از نظر بسیاری از متخصصین اصلا کرنل خود سیستم عامل است و سایر قسمتها برنامه هایی هستند که توسط کرنل اجرا می شوند. از وظایف اصلی کرنل می توان به مدیریت اجرای برنامه ها و اختصاص زمان به همه آنها برای اجرا، مدیریت رویدادهای (event) حاصل از سخت افزار (یا Interupt ها) و مدیریت رویدادهای حاصل از برنامه ها (یا فراخوانی های سیستمی - System calls) اشاره کرد.

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

مفهوم دیگری به نام GUI یا رابط گرافیکی کاربر نیز وجود دارد که درواقع نرم افزاری است که به شکلی وظیفه ترسیم اشیاء مثل پنجره ها، منو ها و ... را بروی صفحه نمایش دارد و جزء اصلی سیستم عاملهای مدرن امروزی نیز هست.

به عنوان یک برنامه نویس اگر می خواهید وارد مبحث طراحی سیستم عامل شوید، باید اطلاعات خوبی از بسیاری از مفاهیم پایه ای علم کامپیوتر داشته باشید. سیستم عامل شاید پیچیده ترین نرم افزاری است که یک برنامه نویس در تمام طول مدت زندگی حرفه ای خود ممکن است در طراحی آن دخیل باشد. پیچیده ترین قسمت طراحی سیستم عامل طراحی کرنل آن است که معمولا توسط یک تیم کوچک از برنامه نویسان بسیار ماهر طراحی می شود (گاهی 1 یا 2 نفر).

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

-آشنایی با زبان C (یا ++C) - گرچه برخی سیستم عامل های کوچک تحقیقاتی با Pascal  و همینطور FreeBasic نیز نوشته می شوند.

-آشنایی با برنامه نویسی Assembly - معمولا C توانایی انجام بخش اعظم کارها را دارد اما همیشه نیاز به اسمبلی هم هست.

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

-تجربه خوب برنامه نویسی

-تجربه کار با Unix/Linux - اکثر ابزارهای لازم برای طراحی سیستم عامل برای این محیطها طراحی شده اند گرچه نمونه ویندوزی برخی از آنها هم وجود دارد.

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

-آشنایی کامل با پلت فرم هدف - در وافع نوع CPU هدف، ساختار داخلی و مجموعه دستورات اسمبلی آن باید به طور کامل برای برنامه نویس شناخته شده باشد.

موفق و پیروز باشید

۱۳۸۹ آذر ۷, یکشنبه

WPF چیست؟

WPF مخفف عبارت Windows Presentation Foundation، نسل جدید روشهای تولید نرم افزارهای سمت کاربر مایکروسافت است.

کسانی که پیش از این تجربه کار با سایر تکنولوژی های تولید نرم افزار و سایر محیطهای برنامه نویسی را داشته اند احتمالا این تکنولوژی را بسیار متفاوت خواهند یافت. این تکنولوژی در ابتدا همراه با Net framework 3.0. عرضه شد و هم اکنون نیز با کمی تغییرات روی نگارش 4 آن ارائه می گردد.

هنگام شروع کار با WPF بزرگترین تفاوت را در شیوه طراحی ظاهر یا همان رابط گرافیکی کاربر (GUI) خواهید دید. طراحی ظاهر نرم افزار بیشتر از اینکه به سایر زبانها و تکنولوژی های ویژوال شبیه باشد به طراحی صفحات HTML شباهت دارد. مایکروسافت از ایده جدیدی در این تکنولوژی استفاده کرده است که پیش از این چیزی شبیه به آن را در ASP.NET ارائه کرده بود. جدایی کد نرم افزار از ظاهر آن. اگر با ASP.NET آشنا باشید می دانید که در این تکنولوژی کدهای xHTML همراه با بعضی تگهای ASP.NET که عموما مربوط به ظاهر صفحات وب است در فایلهایی با پسوند aspx. ذخیره شده و سپس کد پشت هر صفحه که در سمت سرور کامپایل و اجرا می شوند، بسته به نوع زبان برنامه نویسی استفاده شده در فایهایی با پسوند aspx.cs. و یا aspx.vb ذخیره شده و یا حتی کامپایل شده و در فایلهای dll. ذخیره می شوند. این مسئله جدایی کد سمت سرور و طراحی ظاهری را تا حدود زیادی مهیا می ساخت. می شد طراحی ظاهر را به طراح و متخصص گرافیک وب سپرد و برنامه نویس با خیال آسوده به نوشتن کدهای سمت سرور بپردازد.

مایکروسافت از این شیوه برای جدا کردن طراحی رابط کاربری نرم افزار و همینطور کد پشت آن استفاده کرده است. در WPF از XAML (بخوانید زَمِل) برای طراحی رابط کاربری و در واقع ظاهر پنجره های نرم افزار استفاده می شود. XAML از قوانین XML برای نوشتن کدهای طراحی ظاهر پنجره ها استفاده می کند. متن زیر نمونه ای از یک کد XAML است:

<Window>
<Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="120"/>
            <RowDefinition Height="2*" />
            <RowDefinition Height="1*" x:Name="rw1"/>
            <RowDefinition Height="30" />
        </Grid.RowDefinitions>
   <Label Name="lblF1" Content="از تاریخ" Grid.Column="0" Grid.Row="0"                 HorizontalContentAlignment="Right" />
        <Label Name="lblF2" Content="تا تاریخ" Grid.Column="4" HorizontalContentAlignment="Right" />
.
.
.
.
</Grid>
</Window>

کد های نرم افزار نیز با یکی از زبانهای NET. مثل #C یا VB نوشته می شود.

البته این تنها تفاوت WPF با تکنولوژی های پیشین نیست، بلکه همانطور که پیشتر گفتم شاید بارز ترین تفاوت آن باشد. WPF برای نمایش کنترل ها روی پنجره و حتی نمایش خود پنجره از DirectX استفاده می کند که نتیجه آن پشتیبانی از گرافیک بسیار جذاب از نوع برداری است که با هر مقدار بزرگ نمایی باز جزئیات آن حفظ می شود. می توانید از انواع انیمیشن ها برای ساخت پنجره های غنی از گرافیک استفاده کنید. در ضمن جدا بودن کد نرم افزار از کد رابط کاربری یا همان XAML این امکان را فراهم کرده که نرم افزار های جانبی زیادی از سوی شرکت مایکروسافت و همینطور سایر شرکتها برای طراحی ظاهر گرافیکی بسیار جذاب و غنی تولید شوند. نرم افزارهایی مثل Microsoft Expression Blend که به طور خاص و با تمرکز بروی گرافیک برای طراحی پنجره های نرم افزار طراحی شده اند که طراح با استفاده از آنها نیاز چندانی به نوشتن کدهای XAML ندارد و می تواند بسیار راحت تر به تولید محتوای گرافیکی صفحات و پنجره های نرم افزار بپردازد.

خصوصیات WPF تنها محدود به گرافیک و رابط کاربری نیستند. Databinding در WPF تغییرات عمده ای کرده است. می توانید هر کنترلی در پنجره برنامه را به هر نوع مجموعه داده مثل آرایه ها، لیست ها،Dataset ها و ... متصل (Bind) کنید. کلاً Databinding بسیار کاربردی تر و جذاب تر از پیش شده است.

از جمله تغییرات دیگر می توان به مباحثی مثل Globalization و Localization اشاره کرد.

با کمی کار کردن باWPF و نوشتن یک نرم افزار کاربردی با تفاوتهای عمده آن با روشهای پیشین طراحی نرم افزار آشنا خواهید شد، چه پیش از این از Net. استفاده کرده باشید چه نه!

با روشهای مشابهی توسط WPF می توانید نرم افزارهای قابل نمایش در web browser یا Browser Hosted Application ها را طراحی کنید.

برای اطلاعات بیشتر می توانید به  MSDN مراجعه کنید.

با تشکر از همراهی شما

۱۳۸۹ آذر ۶, شنبه

چگونه یک برنامه نویس خوب شوم؟

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

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

حال اگر قرار باشد از برنامه نویسان نسخه های برتر بخواهید که امکان بزرگ دیگری را به نرم افزار اضافه کرده و روند کاری بخشی از نرم افزار را به طور کلی تغییر دهند، احتمالا با نتایج جالبی برخورد خواهید کرد. گروهی از برنامه نویسان نرم افزار خود را در مدت چند روز تغییر داده و تحویل می دهند، بعضی در مدت چند هفته و بعضی دیگر شاید اصلا نتوانند این کار را انجام دهند و با مشکلات و به اصطلاح باگ های فراوانی روبرو شوند. شاید گروهی از آنها بگویند "اگر از همان ابتدا کل نرم افزار را برایمان مشخص کرده بودید برایتان طراحی می کردیم ولی الان تغییرات بسیاری لازم است"  و شما در جواب می گویید "چطور فلانی توانست نرم افزار را در مدت 2 روز به طور کامل تغییر دهد؟".

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

در عمل و در یک تیم طراحی نرم افزار، وظیفه طراحی ظاهر و رابط کاربری به عهده برنامه نویس نیست بلکه مهندسین نرم افزار طی جلساتی که شاید همه برنامه نویسان در آن حضور نداشته باشند، رابط کاربری نرم افزار را تعیین کرده و با در نظر گرفتن اولویتهای کاری نرم افزار بهترین و راحت ترین شیوه برقراری ارتباط کاربر با نرم افزار "از نظر خود" را تعیین می کنند. همین مهندسین نرم افزار معماری نرم افزار و کلاسهای موجود در آن را تعیین می کنند و در نهایت احتمالا رابطهای کلاس (Interface) نوشته شده و سپس برنامه نویسان وارد عمل می شوند.

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

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

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

برای اینکه یک برنامه نویس خوب باشیم لازم است از مسائل پایه ای که مربوط به کارایی نرم افزار می شود شروع کنیم. الگوریتم و ساختمان داده (Data Structure).

اصول طراحی الگوریتم ها یکی از مهمترین مباحثی است که هر برنامه نویسی باید با آن آشنا باشد، مبحثی که در آن برنامه نویس با انواع الگرویتمهای روتین برای حل دسته های مختلف مسائل آشنا می شود، یاد می گیرد که چطور سرعت و کارایی یک الگوریتم را محاسبه کند و حتی پیش بینی کند که برای یک مسئله خاص الگوریتمی که در ذهن اوست به نتیجه می رسد و یا خیر. کتایهای زیادی برای آشنایی برنامه نویسان با این مبحث وجود دارد که معروفترین مرجع دانشگاهی آن در دنیا معروف به CLRS است.

ساختمان داده ها نیز از جمله مباحث بسیار مهم است که برنامه نویس در آن با انواع ساختارهای داده ای در علم کامپیوتر آشنا شده، معایب و مزایای آنها را متوجه شده و می تواند تشخیص دهد که در هر موقعیت و برای هر کاری از کدام ساختار استفاده کند. این ساختار های به طور کلی برای نگهداری داده ها استفاده می شوند، از نگهداری داده ها بروی حافظه اصلی و برای انجام پردازش روی آنها گرفته تا نگهداری داده های با حجم بالا روی حافظه های کمکی. از جمله آنها می توان به موارد زیر اشاره کرد.
Linked List ها، Queue ها،Stack ها، Tree ها،Dictionary و ...

لازم به ذکر است که این دو مبحث ار مسائل پایه ای هستند و برنامه نویس در مرحله بعد به جز در مواردی خاص لازم است برای نوشتن اکثر نرم افزارهای کامپیوتری با برنامه نویسی شیء گرا و اصول مهندسی نرم افزار نیز آشنا باشد.

البته تمرین، مطالعه و تفکر از ضروری ترین اموری هستند که هر برنامه نویسی در هر سطحی باید مد نظر قرار دهد.

در انتها ذکر این نکته لازم است که طراحی ظاهر نرم افزارها در اکثر کشورهای جهان زیر مجموعه شاخه ای از علم کامپیوتر به نام "تعامل انسان و کامپیوتر" (Human Computer Interaction) است.

۱۳۸۹ آذر ۵, جمعه

برنامه نویسی شیء گرا (Object Oriented Programming - OOP)

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

شاید این سوال کمی مبهم به نظر برسد، ولی احتمالا در ادامه مطلب متوجه خواهید شد که منظور من از طرح این سوال چه بود. راهی که امروز برنامه نویسان برای حل اینگونه مسائل استفاده می کنند این است که به همه این وسایط نقلیه به عنوان یک شیء نگاه می کنند، به این معنی که برای مثال همه وسایط نقلیه را به عنوان یک شیء در نظر می گیرند و همه خصوصیات مشترک آنها را یکجا تعریف می کنند. برای مثال همه وسایط نقلیه حرکت می کنند پس متغیر های مرتبط با حرکت بین همه آنها مشترکند مثل سرعت و جهت حرکت (یا در واقع بردار سرعت)، شتاب و جهت آن (یا بردار شتاب) و همینطور موقیت فعلی با توجه به محورهای مختصات (x,y,z). شاید بتوان متغیر های مشترک دیگری نیز بین آنها پیدا کرد مثل وزن، حداکثر سرعت، مقاومت در برابر باد و ... .
برنامه نویس همه اینها را به عنوان خصوصیات مشترک وسایط نقلیه در نظر می گیرد و در یک بسته به نام کلاس تعریف می کند.
البته متغیرها تنها چیزهایی نیستند که می توان در یک کلاس تعریف کرد، ولی فعلا به همین بسنده می کنیم و به بحث ادامه می دهیم.
حال نوبت به تعریف وسایط نقلیه ای که روی زمین حرکت می کنند می رسد. از این دسته می توان به اتومبیل ها و کامیونها اشاره کرد. خصوصیات مشترک همه اینها کدامند؟ اصطکاک با زمین شاید یکی از آنها باشد. حداکثر تعداد دنده ها و همینطور دنده جاری نیز می توانند جزء این متغیر ها باشند. برنامه نویس این متغیر ها را در یک کلاس دیگر تعریف می کند اما حتما یادتان هست که این کلاس همه خصوصیات کلاس بالاتر (وسایط نقلیه) که در بالا ذکر شد را دارند. به همین دلیل این کلاس (وسایط نقلیه زمینی) همه خصوصیات کلاس بالاتر را به ارث می برد. به همین ترتیب می توان کلاسهای دیگر مثل وسایل نقلیه هوایی و آبی را تعریف کرد و سپس زیر مجموعه های هرکدام (مثلا کامیون و اتومبیل به عنوان زبر مجموعه های وسایط نقلیه زمینی).

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

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

شایان ذکر است که توضیحات بالا تنها بخش کوچکی از خواص برنامه نویسی شیء گرا را بیان کرد و طبعا فواید ذکر شده در این مورد نیز بر اساس مطالب گفته شده بود. اشیاء یا کلاسها خواص بسیار بیشتری دارند و به همین شکل فواید آنها نیز بسیار بیشتر خواهد بود.

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

یک شی (Object)  ممولا یک مفهوم در دنیای واقعی مثل کالا، شخص، حساب بانکی و ... را نشان می دهد. می توان گفت که شیء یک نمونه (Instance) از کلاس است، اگر شخص یک کلاس باشد، آقای "علی احمدی" یک شیء است.
زیر کلاسها معمولا خاص تر از کلاسهای والد هستند و به طور دقیق تر خصوصیات یک شیء را بیان می کنند. مثل کلاس وسایط نقلیه به عنوان والد و کلاس وسایط نقلیه زمینی به عنوان کلاس فرزند در مثال بالا. به این خاصیت ارثبری (Inheritance) گفته می شود.

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

تقریبا تمام زبانهای برنامه نویسی امروزی از برنامه نویسی شیء گرا به طور کامل پشتیبانی می کنند. C++ مهمترین آنهاست و اگر مایل به راحتی بیشتر درطراحی نرم افزار ها هستید و بیشتر به برنامه های تجاری تحت ویندوز فکر می کنید، C#.net یا VB.net گزینه های مناسبی برای شما می باشند. شاید یاد گرفتن VB.net راحت تر از C#.net باشد، باز هم تاکید می کنم که شاید!، اما توصیه من به شما این است که اگر برنامه نویسی به هیچ زبانی را بلد نیستید، با C# شروع کنید چون هم مدت زمان کمتری را صرف یادگیری این زبان می کنید (نسبت به C++) و هم اگر در آینده بخواهید C++ را یاد بگیرید و کمی پیشرفته تر کار کنید، به دلیل نزدیکی قواعد نحوی دو زبان بسیار راحت تر خواهید بود. ضمنا کسی که C#.net را بلد است، به دلیل Platform یکسان آن با VB.net براحتی می تواند آن را نیز یاد بگیرد، گرچه نیازی به این کار نخواهد بود. اگر یکی از زبانهای .net را یاد گرفته باشید نیاز زیادی به یادگیری سایر آنها پیدا نخواهید کرد، چون تقریبا توانایی های یکسانی دارند. در ضمن C# به طرز باور نکردنی به Java نزدیک است و اگر نیاز به یادگیری Java داشتید پس از یادگیری C# کار چندان سختی پیش رو ندارید.

در پستهای بعد سعی خواهم کرد زبانهای برنامه نویسی را با هم مقایسه کنم.

امیدوارم این مطلب مفید بوده باشد.

موفق باشید.