דלג לתוכן הראשי
שכבת הפשטה ארכיטקטורת תוכנה בעברית

כשהבעיה במבנה, לא באלגוריתם

תבניות עיצוב בעברית — GoF, SOLID, UML ומיקרו־שירותים עם מימוש מלא

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

תרשים מחלקות

מפת הנושאים

כל נושא באתר הוא מחלקה בתרשים: המבוא הוא המחלקה המופשטת שממנה יורשות משפחות התבניות, והעקרונות והארכיטקטורה נשענים עליהן.

package תבניות GoF

package עקרונות תכנון

«solid»

עקרונות SOLID

  • מאמרים: 4
  • חדש: היפוך תלויות והזרקת תלויות

package ארכיטקטורה

«api-design»

תכנון API

  • מאמרים: 4
  • חדש: GraphQL מול REST

קטלוג התבניות

תבניות עם מימוש מלא

לכל תבנית שלושה מבטים, כמו בספר: הכוונה, המשתתפים וההשלכות — כפי שהם מופיעים במאמר עצמו.

«creational»

תבנית Factory Method

כוונה

Factory Method מגדירה ממשק ליצירת אובייקט ומשאירה למחלקות־הבת להחליט איזו מחלקה ליצור. ההגדרה המדויקת, ארבעת המשתתפים, מימוש מלא ב-Java ובפייתון, ההבדל מ"פקטורי פשוט" ומתי new ישיר עדיף.

מבנה

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

השלכות

  • היתרון המרכזי: הקוד העסקי עובד מול הממשק Product בלבד, ולכן אינו תלוי…
  • המחיר: כדי ליצור מוצר קונקרטי חדש, צריך לפעמים מחלקת־בת חדשה של ה-Creator,…

למימוש המלא

«creational»

תבנית Abstract Factory

כוונה

Abstract Factory מספקת ממשק ליצירת משפחות של אובייקטים קשורים בלי לציין את המחלקות הקונקרטיות שלהם. ההגדרה לפי ספר ה-GoF, חמשת המשתתפים, מימוש מלא ב-Java ובפייתון, ומה ההבדל האמיתי בינה לבין Factory Method.

מבנה

AbstractFactory
מצהיר על פעולת יצירה לכל מוצר מופשט
ConcreteFactory
מממש את פעולות היצירה עבור משפחה אחת
AbstractProduct
ממשק לסוג אחד של מוצר
ConcreteProduct
מימוש של מוצר בתוך משפחה מסוימת

השלכות

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

למימוש המלא

«creational»

תבנית Builder

כוונה

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

מבנה

Builder
ממשק מופשט ליצירת חלקים של המוצר
ConcreteBuilder
בונה ומרכיב את החלקים, שומר את הייצוג ומספק דרך לקבל את התוצאה
Director
בונה את המוצר דרך ממשק ה-Builder, לפי סדר קבוע
Product
האובייקט המורכב שנבנה

השלכות

  • אפשר לשנות את הייצוג הפנימי של המוצר
  • הפרדה בין קוד הבנייה לקוד הייצוג
  • שליטה עדינה בתהליך
  • המחיר

למימוש המלא

«structural»

תבנית Decorator (קשטן)

כוונה

תבנית Decorator, או קשטן, מוסיפה אחריות לאובייקט באופן דינמי ומהווה חלופה גמישה לירושה. ההגדרה לפי ספר ה-GoF, ארבעת המשתתפים, מימוש מלא ב-Java ובפייתון, איך זרמי הקלט/פלט של Java בנויים עליה, ולמה הסדר בין העטיפות קובע.

מבנה

Component
הממשק של אובייקטים שאפשר להוסיף להם אחריות
ConcreteComponent
האובייקט הבסיסי שאליו מוסיפים אחריות
Decorator
מחזיק הפניה ל-Component, מממש את אותו ממשק ומעביר אליו בקשות
ConcreteDecorator
מוסיף אחריות אחת לפני או אחרי ההעברה

השלכות

  • יותר גמישות מירושה סטטית
  • מחלקות פשוטות בראש ההיררכיה
  • הקשטן והרכיב אינם אותו אובייקט
  • הרבה אובייקטים קטנים

למימוש המלא

«structural»

תבנית Composite

כוונה

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

מבנה

Component
מצהיר על הממשק המשותף לכל האובייקטים בהרכב, ולפעמים גם על פעולות לניהול ילדים
Leaf
אובייקט בסיסי שאין לו ילדים, ומגדיר את ההתנהגות של עצמו
Composite
מחזיק ילדים, מממש את פעולות הממשק בעזרתם ומנהל את רשימת הילדים
Client
עובד עם כל אובייקט בעץ דרך ממשק ה-Component

השלכות

  • היררכיות של אובייקטים פשוטים ומורכבים
  • לקוח פשוט
  • קל להוסיף סוגי צמתים
  • המחיר: עיצוב כללי מדי

למימוש המלא

«behavioral»

תבנית Visitor

כוונה

Visitor מייצגת פעולה שמתבצעת על האלמנטים של מבנה אובייקטים, ומאפשרת להגדיר פעולה חדשה בלי לשנות את מחלקות האלמנטים. ההגדרה לפי ספר ה-GoF, איך double dispatch עובד באמת, מימוש מלא על עץ ביטויים ב-Java ובפייתון, והחלופה המודרנית של pattern matching.

מבנה

Visitor
מצהיר על פעולת visit לכל מחלקת אלמנט קונקרטית
ConcreteVisitor
מממש פעולה אחת לכל סוגי האלמנטים, ויכול לצבור מצב תוך כדי מעבר
Element
מגדיר פעולת accept שמקבלת מבקר
ConcreteElement
מממש accept בקריאה למתודת ה-visit המתאימה לו

השלכות

  • קל להוסיף פעולות
  • פעולות קשורות מרוכזות
  • קשה להוסיף סוגי אלמנטים
  • שבירה של כימוס

למימוש המלא

«object-collaboration»

תבנית Mediator

כוונה

Mediator מגדירה אובייקט שמכמס את האופן שבו קבוצת אובייקטים מתקשרת, ומונעת מהם להפנות זה לזה ישירות. ההגדרה לפי ספר ה-GoF, המשתתפים, מימוש מלא ב-Java ובפייתון על טופס שבו רכיבים תלויים זה בזה, ואיך לא להפוך את המתווך לאובייקט־אל.

מבנה

Mediator
מגדיר ממשק לתקשורת עם העמיתים
ConcreteMediator
מממש התנהגות שיתופית על ידי תיאום העמיתים, ומכיר ומחזיק אותם
Colleague
כל עמית מכיר את המתווך שלו, ומתקשר דרכו במקום עם עמיתים אחרים

השלכות

  • פחות ירושה
  • צימוד רופף בין העמיתים
  • פרוטוקולים פשוטים יותר
  • הפשטה של שיתוף הפעולה

למימוש המלא

«object-collaboration»

תבנית Chain of Responsibility

כוונה

Chain of Responsibility מנתקת את שולח הבקשה מהמקבל שלה בכך שהיא נותנת ליותר מאובייקט אחד הזדמנות לטפל בה. ההגדרה לפי ספר ה-GoF, המשתתפים, מימוש מלא ב-Java ובפייתון על שרשרת אישורי רכש, הווריאציה של צינור מסננים, ומה קורה כשאף חוליה לא מטפלת.

מבנה

Handler
מגדיר ממשק לטיפול בבקשות, ולעיתים מממש את הקישור לחוליה הבאה
ConcreteHandler
מטפל בבקשות שבאחריותו, ניגש לחוליה הבאה, ומעביר אליה את מה שאינו מטפל בו
Client
שולח את הבקשה לחוליה כלשהי בשרשרת, בדרך כלל לראשונה

השלכות

  • צימוד מופחת
  • גמישות בחלוקת האחריות
  • אין הבטחה שהבקשה תטופל

למימוש המלא

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

שכבת הפשטה עוסק בדיוק ברגע הזה: ברגע שבו מבינים שהבעיה אינה באלגוריתם אלא במבנה. האתר מסביר בעברית את תבניות העיצוב הקלאסיות של ספר ה-Gang of Four, את עקרונות SOLID, את UML ואת ההחלטות הגדולות של ארכיטקטורת מערכות. התבניות המרכזיות מוצגות עם מימוש מלא שאפשר לקמפל ולהריץ, וכל מאמר כולל גם פסקה כנה על המקרים שבהם היא לא שווה את המחיר. מי שמתחיל מאפס — מה הן תבניות עיצוב, ומתי הן סתם שכבה מיותרת.

מהבעיה אל התבנית

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

מה אתם אומרים לעצמכם התבנית שכדאי לבדוק
"אני צריך ליצור אובייקטים בלי שהקוד יכיר את המחלקות הקונקרטיות" Factory Method
"אני צריך ליצור משפחה שלמה של אובייקטים שחייבים להתאים זה לזה" Abstract Factory
"לבנאי יש תשעה פרמטרים, וחצי מהם אופציונליים" Builder
"אני רוצה להוסיף התנהגות לאובייקט בלי לייצר מחלקת־בת לכל צירוף" Decorator (קשטן)
"יש לי עץ, ואני רוצה לטפל בעלה ובענף באותה צורה" Composite
"הספרייה מצוינת, אבל הממשק שלה לא מתאים לשלי" Adapter
"אני מוסיף כל שבוע פעולה חדשה על אותו מבנה אובייקטים" Visitor
"כמה מטפלים אפשריים, ואני לא רוצה שהשולח יידע מי מהם יטפל" Chain of Responsibility
"כל רכיב בטופס מכיר את כל הרכיבים האחרים" Mediator
"כמה אובייקטים צריכים לדעת כשמשהו משתנה" Observer
"יש כמה דרכים לחשב את אותו דבר, והבחירה נעשית בזמן ריצה" Strategy
"אני צריך לבטל פעולה, לשמור אותה בתור או להריץ אותה מאוחר יותר" Command

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

SOLID: הסיבה שהתבניות עובדות

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

UML: לצייר רק את מה שצריך

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

מיקרו־שירותים: ארכיטקטורה עם חשבון

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

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

עדכונים

מאמרים אחרונים

לכל המאמרים

מיקרו־שירותים

תבנית Circuit Breaker: איך שירות אחד שנופל לא מפיל את כולם — circuit breaker design pattern במיקרו־שירותים

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

9 דק׳ קריאה

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

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

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

10 דק׳ קריאה

עקרונות SOLID

היפוך תלויות והזרקת תלויות: ההבדל החשוב בין העיקרון, הטכניקה והקונטיינר

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

9 דק׳ קריאה

תרשים אובייקטים

מי כותב כאן

רועי פרידמן : כותב

  • מאמרים = 20

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

ליאת שגיא : כותב

  • מאמרים = 20

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