פייתון מונחה עצמים 5: קומפוזיציה
אחרי שבמדריכים קודמים בסדרת הפייתון למדנו את היסודות של תכנות מונחה עצמים ובפרט הורשה ופולימורפיזם, במדריך זה נכיר את עקרון הקומפוזיציה שאומר שאם רוצים לתת לאובייקט את התכונות של אובייקטים אחרים אז עדיף להשתמש בהכלה במקום בהורשה.
במדריך זה נדגים את עקרון הקומפוזיציה בפייתון באמצעות שלוש דוגמאות:
- כדי לבטא יחס של שייכות
- כדי לתת לאובייקט תכונות ומתודות של אובייקטים אחרים
- קומפוזיציה עם רשימות אובייקטים מאותו סוג
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 כוכבים
המדריכים באתר עוסקים בנושאי תכנות ופיתוח אישי. הקוד שמוצג משמש להדגמה ולצרכי לימוד. התוכן והקוד המוצגים באתר נבדקו בקפידה ונמצאו תקינים. אבל ייתכן ששימוש במערכות שונות, דוגמת דפדפן או מערכת הפעלה שונה ולאור השינויים הטכנולוגיים התכופים בעולם שבו אנו חיים יגרום לתוצאות שונות מהמצופה. בכל מקרה, אין בעל האתר נושא באחריות לכל שיבוש או שימוש לא אחראי בתכנים הלימודיים באתר.
למרות האמור לעיל, ומתוך רצון טוב, אם נתקלת בקשיים ביישום הקוד באתר מפאת מה שנראה לך כשגיאה או כחוסר עקביות נא להשאיר תגובה עם פירוט הבעיה באזור התגובות בתחתית המדריכים. זה יכול לעזור למשתמשים אחרים שנתקלו באותה בעיה ואם אני רואה שהבעיה עקרונית אני עשוי לערוך התאמה במדריך או להסיר אותו כדי להימנע מהטעיית הציבור.
שימו לב! הסקריפטים במדריכים מיועדים למטרות לימוד בלבד. כשאתם עובדים על הפרויקטים שלכם אתם צריכים להשתמש בספריות וסביבות פיתוח מוכחות, מהירות ובטוחות.
המשתמש באתר צריך להיות מודע לכך שאם וכאשר הוא מפתח קוד בשביל פרויקט הוא חייב לשים לב ולהשתמש בסביבת הפיתוח המתאימה ביותר, הבטוחה ביותר, היעילה ביותר וכמובן שהוא צריך לבדוק את הקוד בהיבטים של יעילות ואבטחה. מי אמר שלהיות מפתח זו עבודה קלה ?
השימוש שלך באתר מהווה ראייה להסכמתך עם הכללים והתקנות שנוסחו בהסכם תנאי השימוש.