פייתון מונחה עצמים 5: קומפוזיציה

מחבר:
בתאריך:

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

במדריך זה נדגים את עקרון הקומפוזיציה בפייתון באמצעות שלוש דוגמאות:

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

exception handling tutorial python

 

1. כדי לבטא יחס של שייכות

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

נאמר שיש לנו שתי מחלקות: Car שמייצגת מכוניות ו-Person המייצגת אנשים, ואנחנו מעוניינים לשייך מכונית מסוימת לאדם מסויים. נכתוב את המחלקות:

class Car():
    def __init__(self, model):
        self.model = model

class Person():
    def __init__(self, name):
        self.name = name

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

class Car():
    def __init__(self, model, person=None):
        self.model = model
        self.person = person

ועכשיו בכל פעם שניצור אובייקט מהמחלקה Car נוכל להעביר לו אובייקט של המחלקה Person

אנחנו יכולים לבטא את העובדה שמשה הוא הבעלים הוא של מכונית מסוג KIA על ידי שנעביר את האובייקט moshe לאובייקט kia:

moshe = Person("Moshe")
kia = Car("kia sorento", moshe)

עכשיו, אנחנו יכולים לשאול שאלות כדוגמת: "למי שייכת המכונית?"

print(kia.person.name)
Moshe

 

2. כיצד לתת לאובייקט תכונות ומתודות של אובייקטים אחרים

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

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

נתחיל מקלאס המנוע, Engine:

class Engine():
    def operate(self):
        return 'roar...'

נאפשר למחלקה Car לקבל את אובייקט המנוע בתור תכונה:

class Car():
    def __init__(self, model, engine):
        self.model = model
        self.engine = engine

נעביר את הפרמטר של אובייקט המנוע בתור תכונה לאובייקט המכונית:

engine = Engine()
kia = Car("kia sorento", engine)

נורה למכונית להפעיל את המנוע:

print(kia.engine.operate())
roar...

היופי בקומפוזיציה הוא שניתן לשנות את הרכיבים במאמץ קטן.

לדוגמה, אם אנחנו רוצים לשנות את המנוע לסוג מתקדם יותר, HyperloopEngine:

class HyperloopEngine():
    def operate(self):
        return 'Woosh'

ניצור אובייקט מהמחלקה Car ונעביר לו את המנוע החדש במקום את הישן:

engine = HyperloopEngine()
kia = Car("kia sorento", engine)

נורה למכונית להפעיל את המנוע:

print(kia.engine.operate())
Woosh
  • למרות ששינינו את סוג המנוע אנחנו יכולים להפעיל אותו בלי לשנות דבר במכונית עצמה הודות לקומפוזיציה.

 

3. קומפוזיציה עם רשימות אובייקטים מאותו סוג

ראינו כבר שניתן להעביר לאובייקט תכונה שהיא אובייקט אחד. אבל מה לגבי רשימה של אובייקטים?

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

נגדיר למחלקה Car משתנה persons שיכיל את רשימת הבעלים:

class Car():
    def __init__(self, model, persons=None):
        self.model = model
        if persons is None:
            self.persons = []
        else:
            self.persons = persons

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

נוסיף למחלקה Car מתודות להוספה, הסרה והדפסה של רשימת הבעלים:

class Car():
    def __init__(self, model, persons=None):
        self.model = model
        if persons is None:
            self.persons = []
        else:
            self.persons = persons

    def add_person(self, person):
        if person not in self.persons:
            self.persons.append(person)

    def remove_person(self, person):
        if person in self.persons:
            self.persons.remove(person)

    def print_persons(self):
        for person in self.persons:
            print('--> %s' % person.name)

ניצור אובייקטים עבור המכונית ושני בעליה, משה ויעל:

moshe = Person("Moshe")
yael = Person("Yael")
kia = Car("kia sorento")

נוסיף את משה לרשימת הבעלים ונראה את ההשפעה על הרשימה:

kia.add_person(moshe)
kia.print_persons()
--> Moshe

נוסיף את יעל לרשימת הבעלים:

kia.add_person(yael)
kia.print_persons()
--> Moshe
--> Yael

נסיר את משה:

kia.remove_person(moshe)
kia.print_persons()
--> Yael

 

לסיכום

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

לכל המדריכים בסדרה ללימוד פייתון

 

אהבתם? לא אהבתם? דרגו!

0 הצבעות, ממוצע 0 מתוך 5 כוכבים

 

 

הוסף תגובה חדשה

 

= 8 + 2