JavaRush /בלוג Java /Random-HE /תכנות מונחה עצמים (תרגום מאמר)
Exidnus
רָמָה
Санкт-Петербург

תכנות מונחה עצמים (תרגום מאמר)

פורסם בקבוצה
מהמתרגם: לצערי אין לי ניסיון משמעותי בתרגום מאנגלית, למרות שקראתי די הרבה באנגלית. אבל התברר שקריאה ותרגום הם שני דברים שונים. כמו כן, לצערי, אין לי ניסיון משמעותי בתכנות (לא מזמן הכנתי יישום אינטרנט פשוט ב-Spring MVC ו-Hibernate). לכן, התרגום יצא הרבה יותר גרוע ממה שהיה יכול להיות. לקחתי את החופש לתקן מעט את דוגמאות הקוד שניתנו במאמר, מכיוון שהן אינן תואמות את מוסכמות השמות ב-Java. אולי לא היה כדאי לתרגם שמות של כמה דפוסים (תרגום כזה לא מספק הרבה הבנה), אבל חשבתי שזה הרע במיעוטו. ראוי להזכיר בנפרד על "לכידות גבוהה" כתרגום של "לכידות גבוהה". אני מסכים, לא התרגום הטוב ביותר. אבל "קישוריות חזקה" היא "צימוד גבוה" (מושג חשוב נוסף), וסביר ש"קוהרנטיות" לא תתאים כאן. אני פתוח לביקורת ואקבל תגובות על המאמר בכל צורה שהיא. תכנות מונחה עצמים הוא סגנון תכנות שבו תוכנית מורכבת ממרכיבים התואמים לאובייקטים בעולם האמיתי. לכל אובייקט אמיתי יש כמה מאפיינים (שעשויים להשתנות או לא ישתנו עם הזמן) והתנהגות (שעשויים או לא להשתנות בהתאם לאחרים). לדוגמה, עיפרון הוא אובייקט בעולם האמיתי בעל המאפיינים הבאים:
  • הוא אדום (זה לא משתנה עם הזמן).
  • אורכו כעת 10 סנטימטרים (זה עשוי להשתנות אם העיפרון יחודד).
ויש לו את ההתנהגות הבאה:
  • זה משאיר סימן אם משתמשים בו נכון.
  • העקיבה עשויה להיות שונה בהתאם ללחץ (בהתאם לגורמים חיצוניים).
  • אורכו מתקצר ככל שהוא מתחדד (התנהגות קבועה).
כמו בדוגמה זו, לאובייקטים בעולם האמיתי יכולים להיות מאפיינים רבים, אך בעת כתיבת תוכניות אנו לוקחים בחשבון רק את המאפיינים הדרושים. לתכנות מונחה עצמים יש יתרונות. לדוגמה, זה מקל על יצירת קשר בין אובייקט בעולם האמיתי לתוכנית בצורה המצופה. זה באמת עוזר ככל שהאפליקציה גדלה ואובייקטים רבים מקיימים אינטראקציה זה עם זה. זה עוזר בחלוקת אחריות בתוך העולם האובייקטיבי, ומאפשר לך להתמקד בחשיבה דרך היישום. תכונה חשובה נוספת הקשורה ל- OOP (תכנות מונחה עצמים) היא סיווג אובייקטים. מכיוון שהעולם (אמיתי/וירטואלי) מלא באובייקטים, קשה לשלוט בהם בנפרד. אנחנו צריכים דרך לסווג את האובייקטים האלה שתעזור לנו לשייך אובייקטים שונים ותכונותיהם, כמו עיפרון שחור. זה יהיה בלתי ניתן להבחין (אותו?) אם נעשה בו שימוש בדוגמה הקודמת, אבל זה אובייקט אחר. אבל מכיוון ששניהם עפרונות, הם שייכים לאותה מעמד "עיפרון". ואילו עט, שדומה מאוד לעיפרון, שייך למעמד אחר. עם זאת, עט ועיפרון הם שניהם "מכשירי כתיבה". לתכנות מונחה עצמים יש את העקרונות הבאים:
הַפשָׁטָה
הפשטה מוגדרת כאיכות של אינטראקציה עם רעיונות ולא עם אירועים או, במילים אחרות, חופש מאיכויות ייצוג . זה מאפשר למתכנתים להתמקד במה לתכנת ולא כיצד לתכנת . ניתן להתייחס להפשטה כעל חוזה שבאמצעותו אנו מספקים פונקציונליות. פרטי יישום עשויים להיות מוסתרים בעת שימוש במושג זה. למשל אם אנחנו צריכים מחלקה שכותבת אז אנחנו חייבים להיות בטוחים שיש לה שיטת "כתיבה" abstract class writer { write (); } מה עשינו? תכננו מחלקה ברמה גבוהה שהיא מופשטת, במילים אחרות, היא יודעת איזו פונקציונליות אנחנו צריכים, אבל איך ליישם אותה היא מחוץ לתחום המחלקה הזו. זה מציע יתרונות רבים:
  • אנו חושפים את המידע המינימלי הדרוש לגופים חיצוניים, זה מאפשר לנו להתמקד בחשיבה דרך התוכנית (זה מאפשר חשיבה ממוקדת), להימנע מבלבול ולהימנע מהבטחות לא מכוונות.
  • אנו משאירים מקום לשיפורים עתידיים שלא היו אפשריים אילו נחשפו פרטי היישום.
יְרוּשָׁה
"ירושה" באנגלית רגילה פירושו "לרכוש ולהעביר הלאה". המילה הזו קיימת בתרבות שלנו הרבה מאוד זמן. אבות רכשו אדמה בעבודה קשה והעבירו אותה לילדיהם, אפילו הטבע מעדיף ירושה. כל תכונות הגוף, כגון גובה, צבע עור/עיניים/שיער וכו'. תלויים בגנים שאנו יורשים מהורינו. הורשה מונעת המצאת הגלגל מחדש ומזרזת את ההתקדמות. זה אותו דבר ב-OOP. אנו יוצרים כיתת הורים עם כמה מאפיינים/התנהגויות בסיסיות. כל המחלקות שיורשו מהורה זה יכילו את אותם מאפיינים/התנהגות כמו ההורה שלהם. עם זאת, מחלקות בירושה עשויות לקבל יותר מאפיינים/התנהגות או לשנות את יישום ההתנהגות. class WritingInstrument { colour; write() { } } class Pen (child of parent) { inkcolour; } בדוגמה למעלה, למחלקת האב (WritingInstrument) יש תכונה "צבע" והתנהגות "כתיבה". כאשר מכריזים על המחלקה הצאצאית (handle), אין צורך להכריז שוב על המאפיין "color" והתנהגות "write". הם נוכחים במעמד "ידית" עקב ירושה. עם זאת, מעמד צאצא יכול להכריז על מאפיינים/התנהגות נוספים משלה. איך נוכל להשתמש בזה בפועל? אנחנו המפתחים מאוד עצלנים. אנחנו לא רוצים להדפיס משהו שוב ושוב. קיומם של עותקים מרובים של אותו קוד אינו מעודד בשל השיקולים הבאים:
  • ככל שפחות עותקים של קוד, כך קל יותר לתחזק אותו.
  • אם אין הרבה עותקים של הקוד, אז שינוי במקום אחד הופך גלוי בכל מקום.
  • ככל שפחות קוד, פחות שגיאות.
  • אם נעשה שימוש בקוד אחד במקומות רבים, אזי מושגת הכללה.
  • אנו מתמקדים בכתיבת קוד.
  • אנו מתמקדים במבחנים.
הירושה ב-Java מושגת באמצעות מילות המפתח "מאריך" ו"מיישם". class WritingInstrument { } class Pen extends WritingInstrument { }
רב צורתיות
המילה "פולימורפיזם" מגיעה משתי מילים: "פולי" , כלומר. "רבים" / "יותר מאחד" "מורף" , כלומר. "צורה" מילולית, המילה "פולימורפיזם" מתייחסת ליכולת של עצמים להתנהג בדרכים שונות בהתאם לתנאים. בתכנות, ניתן ליישם פולימורפיזם במספר מקומות:
  • שיעורים
  • שיטות
  • מפעילים
כל האמור לעיל עשוי להתנהג בצורה שונה בהתאם לתנאים, אולי ההקשר, שבו הם משמשים. זה שימושי מכיוון שהלקוח (המתכנת המשתמש בספריות שלך) לא צריך לדעת הרבה דקויות, והפונקציונליות הרצויה מיושמת על ידי בחירת המידע הדרוש מההקשר. 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, אשר מורחב/מוחלף על ידי עט ועט בכיתות הצאצאים. למתודה write() קוראים שלוש פעמים במחלקה Main. בכל פעם נקרא מימוש אחר בהתאם לאיזה אובייקט נקראת השיטה. במקרה זה, לשיטת write() יש סוגים רבים של התנהגות מכיוון שהיא פולימורפית.
כימוס
Encapsulation מוגדר כאיסוף נתונים/פונקציונליות קשורים ביחידה אחת. זה עוזר להקל על גישה/שינוי לנתונים. לדוגמה, אם אנחנו צריכים להדפיס את כל המאפיינים שיש למשתמש נתון, יש לנו את האפשרויות הבאות: printUserProperties(userName, userId, firstname, lastname, email, phone, … … ….) יצרנו שיטה שלוקחת את כל המאפיינים ומדפיסה אותם בזה אחר זה. ככל שמספר האלמנטים ברשימה יגדל, לא ניתן יהיה לזהות עוד שדות נכונים, והוספה/הסרה של שדה אחד תשנה את חתימת השיטה. לכן, עלינו להחליף את כל המשתמשים בשיטה זו, גם אם הם לא צריכים את השדות החדשים שנוספו. כדי להפוך את הקוד לקריאה יותר ולהקל על שינויים עתידיים, אנו עוטפים מאפיינים במחלקה והופכים אותה לאובייקט קולקטיבי.אובייקט class User { userName userId firstname lastname email phone .. .. .. } printUserProperties(user) {} הוא חבילת תוכנה של משתנים ושיטות משויכות. אתה יכול לייצג אובייקטים בעולם האמיתי באמצעות אובייקטי תוכנית. אתה יכול לדמיין כלבים אמיתיים בתוכנית אנימציה, או אופניים אמיתיים כאובייקט תוכנה בתוך אופני כושר. ב-OOP, מחלקה היא תבנית הניתנת להרחבה (תוכנית-קוד-תבנית) ליצירת אובייקטים, מתן מצב ראשוני (משתנים) והטמעת התנהגות (פונקציות, שיטות). ראשי התיבות SOLID נטבע על ידי מייקל פיטר עבור "חמשת העקרונות הראשונים" שנקראו על ידי רוברט סי מרטין בתחילת שנות ה-2000. מטרת העקרונות, כשהם מיושמים יחד, היא להגדיל את הסבירות שהמתכנת יצור מערכת שקל לתחזק ולהרחיב. עקרונות SOLID הם קווים מנחים בפיתוח תוכניות הנחוצים להסרת קוד "רקוב" באמצעות עיבוד מחדש, וכתוצאה מכך הקוד אמור להיות קל לקריאה וניתן להרחבה. זה חלק מאסטרטגיית התכנות הזריזה והסתגלנית.
עיקרון אחריות יחידה
ב-OOP, עקרון האחריות היחידה קובע שכל מחלקה צריכה להיות אחראית לחלק אחד מהפונקציונליות שמספקת התוכנית, והאחריות הזו צריכה להיות מוקפת לחלוטין על ידי אותה מחלקה. כל הפונקציונליות שלו צריכה להיות קשורה קשר הדוק לאחריות זו.
עקרון פתוח/סגור
ב-OOP, העיקרון הפתוח/סגור קובע כי "ישויות תוכנה (מחלקות, מודולים, שיטות וכו') צריכות להיות פתוחות להרחבה אך סגורות לשינוי." במילים אחרות, הישות חייבת לאפשר להרחיב את התנהגותה מבלי לשנות את קוד המקור.
עקרון ההחלפה של ליסקוב
תחליפיות היא עיקרון ב-OOP. הוא קובע שאם S בתוכנת מחשב הוא תת-סוג של T, אז אובייקטים מסוג T חייבים להיות כאלה שניתן להחליפם באובייקטים מסוג S (כלומר אובייקטים מסוג S יכולים להיות מוחלפים באובייקטים מסוג T) מבלי לשנותם. כל תוכניות המאפיינים הנדרשות (דיוק, השלמת משימה וכו').
עקרון הפרדת ממשק
עקרון הפרדת הממשק קובע שאין לכפות על מתכנת הלקוח להיות תלוי בשיטות שהוא אינו משתמש בהן. לפי עיקרון זה יש צורך לחלק ממשקים גדולים לקטנים וספציפיים יותר כדי שמתכנת הלקוח ידע רק על השיטות המעניינות אותו. מטרת עקרון ניתוק הממשק היא להשאיר את המערכת מנותקת, מה שיקל על הפירוק מחדש, ביצוע השינויים והפריסה מחדש.
עקרון היפוך תלות
ב-OOP, עקרון היפוך תלות פירושו צורה ספציפית של ניתוק בין מודולי התוכנית. על ידי ביצוע עיקרון זה, יחסי התלות הסטנדרטיים שנוצרו ממודולים ברמה גבוהה היוצרים את ארכיטקטורת האפליקציה (קביעת מדיניות) למודולים תלויים ברמה נמוכה הופכים (הפוכים), כך שהמודולים ברמה גבוהה שהשתנו הופכים לבלתי תלויים בפרטי היישום של מודולים ברמה נמוכה. עקרון זה קובע:
  • מודולים ברמה גבוהה לא צריכים להיות תלויים במודולים ברמה נמוכה. שני סוגי המודולים חייבים להיות תלויים בהפשטות.
  • הפשטות לא אמורות להיות תלויות בפרטי יישום. הפרטים חייבים להיות תלויים בהפשטות.
העיקרון הופך את הדרך שבה אנשים יכולים לחשוב על עיצוב מונחה עצמים על ידי קביעה שאובייקטים ברמה גבוהה ונמוכה צריכים להיות תלויים באותן הפשטות.

עקרונות GRASP

תבניות התוכנה להקצאת אחריות כללית (GRASP) מספקות הנחיות להקצאת אחריות למחלקות ולאובייקטים בעיצוב מונחה עצמים.
בקר
דפוס הבקר מקצה אחריות לאינטראקציה עם אירועי מערכת למחלקות שאינן GUI המייצגות את כל המערכת או תרחיש מקרה שימוש. בקר:
  • זהו אובייקט שאינו מקיים אינטראקציה ישירה עם המשתמש והוא אחראי על קליטה ותגובה לאירועי מערכת.
  • יש להשתמש בו כדי להתמודד עם כל אירועי המערכת של מקרה שימוש אחד (או רבים הקשורים זה לזה).
  • זהו האובייקט הראשון מאחורי ה-GUI השולט בפעולות המערכת.
  • הוא לא צריך לעשות את העבודה בעצמו; המשימה שלו היא לשלוט בזרימת האירועים.
בורא
המשימה של מחלקת היוצר היא ליצור וליזום אובייקטים לשימוש מאוחר יותר. הוא יודע את פרמטרי האתחול, כמו גם איזה אובייקט ייווצר. לפעמים מחלקת היוצר יוצרת באופן אקטיבי אובייקטים וממקמת אותם במטמון, ומספקת מופע אחד כאשר יש צורך בכך.
לכידות גבוהה
לכידות גבוהה היא דפוס הערכה, שמטרתו לשמר אובייקטים במצב כזה שהם מכוונים לביצוע משימה אחת ברורה, ניתנים לשליטה והבנה בקלות. High Coupling משמש בדרך כלל לתמיכה ב- Low Coupling. קוהרנטיות גבוהה פירושה שהאחריות של אלמנט נתון מוגדרות בצורה ברורה (קשורה מאוד וממוקדת מאוד). חלוקת תוכנית למחלקות ותתי-מערכות היא דוגמה לפעולות המגבירות את הלכידות של מאפייני המערכת. צימוד רופף, לעומת זאת, הוא מצב שבו לאלמנט יש יותר מדי משימות לא קשורות. אלמנטים המצורפים בצורה רופפת נוטים להיות קשים להבנה, לשימוש חוזר, קשים לתחזוקה וקשים לשינוי.
עקיפה
תבנית ה-Roundabout שומרת על צימוד רופף (ואפשרות לשימוש חוזר) בין שני אלמנטים על ידי הקצאת אחריות על האינטראקציה ביניהם לאובייקט ביניים. דוגמה לכך היא הכנסת בקר לתווך בין הנתונים (מודל) לתצוגה (תצוגה) שלו בתבנית Model-View-Controller (MVC).
מומחה מידע
מומחה מידע (גם מומחה או עקרון מומחה) הוא עיקרון המשמש כדי לקבוע למי להאציל אחריות. האחריות כוללת שיטות, שדות מחושבים וכו'. כאשר משתמשים בעקרון זה בעת חלוקת אחריות, הגישה העיקרית היא רצף הפעולות הבא: ניתוח האחריות, זיהוי המידע הדרוש למילויה ולבסוף קביעה היכן מידע זה נמצא. שימוש בעקרון מומחה המידע מביא להקצאת אחריות לכיתה שיש לה הכי הרבה מידע לבצע אותה.
צימוד נמוך
צימוד רופף הוא דפוס הערכה המפרט כיצד להקצות אחריות: צימוד רופף בין מחלקות, שינוי אחד צריך להיות בעל השפעה מינימלית על השני, מיקסום השימוש החוזר.
רב צורתיות
לפי פולימורפיזם, וריאציה של התנהגות המבוססת על סוג מוקצית לסוגים שעבורם וריאציה זו מתרחשת. זה מושג על ידי שימוש בפעולות פולימורפיות.
וריאציות מוגנות
דפוס השינויים המוגנים מגן על אלמנטים מפני שינויים באלמנטים אחרים (אובייקטים, מערכות, תת-מערכות) על ידי עטיפת מוקד חוסר היציבות בממשק ושימוש בפולימורפיזם ליצירת יישומים שונים של ממשק זה.
ייצור טהור
בנייה טהורה כוללת מחלקה שאינה מייצגת קונספט בתחום הבעיה ותוכננה במיוחד כדי להשיג צימוד רופף, צימוד גבוה, ולכן פוטנציאל שימוש חוזר מרבי (הפתרון שמציע דפוס Information Expert אינו משיג זאת). מחלקה כזו נקראת בדרך כלל "שירות" בעיצוב מונחה דומיין.

ביקורת

מחקר של Potok וחב' לא הראה הבדלים משמעותיים בין OOP לגישות פרוצדורליות.
השוואה קריטית של OOP עם טכנולוגיות אחרות, במיוחד טכנולוגיות יחסיות, קשה בגלל היעדר הגדרה של OOP שהיא קפדנית ומקובלת (Christopher J. Date)
בהשוואה לשפות אחרות (דיאלקטים LISP, שפות פונקציונליות וכו'), לשפות OOP אין יתרון ייחודי ומטילות מורכבות מיותרת. (לורנס קרובנר)
אני מוצא תכנות מונחה עצמים דקיק מבחינה טכנית. הוא מנסה לפרק את העולם לחלקים במונחים של ממשקים המשתנים בתוך סוג אחד. כדי להתמודד עם בעיות אמיתיות, אתה צריך אלגברות מגוונות - משפחות של ממשקים המשתרעות על פני סוגים רבים. אני מוצא תכנות מונחה עצמים לא בריא מבחינה פילוסופית. הוא קובע שהכל הוא חפץ. גם אם זה נכון, זה לא מאוד מעניין: להגיד שהכל הוא אובייקט זה לא להגיד כלום. (אלכסנדר סטפנוב)
הפופולריות של OOP בקרב חברות גדולות נובעת מ"קבוצות גדולות (ובתדירות משתנות) של מתכנתים בינוניים". המשמעת שנכפתה על ידי OOP מונעת מהמתכנת לעשות "יותר מדי נזק". (פול גרהם)
תכנות מונחה עצמים שם את שמות העצם בראש ובראשונה. למה ללכת לאמצעים כל כך קיצוניים ולשים חלק אחד של דיבור על הדום? מדוע מושג אחד מקבל עדיפות על פני אחר? זה בלתי אפשרי עבור OOP פתאום להפוך פעלים פחות חשובים לחשיבה שלנו. זו פרספקטיבה מוטה בצורה מוזרה. (סטיב יג)
ריק היקי, היוצר של Clojure, תיאר מערכות אובייקטים כמודלים פשוטים ביותר של העולם האמיתי. הוא הדגיש את חוסר היכולת של OOP לדגמן נכון את הזמן, מה שיוצר בעיות עצומות כאשר ריבוי השרשורים הופך נפוץ בתוכניות. אריק ס. ריימונד, מתכנת יוניקס ותומך תוכנת קוד פתוח, מתח ביקורת על הטענה ש-OOP הוא "הפתרון היחיד" וכתב ש-OOP מעודד תוכניות רב-שכבתיות, מה שמפריע לשקיפות. כגישה הפוכה, ריימונד נתן את הדוגמה של Unix ו-C.

קישורים

מאת Margaret Rouse @ WhatIs.com ויקיפדיה! ( גרסה רוסית ) הירושה היא פולימורפיזם מוצק (עיצוב מכוון אובייקט) ( גרסה רוסית ) עיקרון אחריות יחידהטענות נגד OOPS ( גרסה רוסית ) מה זה OOPS (ללא ההייפ) תרגום: Varygin D.V.
הערות
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION