תבנית Factory
חלק מהיחידה תכנות מונחה עצמים במסלול ה-C של Coddy. שיעור 55 מתוך 61.
דפוס Factory מרכז יצירת אובייקטים בפונקציה אחת. במקום לפזר את malloc ואת קוד האתחול ברחבי התוכנית שלך, קוראים לפונקציה אחת שמחליטה מה ליצור ומחזירה אובייקט מוכן לשימוש.
התבנית הזאת חזקה במיוחד בשילוב עם פולימורפיזם. מפעל יכול להחזיר טיפוסים קונקרטיים שונים דרך מצביע בסיס משותף, ולהסתיר מהקורא את פרטי היצירה. הקורא רק מבקש "צורה", והמפעל מחליט אם ליצור עיגול, מלבן או משהו אחר.
הנה מימוש טיפוסי של מפעל:
typedef enum {
SHAPE_CIRCLE,
SHAPE_RECTANGLE
} ShapeType;
Shape* create_shape(ShapeType type) {
switch (type) {
case SHAPE_CIRCLE:
return (Shape*)create_circle(5.0);
case SHAPE_RECTANGLE:
return (Shape*)create_rectangle(4.0, 3.0);
default:
return NULL;
}
}המפעל מקבל מזהה (בדרך כלל enum) ומשתמש במשפט switch כדי לקבוע לאיזה בנאי לקרוא. הוא מחזיר Shape* ללא קשר לסוג שנוצר בפועל. הקוד הקורא לא צריך לדעת על Circle או על Rectangle. הוא פשוט עובד עם טיפוס הבסיס:
Shape* s = create_shape(SHAPE_CIRCLE);
s->draw(s); // קריאה פולימורפית
free_shape(s);התבנית הזו מקלה על הוספת סוגים חדשים: פשוט מוסיפים ערך חדש ל־enum ומקרה חדש במפעל. שאר הקוד נשאר ללא שינוי.
אתגר
קלבואו נבנה מפעל לחיות מחמד: מערכת שיוצרת סוגים שונים של חיות מחמד באמצעות פונקציית מפעל יחידה. במקום לפזר את לוגיקת היצירה לאורך הקוד, תרכזו אותה במקום אחד שמחליט איזה סוג של חיית מחמד ליצור על סמך מזהה קלט.
תארגנו את הקוד שלכם בשלושה קבצים:
pet.h: הגדירו טיפוס enum בשםPetTypeעם הערכיםPET_DOG,PET_CATו-PET_BIRD. צרו מבנה בסיס בשםPetשמכיל מצביע לפונקציה בשםspeak(שמקבלתconst Pet*ואינה מחזירה ערך). הצהירו על פונקציית המפעלcreate_petשמקבלתPetTypeומחזירהPet*, וכן על פונקציה בשםfree_petלניקוי.pet.c: הגדירו שלושה מבני חיות מחמד קונקרטיים,Dog,Catו-Bird, שכל אחד מהם משלב אתPetכחבר הראשון שלו. ממשו פונקציית דיבור לכל סוג:- כלבים מדפיסים:
Woof! - חתולים מדפיסים:
Meow! - ציפורים מדפיסות:
Tweet!
create_pet: השתמשו במשפט switch עלPetTypeכדי לקרוא לבנאי המתאים ולהחזיר את התוצאה בתורPet*. עבור טיפוסים לא תקינים, החזירוNULL. ממשו אתfree_petכדי לשחרר את הזיכרון שהוקצה.- כלבים מדפיסים:
main.c: קראו מספר שלם שמייצג את סוג חיית המחמד (0 לכלב, 1 לחתול, 2 לציפור). השתמשו במפעל כדי ליצור את חיית המחמד המתאימה, קראו לפונקצייתspeakשלה באופן פולימורפי באמצעות המצביע מסוגPet*של מבנה הבסיס, ואז שחררו את חיית המחמד.
התוכנית שלכם תקבל קלט אחד: מספר שלם המציין איזו חיית מחמד ליצור.
דוגמה לפלט כאשר הקלט הוא 0:
Woof!דוגמה לפלט כאשר הקלט הוא 1:
Meow!דוגמה לפלט כאשר הקלט הוא 2:
Tweet!היתרון של תבנית המפעל הוא ש-main.c לא צריך להכיר את המבנים Dog, Cat או Bird. הוא עובד רק עם טיפוס הבסיס Pet. הוספת סוג חדש של חיית מחמד בהמשך פירושה הוספת ערך enum חדש ומקרה חדש במפעל, בלי לשנות קוד שמשתמש בחיות מחמד.
נסו בעצמכם
#include <stdio.h>
#include "pet.h"
int main(void) {
int type;
scanf("%d", &type);
// TODO: השתמשו בפונקציית היצירה כדי ליצור את חיית המחמד המתאימה
// רמז: בצעו המרת טיפוס מ-int ל-PetType
// TODO: קראו לפונקציה speak באופן פולימורפי דרך המצביע Pet*
// TODO: שחררו את הזיכרון של חיית המחמד
return 0;
}
השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה תכנות מונחה עצמים
4כימוס
המושג של מצביעים אטומיםהגדרת מבנים אטומיםפונקציות Get ו-Setאימות ב-Settersסיכום: הקופסה הסודית2אובייקטים ומתודות
מבנים כאובייקטיםמצביע 'Self'נכונות constמצביע לעומת ערךמתודות עזרחזרה: מנהל נקודות5פרויקט: חשבון בנק פשוט
הגדרת הפרויקטמימוש החשבוןתרגלו בעצמכם: קומפיילר C אונליין