380. Strategy design pattern

בהמשך לטיפים הקודמים,

נדבר הפעם על הDesign pattern ששמו Strategy.

הרעיון של הDesign pattern הוא מימוש של חלק ממחלקה באמצעות מחלקה אחרת.

הדבר מאפשר החלפת חלק מההתנהגות של המחלקה באמצעות הזרקה של מחלקה אחרת.


לדוגמה, נניח שיש לנו את הממשק הזה:

1
2
3
4
5
public interface ICommutativeCalculator
{
int Add(int a, int b);
int Multiply(int a, int b);
}

נוכל ליצור מימוש מוכוון Strategy שלו כך:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public class StrategyBasedCommutativeCalculator : ICommutativeCalculator
{
private readonly INumberAdder mAdder;
public StrategyBasedCommutativeCalculator(INumberAdder adder)
{
mAdder = adder;
}
public int Add(int a, int b)
{
return mAdder.Add(a, b);
}
public int Multiply(int a, int b)
{
int result = 0;
for (int i = 0; i < b; i++)
{
result = Add(result, a);
}
return result;
}
}

כאשר הממשק INumberAdder נראה כך:

1
2
3
4
public interface INumberAdder
{
int Add(int a, int b);
}

כעת אנחנו יכולים לאפשר שינוי ההתנהגות של הCalculator ע"י מימושים שונים של NumberAdder, למשל:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class SlowNumberAdder : INumberAdder
{
public int Add(int a, int b)
{
int result = a;
for (int i = 0; i < b; i++)
{
result++;
}
return result;
}
}

או מימוש טיפה יותר טוב 😃

1
2
3
4
5
6
7
public class BetterNumberAdder : INumberAdder
{
public int Add(int a, int b)
{
return a + b;
}
}

וכך נוכל להחליף את ההתנהגות של הפונקציה שלנו ע"י שינוי הAdder מבחוץ:

1
2
3
4
5
ICommutativeCalculator slowerCalculator =
new StrategyBasedCommutativeCalculator(new SlowNumberAdder());
ICommutativeCalculator slowCalculator =
new StrategyBasedCommutativeCalculator(new BetterNumberAdder());

בסה"כ אנחנו רואים שאנחנו יכולים לשפר את המחלקה שלנו ע"י שיפור "האלגוריתם" הפנימי שלה.


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

בנוסף, הדבר יכול להיות שימושי אם נוכל לקנפג את הStrategy בו אנחנו משתמשים מבחוץ – כך נוכל להחליף התנהגות של מחלקה מבלי לשנות קוד.

הדבר גם מאפשר Mocking בחלק מהמקרים.

אני מניח שכולנו השתמשנו בדברים כאלה, רק לא ידענו שקוראים לזה Strategy.

סופ"ש מלא אסטרטגיה טוב.

שתף