50. Factory by Dictionary

למי שלא מכיר, ה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.

סופ"ש אדיר

שתף