از مترجم: متأسفانه من تجربه قابل توجهی در ترجمه از زبان انگلیسی ندارم، هرچند به زبان انگلیسی بسیار مطالعه می کنم. اما معلوم شد که خواندن و ترجمه دو چیز متفاوت هستند. همچنین متأسفانه من تجربه برنامه نویسی قابل توجهی ندارم (من اخیراً یک برنامه وب ساده در Spring MVC و Hibernate ساخته ام). بنابراین، ترجمه بسیار بدتر از آن چیزی که می توانست باشد انجام شد. من این اختیار را داشتم که نمونه کدهای ارائه شده در مقاله را کمی تصحیح کنم، زیرا آنها با قراردادهای نامگذاری در جاوا مطابقت ندارند. شاید ارزش ترجمه نام برخی از الگوها را نداشته باشد (چنین ترجمه ای درک چندانی ارائه نمی دهد)، اما من فکر می کردم که این بد کوچکتر است. شایان ذکر است که «انسجام بالا» به عنوان ترجمه «انسجام بالا» به طور جداگانه ذکر شود. موافقم، بهترین ترجمه نیست. اما "اتصال قوی" "اتصال بالا" است (مفهوم مهم دیگر) و بعید است که "انسجام" در اینجا مناسب باشد. من پذیرای انتقاد هستم و نظرات خود را در مورد مقاله به هر شکلی با کمال میل می پذیرم. برنامه نویسی شی گرا سبکی از برنامه نویسی است که در آن یک برنامه از اجزایی تشکیل شده است که مطابق با اشیاء دنیای واقعی هستند. بسته به دیگران تغییر می کند). به عنوان مثال، مداد یک شی دنیای واقعی است که دارای ویژگی های زیر است:
- قرمز است (این در طول زمان تغییر نمی کند).
- اکنون 10 سانتی متر طول دارد (اگر مداد تیز شود ممکن است تغییر کند).
- در صورت استفاده صحیح اثری از خود بر جای می گذارد.
- ردیابی ممکن است بسته به فشار (بسته به عوامل خارجی) متفاوت باشد.
- طول آن با تیز شدن کوتاه می شود (رفتار دائمی).
انتزاع - مفهوم - برداشت
انتزاع به عنوان کیفیت تعامل با ایده ها به جای رویدادها یا به عبارت دیگر آزادی از کیفیت های بازنمایی تعریف می شود . این به برنامه نویسان این امکان را می دهد که به جای اینکه چگونه برنامه نویسی کنند ، روی برنامه نویسی تمرکز کنند . انتزاع را می توان به عنوان قراردادی در نظر گرفت که از طریق آن عملکرد را ارائه می کنیم. جزئیات پیاده سازی ممکن است هنگام استفاده از این مفهوم پنهان باشد. مثلاً اگر به کلاسی نیاز داریم که می نویسد، پس باید مطمئن باشیم که متد «نوشتن» دارد، چه کار کرده ایم؟ ما یک کلاس سطح بالا طراحی کرده ایم که انتزاعی است، به عبارت دیگر می داند که ما به چه عملکردی نیاز داریم، اما نحوه پیاده سازی آن از حیطه این کلاس خارج است. این مزایای بسیاری را ارائه می دهد:abstract class writer { write (); }
- ما حداقل اطلاعات لازم را در اختیار نهادهای خارجی قرار میدهیم، این به ما امکان میدهد از طریق برنامه بر روی تفکر تمرکز کنیم (این کار تفکر متمرکز را فعال میکند)، از سردرگمی جلوگیری کرده و از دادن وعدههای ناخواسته خودداری کنیم.
- ما فضایی را برای پیشرفتهای آینده میگذاریم که در صورت فاش شدن جزئیات پیادهسازی امکانپذیر نخواهد بود.
وراثت
«ارث» در انگلیسی رایج به معنای «به دست آوردن و انتقال دادن» است. این کلمه از دیرباز در فرهنگ ما وجود داشته است. اجداد با کار سخت زمین را به دست آورده و آن را به فرزندان خود می سپردند، حتی طبیعت به ارث ترجیح می دهد. تمام خواص بدن مانند قد، رنگ پوست/چشم/مو و غیره. به ژن هایی که از والدین خود به ارث می بریم بستگی دارد. وراثت از اختراع مجدد چرخ جلوگیری می کند و پیشرفت را سرعت می بخشد. در OOP هم همینطور است. ما یک کلاس والد با چند ویژگی/رفتار اساسی ایجاد می کنیم. همه کلاسهایی که از این والد به ارث میبرند، دارای ویژگی/رفتار یکسانی هستند که والد خود دارند. با این حال، کلاسهای ارثی ممکن است ویژگی/رفتار بیشتری به دست آورند یا اجرای رفتار را تغییر دهند.class WritingInstrument { colour; write() { } } class Pen (child of parent) { inkcolour; }
در مثال بالا، کلاس والد (WritingInstrument) دارای ویژگی “color” و رفتار “write” است. وقتی کلاس نزول (دسته) اعلان شد، ویژگی "color" و رفتار "write" نیازی به اعلان مجدد ندارند. آنها به دلیل ارث در کلاس "دسته" حضور دارند. با این حال، یک کلاس نسل میتواند ویژگی/رفتار اضافی خود را اعلام کند. چگونه می توانیم از این در عمل استفاده کنیم؟ ما توسعه دهندگان بسیار تنبل هستیم. ما نمی خواهیم چیزی را بارها و بارها چاپ کنیم. وجود چندین نسخه از یک کد به دلیل ملاحظات زیر ممنوع است:
- هر چه کپی کد کمتر باشد، نگهداری آن آسان تر است.
- اگر تعداد زیادی کپی از کد وجود نداشته باشد، تغییر در یک مکان در همه جا قابل مشاهده است.
- هرچه کد کمتر باشد، خطاهای کمتری دارد.
- اگر یک کد در مکان های زیادی استفاده شود، تعمیم حاصل می شود.
- ما روی نوشتن کد تمرکز می کنیم.
- ما روی تست ها تمرکز می کنیم.
class WritingInstrument { } class Pen extends WritingInstrument { }
پلی مورفیسم
کلمه "چند شکلی" از دو کلمه می آید: "Poly" ، یعنی. «بسیار» / «بیش از یک» «مورف» ، یعنی. "فرم" به معنای واقعی کلمه، کلمه "چند شکلی" به توانایی اشیاء برای رفتارهای مختلف بسته به شرایط اشاره دارد. در برنامه نویسی، پلی مورفیسم را می توان در چندین مکان پیاده سازی کرد:- کلاس ها
- مواد و روش ها
- اپراتورها
Class WritingObject { wrire() { // пишем, используя стандартные (по дефолту) цвета } } class Pencil extends WritingObject { write() { // пишем, используя серый цвет, написанный текст можно стереть } } class Pen extends WritingObject { write() { // пишем, используя голубой цвет, написанный текст нельзя стереть } } class Main { main() { WritingObject wr = new WritingObject(); wr.write(); // первый вызов WritingObject wr = new Pen(); wr.write(); // второй вызов WritingObject wr2 = new Pencil(); wr2.write(); // третий вызов } }
مثال بالا یک پیادهسازی پیشفرض در WritingObject دارد که توسط کلاسهای مشتقکننده pen و pen گسترش/بیدریغ میشود. متد write() سه بار در کلاس Main فراخوانی می شود. هر بار یک پیاده سازی متفاوت بسته به اینکه کدام شیء فراخوانی شده است، فراخوانی می شود. در این مورد، متد write() به دلیل چندشکلی بودن، انواع رفتارهای زیادی دارد.
کپسوله سازی
کپسولاسیون به عنوان جمع آوری داده ها / عملکرد مرتبط در یک واحد تعریف می شود. این به تسهیل دسترسی/تغییر داده ها کمک می کند. به عنوان مثال، اگر ما نیاز داشته باشیم که تمام ویژگی هایی را که یک کاربر دارد چاپ کنیم، گزینه های زیر را داریم:printUserProperties(userName, userId, firstname, lastname, email, phone, … … ….)
متدی ایجاد کردیم که تمام ویژگی ها را گرفته و یکی پس از دیگری چاپ می کند. با افزایش تعداد عناصر در لیست، دیگر امکان شناسایی فیلدهای صحیح وجود نخواهد داشت و افزودن/حذف یک فیلد، امضای روش را تغییر می دهد. بنابراین، ما باید همه کاربران این روش را جایگزین کنیم، حتی اگر به فیلدهای اخیرا اضافه شده نیاز نداشته باشند. برای خوانایی بیشتر کد و آسانتر کردن تغییرات آتی، ویژگیها را در یک کلاس کپسوله میکنیم و آن را به یک شی جمعی تبدیل میکنیم class User { userName userId firstname lastname email phone .. .. .. } printUserProperties(user) {}
. شما می توانید اشیاء دنیای واقعی را با استفاده از اشیاء برنامه نمایش دهید. شما می توانید سگ های واقعی را در یک برنامه انیمیشن یا یک دوچرخه واقعی را به عنوان یک شی نرم افزاری در داخل یک دوچرخه ورزشی تصور کنید. در OOP، یک کلاس یک الگوی توسعه پذیر (برنامه-کد-قالب) برای ایجاد اشیا، ارائه یک حالت اولیه (متغیرها) و اجرای رفتار (توابع، روش ها) است. مخفف SOLID توسط Michael Feather برای "پنج اصل اول" که توسط رابرت سی. مارتین در اوایل دهه 2000 نامگذاری شده بود، ابداع شد. هدف از این اصول، زمانی که با هم پیادهسازی میشوند، افزایش احتمال این است که برنامهنویس سیستمی ایجاد کند که نگهداری و گسترش آن آسان باشد. اصول SOLID رهنمودهایی در توسعه برنامه هستند که برای حذف کد "فاسد" از طریق refactoring ضروری است، در نتیجه کد باید به راحتی قابل خواندن و توسعه باشد. این بخشی از استراتژی برنامه نویسی چابک و تطبیقی است.
اصل مسئولیت واحد
در OOP، اصل مسئولیت واحد بیان می کند که هر کلاس باید مسئول بخشی از عملکرد ارائه شده توسط برنامه باشد و مسئولیت باید به طور کامل توسط آن کلاس کپسوله شود. تمام عملکرد آن باید با این مسئولیت مرتبط باشد.اصل باز/بسته
در OOP، اصل باز/بسته بیان میکند که «موجودات نرمافزاری (کلاسها، ماژولها، متدها و غیره) باید برای توسعه باز باشند اما برای تغییر بسته باشند». به عبارت دیگر، موجودیت باید اجازه دهد رفتار خود بدون تغییر کد منبع گسترش یابد.اصل جایگزینی لیسکوف
جایگزینی یک اصل در OOP است. بیان میکند که اگر S در یک برنامه رایانهای، زیرنوع T باشد، پس اشیاء نوع T باید به گونهای باشند که بتوان آنها را با اشیایی از نوع S جایگزین کرد (یعنی اشیاء نوع S را میتوان با اشیایی از نوع T جایگزین کرد) بدون تغییر. هر گونه برنامه ویژگی های مورد نیاز (دقت، تکمیل کار، و غیره).اصل جداسازی رابط
اصل جداسازی رابط بیان می کند که برنامه نویس کلاینت نباید مجبور شود به روش هایی وابسته شود که از آنها استفاده نمی کند. بر اساس این اصل، لازم است که رابط های بزرگ را به رابط های کوچکتر و خاص تر تقسیم کنیم تا برنامه نویس کلاینت تنها از روش هایی که برای او جالب است بداند. هدف از اصل جداسازی رابط، جدا نگه داشتن سیستم است که بازسازی، ایجاد تغییرات و استقرار مجدد را آسانتر میکند.اصل وارونگی وابستگی
در OOP، اصل وارونگی وابستگی به معنای شکل خاصی از قطع ارتباط بین ماژول های برنامه است. با پیروی از این اصل، روابط وابستگی استاندارد ایجاد شده از ماژولهای سطح بالا که معماری برنامه (تنظیم سیاست) را به ماژولهای سطح پایین وابسته تشکیل میدهند، وارونه (معکوس) میشوند، به طوری که ماژولهای سطح بالا اصلاحشده مستقل از جزئیات پیادهسازی میشوند. ماژول های سطح پایین این اصل می گوید:- ماژول های سطح بالا نباید به ماژول های سطح پایین وابسته باشند. هر دو نوع ماژول باید به انتزاعات بستگی داشته باشند.
- انتزاع ها نباید به جزئیات پیاده سازی بستگی داشته باشند. جزئیات باید به انتزاعات بستگی داشته باشد.
اصول GRASP
الگوهای نرم افزار تخصیص مسئولیت عمومی (GRASP) دستورالعمل هایی را برای تخصیص مسئولیت به کلاس ها و اشیاء در طراحی شی گرا ارائه می دهد.کنترل کننده
الگوی Controller مسئولیت تعامل با رویدادهای سیستم را به کلاس های غیر GUI که کل سیستم یا سناریو مورد استفاده را نشان می دهند، اختصاص می دهد. کنترل کننده:- این شیئی است که مستقیماً با کاربر تعامل ندارد و مسئول دریافت و پاسخگویی به رویدادهای سیستم است.
- باید برای مقابله با تمام رویدادهای سیستمی یک (یا بسیاری از موارد مرتبط) استفاده شود.
- این اولین شی در پشت رابط کاربری گرافیکی است که عملیات سیستم را کنترل می کند.
- او مجبور نیست خودش کار را انجام دهد، وظیفه او کنترل جریان رویدادها است.
ایجاد کننده
وظیفه کلاس creator ایجاد و راه اندازی اشیاء برای استفاده بعدی است. پارامترهای اولیه سازی و همچنین اینکه چه شیئی ایجاد خواهد شد را می داند. گاهی اوقات کلاس creator به طور فعال اشیا را ایجاد می کند و آنها را در حافظه پنهان قرار می دهد و در صورت نیاز یک نمونه را ارائه می دهد.انسجام بالا
انسجام بالا یک الگوی ارزیابی است که هدف آن حفظ اشیاء در حالتی است که هدف آنها انجام یک کار واضح است، به راحتی قابل کنترل و درک باشند. کوپلینگ بالا معمولا برای پشتیبانی از کوپلینگ پایین استفاده می شود. انسجام بالا به این معنی است که مسئولیت های یک عنصر مشخص به وضوح تعریف شده است (به شدت مرتبط و بسیار متمرکز). تقسیم یک برنامه به کلاس ها و زیر سیستم ها نمونه ای از اقداماتی است که انسجام ویژگی های سیستم را افزایش می دهد. از سوی دیگر، اتصال شل وضعیتی است که در آن یک عنصر وظایف نامرتبط زیادی دارد. عناصری که با هم جفت شده اند درک، قابل استفاده مجدد، نگهداری دشوار و تغییر آن دشوار است.غیر جهت
الگوی Roundabout اتصال آزاد (و قابلیت استفاده مجدد) بین دو عنصر را با انتساب مسئولیت تعامل بین آنها به یک شیء میانی حفظ می کند. به عنوان مثال، یک کنترل کننده برای واسطه بین داده ها (مدل) و نمایشگر آن (نمایش) در الگوی Model-View-Controller (MVC) معرفی می شود.کارشناس اطلاعات
کارشناس اطلاعات (همچنین کارشناس یا اصل کارشناس) اصلی است که برای تعیین مسئولیت به چه کسی محول شود. مسئولیت ها شامل روش ها، فیلدهای محاسبه شده و غیره است. هنگام استفاده از این اصل هنگام تخصیص مسئولیت، رویکرد اصلی دنباله اقدامات زیر است: تجزیه و تحلیل مسئولیت، شناسایی اطلاعاتی که برای انجام آن لازم است و در نهایت تعیین محل قرار گرفتن این اطلاعات. استفاده از اصل Information Expert منجر به واگذاری مسئولیت به کلاسی می شود که بیشترین اطلاعات را برای اجرای آن دارد.کوپلینگ کم
اتصال شل یک الگوی ارزیابی است که نحوه تخصیص مسئولیتها را مشخص میکند: اتصال آزاد بین کلاسها، تغییر یکی باید کمترین تأثیر را بر دیگری داشته باشد، و قابلیت استفاده مجدد را به حداکثر میرساند.پلی مورفیسم
با توجه به چندشکلی، تنوع رفتار بر اساس نوع به انواعی که این تنوع برای آنها اتفاق می افتد اختصاص می یابد. این امر با استفاده از عملیات چند شکلی به دست می آید.تغییرات محافظت شده
الگوی تغییرات محافظت شده با قرار دادن کانون ناپایداری در یک رابط و استفاده از چند شکلی برای ایجاد پیاده سازی های مختلف از آن رابط، از عناصر در برابر تغییرات به عناصر دیگر (اشیاء، سیستم ها، زیر سیستم ها) محافظت می کند.ساخت خالص
ساخت و ساز خالص شامل کلاسی است که مفهومی را در حوزه مشکل نشان نمی دهد و به طور خاص برای دستیابی به اتصال شل، انسجام بالا، و بنابراین حداکثر پتانسیل استفاده مجدد طراحی شده است (راه حل ارائه شده توسط الگوی خبره اطلاعات این امر را محقق نمی کند). چنین کلاسی معمولاً در طراحی Domain-drive "Service" نامیده می شود.انتقاد
تحقیقات پوتوک و همکاران تفاوت معنی داری را بین رویکردهای OOP و رویه ای نشان نداد.مقایسه انتقادی OOP با سایر فناوریها، بهویژه فناوریهای رابطهای، به دلیل عدم وجود تعریف دقیق و پذیرفتهشده از OOP دشوار است (Christopher J. Date)
در مقایسه با سایر زبان ها (گویش های LISP، زبان های کاربردی و غیره)، زبان های OOP مزیت منحصر به فردی ندارند و پیچیدگی های غیر ضروری را تحمیل می کنند. (لارنس کروبنر)
به نظر من برنامه نویسی شی گرا از نظر فنی ضعیف است. سعی می کند جهان را از نظر رابط هایی که در یک نوع واحد متفاوت است، به بخش هایی تجزیه کند. برای مقابله با مشکلات واقعی، به جبرهای چند مرتبه ای نیاز دارید - خانواده هایی از رابط ها که در انواع مختلفی گسترش می یابند. به نظر من برنامه نویسی شی گرا از نظر فلسفی ناسالم است. بیان می کند که همه چیز یک شی است. حتی اگر این درست باشد، خیلی جالب نیست: گفتن اینکه همه چیز یک شی است، اصلاً چیزی نگفتن است. (الکساندر استپانوف)
محبوبیت OOP در بین شرکت های بزرگ به دلیل "گروه های بزرگ (و اغلب در حال تغییر) برنامه نویسان متوسط است." انضباط تحمیل شده توسط OOP مانع از انجام "زیاد بیش از حد" برنامه نویس می شود. (پل گراهام)
برنامه نویسی شی گرا اسامی را در اولویت قرار می دهد. چرا دست به چنین اقدامات افراطی میزنیم و بخشی از سخن را روی پایه میگذاریم؟ چرا یک مفهوم بر مفهوم دیگر ارجحیت دارد؟ برای OOP غیرممکن است که ناگهان افعال را برای تفکر ما کم اهمیت کند. این دیدگاه به طرز عجیبی منحرف است. (استیو یگ)ریک هیکی، خالق Clojure، سیستم های شی را به عنوان مدل های بسیار ساده شده از دنیای واقعی توصیف کرد. او بر ناتوانی OOP در مدلسازی درست زمان تاکید کرد، که وقتی چند رشتهای در برنامهها رایج میشود، مشکلات بزرگی ایجاد میکند. Eric S. Raymond، یک برنامه نویس یونیکس و مدافع نرم افزار منبع باز، از این ادعا که OOP "یک راه حل" است انتقاد کرده است و نوشته است که OOP برنامه های چند لایه را تشویق می کند، که مانع از شفافیت می شود. به عنوان یک رویکرد مخالف، ریموند یونیکس و سی را مثال زد.
GO TO FULL VERSION