למי שלא מכיר, הDesign Pattern ששמו Factory הוא Design Pattern נפוץ המשמש לאתחול אובייקטים.
לדוגמה:
1 2 3 4
| public abstract class Shape public class Circle : Shape public class Triangle : Shape public class Square : Shape
|
יש לנו 3 מחלקות ואנחנו מעוניינים ליצור מחלקה עפ"י השם שלה.
המימוש הכי פשוט הוא משהו כזה:
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
| public class ShapeFactory { public static Shape CreateByName(string name) { switch (name) { case "Circle": { return new Circle(); } case "Triangle": { return new Triangle(); } case "Square": { return new Square(); } default: { return null; } } } }
|
ואז אנחנו יכולים להשתמש בזה ככה:
1 2
| Shape triangle = ShapeFactory.CreateByName("Triangle");
|
אלא שהמימוש לא כל כך יפה.
נוכל לעשות את זה טיפה יותר יפה באמצעות שימוש בDictionary:
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 27 28 29 30 31 32
| public class ShapeFactory { private static Dictionary<string, Func<Shape>> m_NameToShapeCreator; static ShapeFactory() { m_NameToShapeCreator = new Dictionary<string, Func<Shape>>(); m_NameToShapeCreator["Circle"] = () => new Circle(); m_NameToShapeCreator["Triangle"] = () => new Triangle(); m_NameToShapeCreator["Square"] = () => new Square(); } public static Shape CreateByName(string shapeName) { Func<Shape> shapeDelegate; bool shapeFound = m_NameToShapeCreator.TryGetValue(shapeName, out shapeDelegate); if (shapeFound) { return shapeDelegate(); } else { return null; } } }
|
ולמרחיקי הלכת, ניתן לאתחל את הDictionary באמצעות Collection Initializer:
1 2 3 4 5 6 7 8 9 10
| static ShapeFactory() { m_NameToShapeCreator = new Dictionary<string, Func<Shape>>() { {"Circle", () => new Circle()}, {"Triangle", () => new Triangle()}, {"Square", () => new Square()} }; }
|
שימו לב שלא דיברנו כאן איך נכון לאתחל את הFactory (כלומר את הDictionary הזה), אלא רק איך אפשר לנצל את הDictionary בשביל המטרה של Factory.
סופ"ש אדיר