如何从工厂模式中获取具体类的数量
本文关键字:获取 工厂 模式 | 更新日期: 2023-09-27 18:28:21
工厂模式通常为具体类创建一个基类,然后具体类从该基类继承。对于许多应用程序,我们需要知道这个工厂可以创建的具体类的数量。例如,一个创建典型形状对象(圆形、矩形等)的工厂C#代码示例如下:
public class ShapeFactory
{
public IShape GetShape(int shapeIndex)
{
IShape s = null;
const int color = 1;
const int thickness = 5;
switch (shapeIndex)
{
case 1: s = new Square(color, thickness);
break;
case 2: s = new Triangle(thickness);
break;
case 3: s = new Circle(color);
break;
}
return s;
}
}
用户可能想知道程序支持多少种形状。我知道两种方法:
- 在工厂类中将数字设置为常量,并使其公众可见。缺点是每次添加新的形状,您必须手动增加形状的数量
- 创建一个包含所有实例的动态容器(C#中的List)工厂可以创建的具体对象。优点是它可以自动计算出它可以创建,即使添加了新的Shape类。缺点是显然,每种形状都必须与请求形状
最好的方法是什么?在这个特定主题上有什么最佳实践吗?
您可以创建一个为您存储常量的枚举。这也有助于用户了解IDE的自动完成功能的"可能性",并防止用户输入"越界"的数字,例如在示例中输入"4"。(请注意,我通常写java…所以C#不是我的强项,但你可以做类似的事情)
public class ShapeFactory
{
enum PossibleShapes {CIRCLE,
SQUARE,
TRIANGLE, // c# allows you to do this (extra comma) on constructors, not sure about Enums, and helps with reducing 'bad' line changes in git/etc.
};
public IShape GetShape(PossibleShapes whichShape)
{
IShape s = null;
switch (shapeCode)
{
case PossibleShapes.SQUARE : s = new Square(color, thickness);
break;
case PossibleShapes.TRIANGLE: s = new Triangle(thickness);
break;
case PossibleShapes.CIRCLE: s = new Circle(color);
break;
}
return s;
}
}
每次添加新的可能性时都必须编辑类的"问题"是没有意义的,因为每次添加都必须编辑这个类,现在你只需要编辑"PossibleShapes"类。
(请注意,我仍然不认为这是工厂模式的正确使用,因为我不知道"颜色"answers"厚度"值来自哪里,但至少这比使用反射要好)
这里有一个构建器模式示例,我认为它为您封装对象创建提供了一个更好的示例。(你可以使用工厂方法模式,而不是为你想在构建器中"获得"的每个形状使用不同的命名方法)
此外,这允许用户自己轻松设置颜色/厚度(仍然可以有默认值,但我没有把它放在这个代码示例中)
表示生成器创建的产品
public class Shape
{
public Shape()
{
}
public int Color { get; set; }
public int Thickness { get; set; }
}
建设者抽象
public interface IShapeBuilder
{
// Adding NotNull attribute to prevent null input argument
void SetColor([NotNull]string colour);
// Adding NotNull attribute to prevent null input argument
void SetThickness([NotNull]int count);
Shape GetShape();
}
混凝土建筑商实施
public class ShapeBuilder : IShapeBuilder
{
private Shape _shape;
public ShapeBuilder()
{
}
public int GetNumberShapesPossible()
{
//return some # here
}
public void GetSquare(){
this._shape = new Square();
}
public void GetCircle(){
this._shape = new Circle();
}
public void SetColor(string color)
{
this._shape.Color = color;
}
public void SetThickness(int thickness)
{
this._shape.Thickness = thickness;
}
public Shape Build()
{
return this._shape;
}
}
总监
public class ShapeBuildDirector
{
public Shape Construct()
{
ShapeBuilder builder = new ShapeBuilder();
builder.GetCircle();
builder.SetColour(2);
builder.SetThickness(4);
return builder.GetResult();
}
}
当您想向库中添加新的具体类时,必须在某个地方更改一些代码。除非你计划将具体的类捆绑成某种.dll,否则这是没有办法的。必须对某个建筑商/工厂等进行一些编辑。
您可以将形状类型存储在数组中,然后使用Activator创建实例。这可以处理索引、计数并简化创建功能。
static class ShapeFactory
{
private static readonly Type[] _shapes = new Type[] { typeof(Square), typeof(Triangle), typeof(Circle) };
public static int FactorySize
{
get
{
return _shapes.Length;
}
}
public static IShape GetShape(int shapeIndex, params object[] ctorParams)
{
return (IShape)Activator.CreateInstance(_shapes[shapeIndex], ctorParams);
}
}