Menu
Coddy logo textTech

תבנית העיצובן

חלק מהיחידה תכנות מונחה עצמים במסלול ה-Dart של Coddy. שיעור 96 מתוך 110.

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

הרעיון המרכזי הוא שגם האובייקט המקורי וגם העוטפים מממשים את אותו ממשק.

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

abstract class Coffee {
  String getDescription();
  double getCost();
}

class SimpleCoffee implements Coffee {
  @override
  String getDescription() => 'Simple Coffee';

  @override
  double getCost() => 2.0;
}

class MilkDecorator implements Coffee {
  final Coffee _coffee;
  MilkDecorator(this._coffee);

  @override
  String getDescription() => '${_coffee.getDescription()}, Milk';

  @override
  double getCost() => _coffee.getCost() + 0.5;
}

class SugarDecorator implements Coffee {
  final Coffee _coffee;
  SugarDecorator(this._coffee);

  @override
  String getDescription() => '${_coffee.getDescription()}, Sugar';

  @override
  double getCost() => _coffee.getCost() + 0.2;
}

void main() {
  Coffee coffee = SimpleCoffee();
  coffee = MilkDecorator(coffee);
  coffee = SugarDecorator(coffee);

  print(coffee.getDescription());  // Simple Coffee, Milk, Sugar
  print(coffee.getCost());         // 2.7
}

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

challenge icon

אתגר

קל

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

תארגנו את הקוד בשני קבצים:

  • pizza.dart: הקובץ הזה מכיל את ממשק הפיצה שלכם ואת כל מחלקות הדקורטור. התחילו במחלקה מופשטת Pizza שמגדירה שתי מתודות: String getDescription() ו-double getPrice(). לאחר מכן צרו מחלקה PlainPizza שמממשת את Pizza — היא מחזירה את Plain Pizza כתיאור שלה ועולה 8.0. כעת בנו שלוש מחלקות דקורטור, שכל אחת מהן עוטפת Pizza ומשדרגת אותה:
    • CheeseDecorator — מוסיפה , Cheese לתיאור ו-1.5 למחיר
    • PepperoniDecorator — מוסיפה , Pepperoni לתיאור ו-2.0 למחיר
    • MushroomDecorator — מוסיפה , Mushrooms לתיאור ו-1.25 למחיר
    כל דקורטור צריך לממש את Pizza, לקבל Pizza בבנאי שלו ולהעביר את הקריאה לפיצה העטופה לפני הוספת התרומה שלו.
  • main.dart: ייבאו את קובץ הפיצה והדגימו כיצד הדקורטורים מצטברים ליצירת הזמנה מותאמת אישית. התחילו ב-PlainPizza, עטפו אותה ב-CheeseDecorator, לאחר מכן עטפו את התוצאה ב-PepperoniDecorator, ולבסוף עטפו את הכול ב-MushroomDecorator. הדפיסו את תיאור הפיצה הסופית, ואז הדפיסו Total: $ ואחריו את המחיר.

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

פלט צפוי:

Plain Pizza, Cheese, Pepperoni, Mushrooms
Total: $12.75

נסו בעצמכם

import 'pizza.dart';

void main() {
  // TODO: צרו PlainPizza
  
  // TODO: עטפו אותה ב-CheeseDecorator
  
  // TODO: עטפו אותה ב-PepperoniDecorator
  
  // TODO: עטפו את הכול ב-MushroomDecorator
  
  // TODO: הדפיסו את תיאור הפיצה הסופית
  
  // TODO: הדפיסו "Total: $" ואחריו את המחיר
}
quiz iconבחנו את עצמכם

השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.

כל השיעורים ביחידה תכנות מונחה עצמים

תרגלו בעצמכם: קומפיילר Dart אונליין