زبانهای برنامهنویسی این ظرفیت را دارند که از یک یا چند شیوه برنامهنویسی پشتیبانی کنند. بهطور مثال، برنامههای نوشته شده با سی پلاسپلاس میتوانند بهطور کامل رویهای یا منطبق بر شیوه برنامهنویسی شئگرا که در تضاد کامل با شیوه رویهای است یا حتا حاوی عناصری از هر دو شیوه باشند. تصمیمگیری برای چگونگی استفاده از الگوهای برنامهنویسی توسط برنامهنویس انجام میشود. در ادامه به چند مورد از رایجترین الگوهای برنامهنویسی اشاره میکنیم.
برنامهنویسی دستوری
برنامهنویسی دستوری (Imperative programming) یکی از پارادایمهای برنامهنویسی است که در آن مراحل اجرای یک برنامه کامپیوتری قدم به قدم توسط برنامهنویس مشخص میشود. رویکرد فوق بر عکس زبانهای اعلانی است که در آنها تنها نتیجه انجام دستورها بیان میشود. به عبارت دیگر در زبانهای دستوری چگونگی اجرای برنامه مشخص میشود، اما در زبانهای اعلانی چیستی نتیجه بیان میشود. بهطور مثال، اگر قصد روشن کردن ماشینی را داشته باشیم و با زبان اعلانی اینکار را بخواهیم بیان کنیم خواهیم گفت ماشین را روشن کن، اما اگر با زبان دستوری بیان کنیم خواهیم گفت بلند شو، به طرف ماشین نزدیک شو، درب ماشین را باز کن، سوییچ را در بچرخان، پدال گاز را فشار بده و ماشین را روشن کن.
برنامهنویسی اعلانی
برنامهنویسی اعلانی یکی دیگر از الگوهای برنامهنویسی است که در آن منطق و هدف محاسبات بدون شرح چگونگی انجام آنها بیان میشود. در این پارادایم تلاش میشود با توصیف عملیات مورد نیاز بهجای توضیح چگونگی انجام عملیات، اثر جانبی برنامهها را کاهش یا به کل از میان برداشت که از لحاظ اولویتهای عملیاتی در تضاد با الگوی برنامهنویسی دستوری است. زبانهای دستوری زبانهایی هستند که عملیات تحلیلی را برحسب عباراتی که در وضعیت برنامهها تغییراتی ایجاد میکنند، شرح میدهند حال آنکه زبانهای اعلانی برنامهها رابه عنوان اصول منطق محاسباتی و مولفههای کوچک درون فضای آن منطق میبینند. از آنجایی که این پارادایم میتواند تا حد زیادی نوشتن برنامههای موازی برای محاسبات موازی را ساده کند با استقبال برنامهنویسان روبرو شده است. زبانهای معمول اعلانی شامل برنامهنویسی تابعی، عبارت باقاعده، برنامهنویسی منطقی میشوند.
برنامهنویسی تابعی (functional programming)
در این شیوه برنامهنویسی محاسبات و تحلیلات به مانند ارزیابی توابع ریاضیاتی هستند و از دادههای توضیحی (state) و بیثبات (mutable) دوری میشود. همچنین بر خلاف برنامهنویسی دستوری که به تغییرات وضعیت درون برنامهها تأکید دارد روی کاربرد توابع تآکید دارد. از جمله این زبانهای برنامهنویسی میتوان به لیسپ و ای پی ال اشاره کرد که بعدها نمونههای پیشرفته آن مانند اسکیم ایجاد شد. در برنامهنویسی تابعی، توابع به عنوان عناصر درجه یک تلقی میشوند. به عبارت دیگر، توابع را میتوان به نامها (از جمله شناسههای محلی) مقید کرده، به عنوان آرگومان ارسال کرده یا از توابع دیگر بازگرداند. این ویژگی این امکان را فراهم میکند که برنامهها به شکل اعلانی و ترکیبپذیر نوشته شوند، بهطوری که که توابع کوچک به صورت پودمانی با هم ترکیب میشوند. برنامهنویسی تابعی گاهی به عنوان مترادفی برای برنامهنویسی تابعی محض در نظر گرفته میشود. این نوع برنامهنویسی زیرمجموعهای از برنامهنویسی تابعی است که در آن تمام توابع به عنوان توابع ریاضی و قطعی یا تابع سره تلقی میشوند. هنگامی که یک تابع سره با مجموعه آرگومانهای ثابت فراخونی میشود، همیشه همان نتیجه را برمیگرداند و نمی تواند تحت تأثیر هیچگونه حالت قابل تغییر یا اثر جانبی دیگری باشد. این برخلاف توابع غیرسره است که معمولاً در برنامهنویسی دستوری استفاده میشود و میتواند اثرات جانبی داشته باشد (مانند تغییر وضعیت برنامه یا گرفتن ورودی از یک کاربر). طرفداران برنامهنویسی تابعی محض ادعا میکنند که با محدود کردن اثر جانبی، برنامهها اشکالات کمتری داشته؛ همچنین اشکالزدایی و تست نرمافزار آسانتر میشود. از سوی دیگر استفاده از این رویکرد برای دستیابی به درستییابی صوری نرمافزار مناسبتر است. توابع مرتبه بالاتر در برنامهنویسی تابعی، توابعی هستند که میتوانند توابع دیگری را به عنوان آرگومان به کار گرفته یا آنها را به عنوان نتیجه برگردانند. توابع مرتبه بالاتر ارتباط نزدیکی با توابع مرتبه اول دارند زیرا توابع مرتبه بالا و توابع مرتبه یک هر دو توابع را به عنوان آرگومان دریافت کرده و به عنوان نتیجه برمیگردانند. تمایز بین این دو ظریف است: «مرتبه بالاتر» یک مفهوم ریاضی از توابعی که بر روی توابع دیگر کار میکنند توصیف میکند؛ در حالی که «مرتبهٔ اول» یک اصطلاح علوم کامپیوتر برای موجودیتهایی در زبانهای برنامهنویسی است که هیچ محدودیتی در استفاده از آنها وجود ندارد (بنابراین توابع مرتبه اول میتواند در هر جایی از برنامه که سایر موجودیتهای مرتبه اول – مانند اعداد – مجاز هستند؛ استفاده شوند. این شامل آرگومانهای ورودی و مقادیر بازگشتی از توابع نیز هست).
برنامهنویسی مبتنی بر خودکارسازی
برنامهنویسی مبتنی بر اتوماتا (Automata-based programming) یک الگوی برنامهنویسی است که در آن کل برنامه یا بخشی از آن به صورت مدلی از ماشین حالات متناهی (FSM) یا دیگر روالهای خودکار قراردادی دیگر (که اغلب پیچیدهتر هستند) تصور میشود. اتوماتای بر اساس برنامهنویسی نمونهای از برنامهنویسی است که برنامه و قسمتهای مختلف آن سعی بر این دارند تا یک ماشین متناهی را مدل کنند. برنامهنویسی مبتنی بر FSM نیز مانند برنامهنویسی مبتنی بر اتوماتیک است، با این تفاوت که تمامی جنبههای ماشین متناهی را پوشش نمیدهد. موارد زیر مشخصههای برنامهنویسی مبتنی بر اتوماتیک است:
زمان اجرای برنامه به وضوح از مراحل اتوماتا جدا است
ارتباط میان مراحل فقط از طریق رفتن از یک وضعیت به وضعیت دیگر میباشد.
تمام مراحل اجرای یک اتومات بهطور کلی یک چرخه اتوماتا را میگویند.
برنامهنویسی شیءگرا
برنامهنویسی شیءگرا (Object-Oriented) یکی دیگر از پارادایمهای مطرح برنامهنویسی است که ساختار یا بلوک اصلی اجزای آن، شیها هستند. در این شیوه برنامهنویسی، برنامه به شی گرایش پیدا میکند، به این معنا که دادهها و توابعی که بر روی این دادهها عمل میکنند، تا حد امکان در قالبی به نام شیء و در کنار یکدیگر قرار گرفته، جمعبندی شده و یک واحد (یا یک شیء) را تشکیل میدهند و نسبت به محیط بیرون خود، کپسوله میشوند. از این طریق، توابع خارج از آن شیء، امکان ایجاد تغییر در دادههای درون شیء را نخواهند داشت. زبانهایی مانند جاوا، سی پلاس پلاس، سی شارپ، دلفی از جمله زبانهای شیگرا هستند. حتی بسیاری از زبانهای روالگونه که ساختار برنامهها در آنها بلوکهایی با نام پروسیجر است، امروزه از فنون شیگرایی نیز پشتیبانی میکنند. هر شیء یک سری خصوصیت و قابلیت دارد، که اصطلاحاً خاصیتها و عملیات خوانده میشوند. در این پارادایم برنامهنویسی، دید برنامهنویس به سیستم، دید شخصی است، که سعی مینماید با پیدا کردن اشیاء مختلف در سیستم و برقراری ارتباط بین آنها، سیستم را تولید نماید. تکنیک برنامهنویسی شی گرا در مقایسه با برخی از پارادیمهای برنامهنویسی به مراتب کارا و پیچیدهتر است. از مهمترین دلایل برتری برنامهنویسی شیگرا میتوان به قابلیت سازماندهی بهینهتر کدها، قابلیت تقسیم برنامه به برنامههای کوچکتر اما مستقل، عدم نیاز به نوشتن کدهای تکراری و قابلیتهایی که قبلاً پیادهسازی شدهاند و صرف جویی در استفاده از منابع اشاره کرد. با این حال، بسیاری از توسعهدهندگان سعی میکنند در پروژههای کوچک و ساده خود از سبک برنامهنویسی تابعی استفاده کنند. وراثت یا ارث بری (Inheritance) از مفاهیم اساسی برنامهنویسی شیءگراست. هر شیء یک نمونه از یک کلاس است و هر کلاس میتواند از کلاس یا کلاسهای دیگری مشتق شده باشد (خواص متدها یا رویدادهای کلاسهای دیگر را به ارث ببرد). این ویژگی باعث صرفهجویی در نوشتن کد و تا حدودی تضمین صحت کد موجود میشود. بهطور مثال، اگر کلاس پایه مشکلی داشته باشد فقط کافی است کلاس پایه تغییر داده شود و در تمامی کلاسهایی که از این کلاس پایه ویژگیای را به ارث بردهاند این تغییر اعمال خواهد شد. چند ریختی، کمیتی است که به یک رابط امکان میدهد تا از عملیات یکسانی در قالب یک کلاس عمومی استفاده کند. عمل خاص کلاس را ذات حقیقی شیء تعیین میکند. مثال سادهای از چند ریختی، فرمان اتومبیل است. عمل فرمان اتومبیل برای تمام اتومبیلها بدون توجه به ساز و کاری که دارند، یکسان است. فرمان برای اتومبیل که بهطور مکانیکی کار میکند یا با نیروی برق یا هر چیز دیگری، عمل یکسانی را انجام میدهد؛ بنابراین، پس از اینکه شما عملکرد فرمان را یادگرفتید، میتوانید فرمان هر اتومبیلی را کنترل کنید. همین هدف در برنامهنویسی نیز اعمال میشود. بهطور کلی، مفهوم چند ریختی، اغلب با عبارت «یک رابط، چندین روش» بیان میشود. این بدین معنی است که امکان طراحی رابط عمومی برای گروهی از عملیات مرتبط وجود دارد. چند ریختی یا چندشکلی (Polymorphism) به این معنا است که اشیاء میتوانند در موقعیتهای مختلف، رفتارهای متفاوتی بروز دهند. مثلاً یک تابع در صورتی که بر روی نمونهای از کلاس آ فراخوانی شود، رفتار ب را بروز دهد در حالی که اگر بر روی کلاس ج (که فرزند کلاس آ است) فراخوانی شود، رفتاری متفاوت انجام دهد.
برنامهنویسی پروسهای
برنامهنویسی پروسهای یا برنامهنویسی روال (Procedural programming) یک پارادایم برنامهنویسی بر پایه مفهوم فراخوانی پروسهها است. پروسه که همچنین به نامهای روال، زیرروال (سابروتین)، تابع، روش شناخته میشود، دربردارنده یک سری گامهای محاسباتی است که باید توسط رایانه اجرا شوند. هر پروسه میتواند در هر نقطهای در طول اجرای برنامه فراخوانده شود شامل فراخوانی پروسه توسط خودش (برنامهنویسی بازگشتی) یا پروسههای دیگر.
برنامهنویسی منطقی
برنامهنویسی منطقی (Logic Programming) یک پارادایم برنامهنویسی است که بهصورت عمده بر پایه منطق گسترش یافته است. هر برنامه در یک زبان برنامهنویسی منطقی، مجموعهای از جملات منطقی است که حقایق (Facts) و خطمشیها (Rules) یک مسئله را شرح میدهد. از رایجترین زبانهای برنامهنویسی منطقی میتوان به پرولوگ و دیتالاگ اشاره کرد. در این زبانها قوانین به شکل بند درج میشوند:
H :- A1, A2, …, An.
بند فوق بهصورت «H صحیح است اگر A1 و A2 و … و An صحیح باشند» خوانده میشود. هر بند دارای یک راس و یک بدنه است. در بند بالا H راس و A1, … , An بدنه هستند. قوانینی که دارای بدنه نباشند، حقایق نامیده میشوند.
زبان برنامهنویسی پویا
زبان برنامهنویسی پویا (Dynamic programming language) یک کلاس از زبانهای برنامهنویسی سطح بالا است که در زمان اجرا، سبب اجرای بسیاری از رفتارهای مشترک برنامهنویسی که زبانهای برنامهنویسی ایستا در طول کامپایل انجام میدهند میشود. این رفتارها میتواند شامل فرمت برنامه، با اضافه کردن کد، با گسترش اشیاء و تعاریف یا با تغییر نوع سیستم همراه باشد. اگر چه رفتارهای مشابه را تقریباً میتوان در هر زبان با درجات مختلفی از دشواری، پیچیدگی و هزینههای عملکرد، زبان پویا که فراهمکننده ابزارهایی برای استفاده از آنها میباشد را شبیهسازی کرد. بسیاری از این امکانات برای اولین بار به عنوان ویژگیهای اصلی در زبان برنامهنویسی لیسپ پیادهسازی شدهاست.
پویاترین زبانها نیز از نوع پویا میباشند، اما نه همه آنها. زبانهای پویا اغلب (اما نه همیشه) به عنوان «زبانهای اسکریپتنویسی» شناخته میشود، اگر چه اصطلاح «زبانهای اسکریپتنویسی» در مفهوم دقیقتر اشاره به زبان خاص به یک محیط زمان اجرا دارد.
برنامهنویسی رویداد گرا
برنامهنویسی رویداد گرا یک الگوی برنامهنویسی است که در آن، روند اجرای برنامه توسط رویدادها – برای مثال، خروجی یک سنسور یا دستورهای کاربر (کلیکهای موس، دکمههای کیبورد) یا پیامهای دریافتی از سایر برنامهها یا رشتهها – تعیین میگردد. برنامهنویسی رویدادگرا را میتوان به عنوان یک تکنیک معماری نرمافزار تعریف کرد که در آن نرمافزار یک حلقه اصلی دارد که به روشنی به دو انتخاب رویداد (یا شناسایی رویداد) و اداره کردن رویدادها تقسیم میشود. برنامههای رویدادگرا را میتوان در هر زبانی نوشت، اگرچه این کار در زبانهایی که سطح بالایی از انتزاع را فراهم میکنند، آسانتر است. به دلیل اینکه کد بررسی رویدادها و حلقه اصلی در میان برنامهها مشترک هستند، بسیاری از چهارچوبهای برنامهنویسی مسئولیت پیادهسازی را بر عهده دارند و از کاربر انتظار دارند که تنها کد نگهدارنده رویداد را فراهم کنند. در این مثال ساده ممکن است یک نگهدارنده رویداد فراخوانده شود که OnKeyEnter() نامیده میشود و شامل ارگومانی با یک رشته از کاراکترهاست که متناظر است با آنچه که کاربر قبل از فشردن دکمه ENTER تایپ کرده ست. برای اضافه کردن دو عدد، ذخیرهسازی خارج از نگهدارنده رویداد باید مورد استفاده قرار گیرد.
برنامهنویسی غیر ساخت یافته
برنامهنویسی غیر ساخت یافته قدیمیترین پارادایم برنامهنویسی است که قادر به نوشتن الگوریتم برنامه تورینگ کامل است. این برنامهنویسی بعداً با برنامه نویسی تابعی و سپس برنامه نویسی شی گرا ادامه یافت و هر دو این برنامهها به عنوان برنامهنویسی ساخت یافته در نظر گرفته شدند. برنامهنویسی غیر ساخت یافته به خاطر تولید کدهایی که به سختی قابل خواندن بودند (اسپاگتی کد) به شدت مورد انتقاد قرار گرفت و گاهی اوقات یک روش بد برای نوشتن پروژههای بزرگ در نظر گرفته شد. با اینحال، این نوع برنامهنویسی برای آزادیای که به برنامهنویسان میدهد تحسین شدهاست و با این مقایسه شدهاست که موزارت چگونه موسیقی را نوشته است. هر دو زبانهای برنامه نویسی سطح بالا و سطح پایین وجود دارند که به عنوان زبانهای برنامه نویسی غیر ساخت یافته استفاده میشوند.