אני כן מכיר מה זה. אבל אנחנו צריכים לבוא בגישה שאסור לנו להשתמש בזה. למה?
לאחר מכן ניצור מחלקה שיש בה פונקציה מתאימה לכל סוג רכב:
ויהיה לנו מחלקה שבעצם מטפלת בבקשות ויודעת איזה פונקציה מתאימה לאיזה סוג רכב:
עכשיו תארו לכם שאתם צריכים לתחזק את המערכת, ולהוסיף עוד ועוד מכוניות.
כעת ניצור interface שכל מכונית תצטרך לממש אותו:
כל מכונית תממש את ה interface:
ועכשיו לחלק המעניין: זוכרים את ה CarShop שהיה לנו במקרה של Switch-Case? הארוך עם הרבה Case?
תראו מה נקבל עכשיו:
והנה דוגמא לצורה שנפעיל את הקוד:
היתרונות של הקוד הנ"ל:
כאשר נצטרך לתחזק את הקוד ולהוסיף מכונית:
- קשה לתחזוקה
- לא קריא
- כאשר יש המון Case אז נקבל ביצועים נמוכים
וכשאני מתכוון לא להשתמש ב Switch-Case, אני מתכוון גם לא להשתמש במשפטי If מקוננים. את ההבדל בביצועים בין switch ל case אפשר לקרוא כאן
אני אראה לכם למה אני מתכוון.
נגיד ויש לנו מכון שטיפת רכבים מתוחכם. כאשר נכנס רכב למכון, אנחנו רוצים להפעיל את הפונקציה המתאימה לרכב. הקוד שלנו יראה כך:
קודם ניצור Enum עם סוגי המכוניות:
enum CarEnum{
BMW,VW,MERCEDES
}
לאחר מכן ניצור מחלקה שיש בה פונקציה מתאימה לכל סוג רכב:
public class CarHandler
{
public void handleBMW()
{
System.Console.WriteLine("BMW");
}
public void handleVW()
{
System.Console.WriteLine("VW");
}
public void handleMERCEDES()
{
System.Console.WriteLine("MERCEDES");
}
}
ויהיה לנו מחלקה שבעצם מטפלת בבקשות ויודעת איזה פונקציה מתאימה לאיזה סוג רכב:
public class CarShop
{
private CarHandler carHandler = new CarHandler();
public void handleCar(CarEnum car)
{
switch (car)
{
case CarEnum.BMW :
carHandler.handleBMW();
break;
case CarEnum.MERCEDES:
carHandler.handleMERCEDES();
break;
case CarEnum.VW:
carHandler.handleVW();
break;
default: throw new Exception("unknown Car");
}
}
}
עכשיו תארו לכם שאתם צריכים לתחזק את המערכת, ולהוסיף עוד ועוד מכוניות.
- אתם צריכים להוסיף משפט Case
- אתם צריכים להוסיף ערך ל enum
- אתם צריכים לכתוב פונקציה בתוך מחלקת CarHandler
תחשבו איזה ארוך ולא קריא יהיה קטע ה Switch עבור כל סוגי המכוניות...
אז מה עושים?
למדתי אצל Evgeny Borisov את השימוש הנכון :
מה שנעשה זה ניצור Enum "מיוחד" שמדמה את ה Enum שאפשר ליצור בJAVA. ה Enum יכיל בנאי, ועבור כל ערך חדש (כל מכונית חדשה) הבנאי יופעל, ויכניס לתוך LIST את רשימת כל הערכים עם הצבעה לפונקציות המתאימות.
הוא יראה כך: (CarEnum)
public class CarEnum
{
public class CarEnum
{
private String enumName;
private CarHandler handler;
private int dbCode;
private static List<CarEnum> enums = new List<CarEnum>(5);
static CarEnum()
{
enums.Add(new CarEnum("BMW", new BMWHandler(), 1));
enums.Add(new CarEnum("VW", new VWHandler(), 2));
enums.Add(new CarEnum("MERCEDES", new MERCEDESHandler(), 3));
}
private CarEnum(String enumName, CarHandler handler, int dbCode)
{
this.enumName = enumName;
this.handler = handler;
this.dbCode = dbCode;
}
public CarHandler getHandler()
{
return handler;
}
public static CarEnum getEnumByCode(int code)
{
foreach (var carEnum in enums)
{
if (carEnum.dbCode == code)
{
return carEnum;
}
}
throw new Exception("wrong code " + code);
}
public static CarEnum getEnumByName(string name)
{
foreach (var carEnum in enums)
{
if (carEnum.enumName == name)
{
return carEnum;
}
}
throw new Exception("wrong name " + name);
}
}
כעת ניצור interface שכל מכונית תצטרך לממש אותו:
public interface CarHandler
{
void handleCar();
}
public class BMWHandler : CarHandler
{
public void handleCar()
{
System.Console.WriteLine("BMW");
}
}
public class VWHandler : CarHandler
{
public void handleCar()
{
System.Console.WriteLine("VW");
}
}
public class MERCEDESHandler : CarHandler
{
public void handleCar()
{
System.Console.WriteLine("MERCEDES");
}
}
ועכשיו לחלק המעניין: זוכרים את ה CarShop שהיה לנו במקרה של Switch-Case? הארוך עם הרבה Case?
תראו מה נקבל עכשיו:
public class CarShop
{
public void handleCar(CarEnum car)
{
car.getHandler().handleCar();
}
}
//create a new shop
CarShop shop = new CarShop();
//get the correct enum
CarEnum carEnum = CarEnum.getEnumByName("BMW");
//handle the right handler
shop.handleCar(carEnum);
היתרונות של הקוד הנ"ל:
כאשר נצטרך לתחזק את הקוד ולהוסיף מכונית:
- נוסיף שורת קוד אחת ל enum (לבנאי הסטטי)
- נכתוב פונקציה למכונית החדשה שממשת את CarHandler
וגם הקוד יהיה יותר קריא, ללא שום Case


