Menu
Coddy logo textTech

תבנית Strategy

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

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

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

abstract class PaymentStrategy {
  void pay(double amount);
}

class CreditCardPayment implements PaymentStrategy {
  @override
  void pay(double amount) => print('Paid \$$amount with Credit Card');
}

class PayPalPayment implements PaymentStrategy {
  @override
  void pay(double amount) => print('Paid \$$amount with PayPal');
}

class ShoppingCart {
  PaymentStrategy _paymentStrategy;

  ShoppingCart(this._paymentStrategy);

  void setPaymentStrategy(PaymentStrategy strategy) {
    _paymentStrategy = strategy;
  }

  void checkout(double total) {
    _paymentStrategy.pay(total);
  }
}

void main() {
  var cart = ShoppingCart(CreditCardPayment());
  cart.checkout(99.99);  // שולם $99.99 בכרטיס אשראי

  cart.setPaymentStrategy(PayPalPayment());
  cart.checkout(49.99);  // שולם $49.99 באמצעות PayPal
}

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

challenge icon

אתגר

קל

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

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

  • formatting_strategies.dart: צרו כאן את מערכת האסטרטגיות. הגדירו מחלקה מופשטת FormattingStrategy עם מתודה String format(String text). לאחר מכן ממשו שלוש אסטרטגיות קונקרטיות:
    • UppercaseStrategy - ממירה את הטקסט כולו לאותיות גדולות
    • LowercaseStrategy - ממירה את הטקסט כולו לאותיות קטנות
    • TitleCaseStrategy - הופכת את האות הראשונה בכל מילה לאות גדולה (פיצול לפי רווחים, הפיכת התו הראשון בכל מילה לאות גדולה ושאר האותיות לקטנות)
    צרו גם מחלקה TextProcessor שמחזיקה FormattingStrategy. צריכה להיות לה בנאית שמקבלת אסטרטגיה התחלתית, מתודה setStrategy() לשינוי האסטרטגיה בזמן הריצה, ומתודה process(String text) שמחילה את האסטרטגיה הנוכחית ומחזירה את התוצאה המעוצבת.
  • main.dart: ייבאו את אסטרטגיות העיצוב שלכם והדגימו כיצד תבנית האסטרטגיה מאפשרת מעבר דינמי בין התנהגויות. צרו TextProcessor שמתחיל עם UppercaseStrategy. עבדו את הטקסט hello world והדפיסו את התוצאה. לאחר מכן עברו ל־LowercaseStrategy, עבדו את HELLO WORLD והדפיסו. לבסוף, עברו ל־TitleCaseStrategy, עבדו את the quick brown fox והדפיסו את התוצאה.

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

הפלט הצפוי:

HELLO WORLD
hello world
The Quick Brown Fox

נסו בעצמכם

import 'formatting_strategies.dart';

void main() {
  // TODO: צרו TextProcessor שמתחיל עם UppercaseStrategy
  
  // TODO: עבדו את הטקסט 'hello world' והדפיסו את התוצאה
  
  // TODO: עברו ל-LowercaseStrategy
  
  // TODO: עבדו את 'HELLO WORLD' והדפיסו את התוצאה
  
  // TODO: עברו ל-TitleCaseStrategy
  
  // TODO: עבדו את 'the quick brown fox' והדפיסו את התוצאה
}
quiz iconבחנו את עצמכם

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

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

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