יום חמישי, 1 בספטמבר 2011

תכנות מונחה עצמים


תכנות מונחה עצמים

    "אחד בשביל כולם, כולם בשביל אחד" - אלכסנדר דיומא, פר

    הקדמה
    עקרונות OOP
    מחלקה תרשימים
    רצף דיאגרמות
    OOP עבור Javascript - כיצד להשתמש ב גאדג'ט (מושגי יסוד)
    OOP עבור Javascript - כיצד להשתמש ב גאדג'ט (חומר מתקדם)
    מסקנה
    משאבים
    מחבר ביו

הקדמה

תכנות מונחה עצמים (או OOP) היא טכניקה תכנות המבקשת לפתור בעיות או ליצור יישומים המבוססים על חפצים את האינטראקציה ביניהם.תכנות מונחה עצמים, מטרתו של המתכנת, כאשר באמצעות טכניקה זו, היא לתרגם את החיים האמיתיים היבטים לתוך הקוד של התוכנית, או לפחות לשפר את היעילות ואת הקריאות של הקוד בעת התמודדות עם מושגים מופשטים.



בדרך כלל, כאשר יצירת תוכנה (או דברים אחרים) בדרך זו, האנשים שאחראים לחשוב על תוכניות כדי לשקף חפצים אשר ישמשו בקוד, ויחסי הגומלין ביניהם. אלה תוכניות צריך להיות נמשך באופן תורם כל יבינו אותם, ולכן, למרות שזה תלוי הפרויקט עצמו, רוב הפעמים שפת מידול מאוחדת (או UML) משמש.

מאמר זה יראה לכם כיצד לקבוע אובייקטים אפשרי הבעיה שאתה צריך לפתור, וכיצד לייצג אותם. נצטרך גם לראות איך ליישם את השימוש ב-Javascript אובייקט, ואיך זה יעזור בעת יצירת הגאדג'ט. אני אנסה להימנע במונחים מדעיים מאוד מגבלות על הטכניקות שהוצגו כדי לעזור לך להבין OOP ושימושיה מהיר וקל יותר.
עקרונות OOP

תכנות מונחה עצמים יהיה ברור להתמודד עם אובייקטים, אבל להגדיר אובייקטים אנחנו קודם צריכים לדעת את הסוג שבו אנו מתארים משהו שנקרא בכיתה. האובייקטים הם בעצם מופעים של מחלקה מסוימת, טפסים מוחשי כי בכיתה "קיום - להבין את זה טוב יותר, לחשוב על המצב הבא: אם אתה מראה ציור של תפוח על כמה חברים ולשאול אותם מה זה, 'רוב' התשובה הנכונה יהיה ציור של תפוח, לא תפוח:) בכיתה, מלבד שם כדי להבדיל אותה מכיתות אחרות, כולל שיטות ותכונות.

    תכונות - הם מייצגים את מה אובייקט ובדרך כלל ניתן לגשת באמצעות נקודה, ככה: anObject.someAttribute, זה חשוב לדעת כי תכונה יכול להיות מכל סוג שהוא, אפילו סוג של האובייקט המכיל אותו.
    שיטות - הם מייצגים את מה אובייקט אינו יכול להיות השיקה באופן דומה: anObject.someMethod (פרמטרים); ישנם תקנים רבים שמות את התוכן של אובייקט, אבל במקרה הזה שיטות מתייחסים שיטות פונקציות כמו גם - אתה ניתן להבדיל בינם לבין תכונות בדרך זו: תכונה בפועל יכול להיות רק ערך או מדינה, השיטה יכולה גם לעשות משהו.

כאשר הגדרת תכונות ושיטות אנחנו גם צריכים לדעת הנראות שלהם. הראות היא מושג מורכב למדי בתכנות יכול לעזור לנו להפוך את התוכנית לעבוד בצורה יעילה יותר. מפעילי החשובים ביותר הם: הציבור (נגיש מבחוץ של אובייקט) ופרטיים (בלתי נראה מבחוץ, נגיש רק עבור הפעולה הפנימי של האובייקט; בדרך כלל עוזרים או עזר על חישובים אשר צריך להיעשות אובייקט) . לא כל שפות תכנות להתמודד עם בעיות הנראות, למשל, מאפשר Javascript כל השיטות והתכונות להיות ציבורית.

כדי לייצר את המקרים אנחנו כבר מדברים, אנו משתמשים בשיטות מיוחד הנקרא בנאים, אשר נקראים בדרך כלל לאחר השיעור הם בונים. בהתאם לאופן יעיל אנחנו רוצים להיות, אנחנו יכולים גם להגדיר שיטות משלנו הורס.

/ / בניית אובייקט, מופע של מחלקה
objectInstance = ObjectClass חדש ();

/ / בנאי יכול לקבל פרמטרים
/ / כמו כן, יש בדרך כלל ניתן יותר מאחד בנאי
שכר = 1000000;
לי = חדש שכיר (שכר);

בעולם התיכנות, שם טרם הגדרה OOP משכנע שכולם יסכימו עליה, אבל מה שחשוב הוא כי עקרונות מסוימים שגובשו כדי לעזור לנו להבין ולהשתמש OOP:

    מודולריות - זה כנראה החלק המרכזי של OOP. אנחנו צריכים למצוא גופים בודדים התוכנית שלנו. בסופו של דבר, הם יכולים להיות כמעט כל דבר (אובייקטים, מחלקות, וכו '), אבל מה שחשוב הוא שיש לנו לזהות מה יכולה להתנתק משאר הפתרון, קוד אותו בנפרד. אבל למה זה עוזר? הבלוג בדיקה גוגל אומר את זה בצורה הטובה ביותר: "בדיקה rocks.Debugging מבאס". זה לא תמיד נצפתה על ידי משתמשים של המוצר הסופי, אבל זה דבר טוב מאוד לארגן את הפתרון שאתה מנסה הקוד. לא רק שזה יותר קל לחשוב על התוכנית שלך, אבל אם אתה צריך לתקן באג או ליישם עדכון תוכל למצוא את המקום הנכון הרבה יותר מהר.
    מודולריות
    איור 1: מודולריות

    אנקפסולציה - מחוברים חזק מודולריות. זה אומר שכל דבר מלבד ממשק של אובייקט צריך להיות מוסתרים ממוקם בדיוק, ולכן יישומה בפועל יכול בקלות להיות שונה, עם שיפור בביטחון את התוכנית גם כן. עם זאת, משמעות הדבר היא כי ממשק (תכונות ושיטות הציבור) צריך להיות נציג מאוד האובייקט לגרום. רוב הרעיונות הללו הם דוגמה יפה באיור 2. כולנו יודעים מה זה, וכי הוא מאחסן נתונים, אבל אנחנו לא ממש לראות את הנתונים, או איפה ואיך הוא מאוחסן. אנחנו פשוט רואים משהו שהולך ליציאת ה-USB (זה ממשק:)
    כונן USB
    איור 2: דוגמה Encapsulation

    ירושה - עוד רעיון הבסיס של OOP, וזה כנראה הסיבה OOP עובד כל כך טוב, בין השאר, הוא מאפשר לנו לקבוע דפוסים לחסוך מקום בעת כתיבת קוד, על ידי הפיכת הכיתה לרשת אחרת בכיתה. משמעות הדבר היא כי יש תת את כל השדות הציבור העל יש, אבל ניתן גם להגדיר כמה משלהם (שים לב subclass יכול להיות גם העל למשהו אחר). דוגמה יפה מוצג באיור 3, אשר גם מציג כמה סמלים UML לייצג ירושה.
    ירושה
    איור 3: ירושה

    ישנם הרבה סוגי הרכב (אנחנו יכולים לומר שהם יורשים את המעמד שנקרא רכב), אבל באיור 3 ניתן לראות שתי דוגמאות: אוטובוסים racecar. כולם יורשים שדות הציבור "העל, כמו numberOfPassangers או להפסיק (), אבל הם גם להגדיר שיטות משלהם ותכונות. לדוגמה, אוטובוס יש לוח זמנים שהגיעו תחנות racecar יש activeGrandPrix להראות לנו על מה מסלול זה מתחרים השבוע.
    פולימורפיזם - קשורה ירושה, וזה הדבר שהופך אותו גמיש, בעצם, אתה יכול לטפל מחלקה נגזרת בדיוק כמו ההורה, בהתבסס על העובדה כי המחלקה הנגזרת יש לפחות דבר יש מעמד ההורה. לדוגמה, בהתחשב במצב האמור לעיל, אם העבודה של האדם היא מכוניות בפארק כאשר הם מגיעים במלון, אדם כי יהיה כנראה להשתמש ההצתה (), ללכת (מהירות) להפסיק () שיטות, לא משנה איזה סוג של מכונית יש הגיע.

מחלקה תרשימים

כמו שאמרתי, בעת יצירת תוכנית באמצעות OOP, חלק בתכנון וארגון נעשה בדרך כלל לפני יישומו בפועל. לכן, דיאגרמה בכיתה הוא בעצם ציור המציג את מבנה התוכנית, במיוחד את היחסים בין המעמדות השתמשו בתוכנית זו. הנה כמה פרטים על סוגי משמש לעתים קרובות היחסים:

    ירושה UML סמל
    איור 4: ירושה
    צבירת UML סמל
    איור 5: צבירת
    הרכב UML סמל
    איור 6: הרכב

    ירושה - דיברנו על הירושה מוקדם יותר, כמו ששמת לב בוודאי, זה סימל עם חץ סיום במשולש ריקה והצביע לעבר מעמד ההורה (העל); ראה איור 4.
    צבירה - הדרך הטובה ביותר להבין הוא מן הדוגמאות. יש הרבה דרכים להגדיר את זה, אבל עדיף לחשוב על זה כתשובה לשאלה. אנשים רבים משתמשים זה השאלה: "האם יש לו ...". לדוגמה, בואו נסתכל על איור 7. חניון אולי כמה מכוניות בו; בכיתה ParkingLot יש מגוון כלי רכב עם פריטים סוג רכב כדי לשמור על חשבון של מכוניות חונות, ולכן אנחנו בהחלט מסתכלים צבירה. זה סימל עם חץ שהסתיימו יהלום ריק, כפי שמוצג באיור 5.
    צבירת
    איור 7: צבירת

    הרכב - הרכב דומה עם צבירה, אבל זה עונה על שאלה שונה במקצת. השאלה החביבה שלי עבור הרכב היא "האם זה עשוי ...?". שלא כמו במגרש חנייה ללא מכוניות, מכונית לא יכולים "לשרוד" בלי מנועי הגלגלים (איור 8). אם אתה רוצה להבין את ההבדל טוב יותר, אתה יכול לבדוק את המאמר הזה בוויקיפדיה. הרכב מסומל בחץ שהסתיימו יהלום מלא, ומצביע לעבר האובייקט כי הוא עשה משהו (איור 6). לדוגמה הבאה הוספנו כמה שדות מיותרים לכיתה הרכב שלנו כדי לראות מה מכונית הוא עשוי (רק למען הוויכוח: אובייקט מנוע מערך גלגל).
    הרכב
    איור 8: הרכב

    ניתן ליצור השאלות שלך כדי לעזור לך להבין את הדברים האלה יותר טוב. חשוב לדעת כי UML היא גמישה מאוד, ומאפשרת לך להפוך את דיאגרמות בכיתה שבה התוכנית שלך בפרספקטיבה וכולם מבינים. ישנם סוגים רבים אחרים של יחסים, לא כל כך קרוב לרמת כמו אלה שהוזכרו הם, אבל הם מתרחשים פעמים רבות גם כן. דוגמאות טובות הן אסוציאציה (סימל דרך קו א) תלות (סימל דרך חץ משולש וכלה מלא). אלה הם בהגדרות כלליות על יחסי, אך הדבר החשוב ביותר הוא כי התרשים בכיתה שיתקבלו יהיו בקנה אחד עם דרישות התוכנית. הנה איך דיאגרמה בכיתה הסופי שלנו יכול להיראות כך:
    מחלקה תרשים
    איור 9: תרשים מחלקה

הנה כמה טיפים:

    אם אנחנו רוצים לבדל את השדות הציבור מתחומים פרטית, אנו יכולים למקם את '+', בהתאמה "-" סמלים מול ההכרזה.
    המעמדות בתרשים מכילים גם שדות אירוע. אנחנו לא משתמשים בהם עד עכשיו, אבל הם עשויים לעזור בעת ביצוע דיאגרמות רצף, אשר מפורט בסעיף הבא.

רצף דיאגרמות

אם דיאגרמות בכיתה הם ייצוגים סטטי (מבוסס יותר על תכונות, בין אם נרצה בכך או לא:) דיאגרמות רצף להראות את האינטראקציה בין אובייקטים באופן דינמי. בעיקרון, האובייקטים ממוקמים בחלק העליון של התרשים, עם קווים אנכיים יורדים מהם. קווים אלה מהווים למעשה את הזמן, אנו יכולים לראות את רצף של אירועים, מופעלות על ידי פעולות מסוימות (שיטות). בדרך כלל, פעולות הן סימלו באמצעות החצים רציף, ואילו התגובות, אשר נדרשים לעיתים לאחר שאילתה כמו שיטות, הם סימלו באמצעות החצים מנוקד. ניתן לראות את כל זה להלן:
רצף תרשים
איור 10: תרשים רצף - כפי שניתן לראות במאמר זה ויקיפדיה

דוגמה זו מראה לנו מה קורה כאשר אנו לחץ על לחצן שלח / קבל מהלקוח דוא"ל מקוון. הפעולה הראשונה המבוצעת על ידי התוכנית היא לשלוח דואר אלקטרוני שלא נשלחו (sendUnsentEmail). ואז זה "שואל" את השרת אם יש דוא"ל חדש (newEmail), תלוי בתגובה, היא תורד; לאחר מכן, הדוא"ל הישנה נמחקת. שימו לב כי בעת ביצוע כזה תרשים רצף, שיטות על החצים צריכים להיות עם האובייקט הצבעה שלהם (למשל, שיטת sendUnsentEmail שייך האובייקט Server).

הנה כמה טיפים:

    אם זה דורש תגובה, זה כנראה פונקציה:)
    אובייקטים, אשר נמשכים כמו ריבועים גדולים על גבי, מיוצגים באמצעות האמנה: "[שם עצם]: [סוג של אובייקט / מחלקה]". אם אתה רואה ": מחשב", הוא מתייחס לאובייקט מחשב אנונימיים, זה יכול להיות כל מחשב. דוגמה מסוים יכול להיות זה: "MyDormComputer: מחשב" - "UniversityServer: שרת".
    דיאגרמות רצף יכול להיות מאוד מורכב, תלוי הקושי של הבעיה שלנו. מידע נוסף על מושגים ומוסכמות אחרות ניתן למצוא במאמר ויקיפדיה על דיאגרמות רצף.

OOP עבור Javascript - כיצד להשתמש ב גאדג'ט (מושגי יסוד)
תרשים
איור 11: מה עומד מאחורי הגרף הזה?

סעיף זה מראה לך כיצד לעקוף חלק מהבעיות הנפוצות, כיצד ליצור מעמד כמו ישויות וכיצד להשתמש בהם. לכן, כדי להגיע לנקודה, באיזו תדירות אתה כבר לשים מול הצורך לקבל 2 מערכים, עם אורך זהה בהתייחסו את אותם מרכיבים? ובכן זה היה יותר מדי בשבילי:) ו פתרון מגניב הוא משתמש פשוט ליישם OOP. לדוגמה, בגאדג'ט תרשים שלי, אני מרוכז 2 מערכים למערך אחד, המכיל אלמנטים מסוג מסוים, אשר אני מגדיר. ראשית, יצרתי מחלקה בשם דוט להחזיק את המיקום של נקודה.

פונקציה דוט (xParam, yParam) {
this.x = xParam;
Y = yParam;
}

כפי שאתה יכול לראות, x ו-y תכונות מוגדרות כאשר קוראים את בנאי בכיתה. אתה יכול לראות שיחה בפועל כאן:

פונקציה MakeArray (dataParam) {
//...
aux = data.split (';');
עבור (i = 0; i <aux.length; i + +) {
מתאם aux = [i]. לפצל (',');
נקודות [i] = new דוט (parseInt (הקואורדינטות [0], 10), parseInt (הקואורדינטות [1], 10));
}
}

אחרי שאני מקבל את הערך המדויק של קואורדינטות, אשר מופרדים בתחילה במחרוזת ידי התו פסיק, אני יוצר מערך נקודות המכיל חפצים דוט, אשר בנויים לראות. הנה קטע קוד המחשבת גדלים עמדות עבור קווי תרשים, בהתבסס על הקואורדינטות נקודת שהוקלטו בעבר.

עבור (i = 0; i <dots.length-1, i + +) {
קווים [i] chart.appendElement = ("height='2' <div background='#888888'/>");
קווים [i] = x (נקודות [i] x-minXValue.) * xUnit 2;. הקווים [i] y = גובה (נקודות [i]-y minValue.) * yUnit-2.

קווים [i]. רוחב = Math.sqrt (sqr ((נקודות [i 1].-y נקודות [i]. y) * yUnit) + sqr ((נקודות [i 1]. x-נקודות [i] . x) * xUnit));
}

הגישה היא אינטואיטיבית (נקודות [i]. X ו נקודות [i]. Y) ומונע את הצורך 2 מערכים. כדאי גם לציין כי אנקפסולציה הנובע אופטימיזציה זה פשוט יחסית הוא עוזר ענק כאשר באגים:)
OOP עבור Javascript - כיצד להשתמש ב גאדג'ט (חומר מתקדם)
ComboBox
איור 12: ComboBox שנוצרו לאחר עקרונות OOP

שולט מן גאדג'ט של Google Desktop API (<button>, <img> וכו ') מונחה עצמים - הם משקפים את כל העקרונות המפורטים בסעיפים הקודמים של המאמר. אני גם עשה את השליטה שלי, לאחר העקרונות הללו לזכור: ComboBox. אתה יכול לכלול אותו (באופן חופשי) בגאדג'ט שלכם פשוט על ידי רוכסן זה ארכיון לתוך ספריית לבנות שלך כולל את התסריט בתוכו.

ראשית, עלינו להבין מה ההתנהגות ממוקד יהיה. במקרה של ComboBox שלי, אני רוצה להיות מסוגל לבצע את הפעולות הבאות בקובץ main.js:

var = מערך חדש (3);
[0] = "element0"; [1] = "element1"; [2] = "element2";

פונקציה testClick (x) {
/ / Alert (c.getValue ());
}

/ / יצירת ComboBox
c = new ComboBox (תצוגה, 50,50,200,3 "testClick", א);

/ / קביעת ערך
c.setValue ("element1");

/ / השמדה עצמית לאחר 20 שניות
setTimeout ("c = c.destroy ();", 20,000);

בוא נראה מה את קטע הקוד הזה עושה. מערך נוצרת יש משהו לעבוד איתו. לאחר מכן, אנו מגדירים פונקציה אשר אנחנו רוצים להיות כאשר השיקה את האירוע onClick או onChange מופעלת. לאחר מכן, אנו להפעלת ComboBox לתוך המשתנה c, באמצעות בנאי אשר זה אב טיפוס: המשמעות של כל פרמטר הוא די ברור - רק לשים לב את הגמישות של האובייקט בשל פרמטר האב. לדוגמה, אם אנחנו רוצים ליצור את ComboBox ב <div>, לא ישירות <view>, אנחנו רק לכתוב את שם <div> כי כפרמטר ראשון בנאי.

יש לנו גם יש setValue () שיטה ופונקציה getValue, וכן פונקציה הורס: c.destroy (); אנחנו יכולים לקרוא לזה לתפקד כי היא מחזירה את המצביע null. אז לרוקן את התייחסות ג אנחנו יכולים בעצם לכתוב: c = c.destroy ();

אבל איך אנחנו עושים את כל זה? ובכן, בואו ניקח את זה צעד אחד בכל פעם. ראינו כיצד לדמות תכונות (באמצעות אובייקט בשם זה) מלא תפקודית בנאים (על ידי כתיבת קוד בגוף לתפקד בפועל). כדי ליצור שיטות בתוך הכיתה, אנו משתמשים קוד דומים, אנחנו רק צריכים להגדיר אותם, כמו זה:

this.setValue = setValue;

פונקציה setValue (ים) {
this.value = s;
CBedit.value = s;
}

באפשרותך לכלול פרמטרים וחפצים לחזור או ערכים בדיוק כמו שהיית אם לא היית משתמש כיתות. בעיקרון, כיסינו עכשיו כל מה שאנחנו צריכים לעשות, כדי לקבל פרספקטיבה, הנה מבט כללי על המעמד ComboBox:

ComboBox פונקציה (אב, x, y, רוחב, numberOfDisplayedItems, onClickFunction, newArray) {
/ / כמה משתנים, לא חשוב למשל שלנו
var CBbutton; var auxCBarray = מערך חדש (); var actualNumberOfElements = 0; var CBcontentDIV; var CBshape;

/ / בנאי
לבנות ();
לבנות פונקציה () {
this.value = "";
//...
/ / הוספת רכיבי ממשק משתמש, חישוב עמדות וכו '
}

/ / ציבורי
this.setValue = setValue;
פונקציה setValue (ים) {
this.value = s; CBedit.value = s;
}

/ / ציבורי
this.getValue = getValue;
getValue פונקציה () {
לחזור (CBedit.value);
}

/ / ציבורי (הורס)
this.destroy = להשמיד;
פונקציה להרוס () {
parent.removeElement (anotherReferenceToCBcontentDIV);
parent.removeElement (anotherReferencetoCBedit);
parent.removeElement (anotherReferencetoCBbutton);
parent.removeElement (AnotherReferencetoCBShape);
להחזיר null;
}

//...
}

הנה כמה עצות מועילות על OOP ב-Javascript:

    ייתכן שיהיה לב של קטעי קוד, אמר כי כמה הערות / / ציבורי. אלה קיימים כדי להקל על מפתחים אחרים כדי לדעת מה את הנראות עבור כל שדה, אבל האמת היא, כי Javascript אינו עוסק ניראות כל השדות הציבור, אנחנו יכולים להשתמש זה הוועידה: לשים תחתון מול של כל דבר שאתה רוצה להישאר פרטיים, למשל: _privateFunction.

    ישנן 2 דרכים להפיק סוג של אחר. אחת הפונקציות משתמש:

    פונקציה העל () {
    this.f = superFunction;
    }

    תת פונקציה () {
    this.inheritFrom = העל;
    this.inheritFrom ();
    this.f = subFunction;
    }

    ... אחד השימושים התכונה אב טיפוס:

    פונקציה העל () {
    this.f = superFunction;
    }

    תת פונקציה () {
    this.f = subFunction;
    }

    subClass.prototype = חדש העל;

    חסר מפעילת instanceof? למי שלא יודע, זו כלולה בשפות תכנות אחרות כדי לעזור לנו להשוות ולברר סוגי אובייקטים. אתה יכול לכתוב את זה בעצמך ב-Javascript, שוב, על בסיס אב טיפוס יעיל:

    פונקציה instanceof (אובייקט, constructorFunction) {
      ואילו (אובייקט! = null) {
        אם (== אובייקט constructorFunction.prototype)
         {ההחזר האמיתי}
    אובייקט = object.__proto__;
      }
      בתמורה שווא;
    }

    הנה איך לגלות מאפיינים של אובייקט ב-Javascript:

    פונקציה דוט (xParam, yParam) {
    this.x = xParam;
    Y = yParam;
    }

    d = חדש דוט (3,4);

    עבור (רכוש ד)
    התראה (רכוש);

מסקנה

זה כנראה מאמר ארוך, תכנות מונחה עצמים אבל שעברנו הכל OOP עקרונות בסיסיים שימושים מעשיים. למדנו את הפוטנציאל של אובייקט של אינטראקציות בין אובייקטים, עם דגימות וטריקים בסעיף כל המאמר. תכנות מונחה עצמים צריך להיות למד לנצל כל מפתח, ואנחנו לא ראיתי מדוע מפתחי הגאדג'ט צריך לעשות לא יוצא מן הכלל:)

גאדג'טים רבים, כולם!

2 תגובות:

  1. ל- javascrip יש מודל הרבה יותר גמיש מ- oop
    javascrip מבוסס על prototype.
    דבר שני עדיף לך לשנות כיוון של הטקסט בדוגמאות כדי שיהיה אפשר להבין אותם. אני רשמתי בלוג על רעיונות של שימושים מיוחדים ב- javascrip בבלוג:
    http://mryublog.blogspot.com/2010/11/using-corutine-in-javascript.html

    השבמחק