如何从工厂模式中获取具体 类 的数量?
How to get number of concrete classes from factory pattern?
工厂模式通常为具体的 classes 创建一个基础 class,然后具体的 classes 从该基础 class 继承。对于很多应用程序,我们需要知道这个工厂可以创建的具体 classes 的数量。例如,一个创建典型 Shape 对象(圆形、矩形等)的工厂。下面的 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;
}
}
用户可能想知道程序支持多少种形状。我知道有两种方法可以做到这一点:
- 在工厂中将数字设置为常量class并使其成为
public 可见。缺点是每次添加新的
形状,你要手动增加形状的数量。
- 创建一个包含所有实例的动态容器(C# 中的 List)
工厂可以创建的具体对象。优点是
它可以自动计算出它可以处理的形状数量
创建,即使添加了新的 Shape classes。缺点是
很明显,每种形状都必须与
要求形状!
最好的方法是什么?关于这个特定主题的最佳实践?
您可以将形状类型存储在数组中,然后使用 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);
}
}
您可以创建一个为您存储常量的枚举。
这也有助于通过 IDE 的自动完成功能了解 'possibilities' 来帮助用户,此外它还可以防止用户输入数字 'out of bounds',例如在您的示例中输入“4”。 (请注意,我通常写 java... 所以 C# 不是我的强项,但你可以 'something' 类似于此)
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;
}
}
每次添加新的可能性时都必须编辑 class 的 "issue" 是没有实际意义的,因为你每次这样做都必须编辑这个 class,现在你只需要编辑 'PossibleShapes' class。
(请注意,我仍然不认为这是工厂模式的正确用法,因为我不知道 'color' 和 'thickness' 值的来源,但至少这比使用反射更好)
这是一个 Builder Pattern 示例,我认为它是一个更好的示例,它为您封装了您的对象创建。 (您可以使用工厂方法模式,而不是为每个要在构建器中 'get' 的形状使用不同的命名方法)
此外,这允许用户自己轻松设置 color/thickness(仍然可以有默认值,但我没有将其放入此代码示例中)
表示由构建器创建的产品
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 否则没有办法解决这个问题。必须对某处的 builder/factory/etc 进行一些编辑。
工厂模式通常为具体的 classes 创建一个基础 class,然后具体的 classes 从该基础 class 继承。对于很多应用程序,我们需要知道这个工厂可以创建的具体 classes 的数量。例如,一个创建典型 Shape 对象(圆形、矩形等)的工厂。下面的 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;
}
}
用户可能想知道程序支持多少种形状。我知道有两种方法可以做到这一点:
- 在工厂中将数字设置为常量class并使其成为 public 可见。缺点是每次添加新的 形状,你要手动增加形状的数量。
- 创建一个包含所有实例的动态容器(C# 中的 List) 工厂可以创建的具体对象。优点是 它可以自动计算出它可以处理的形状数量 创建,即使添加了新的 Shape classes。缺点是 很明显,每种形状都必须与 要求形状!
最好的方法是什么?关于这个特定主题的最佳实践?
您可以将形状类型存储在数组中,然后使用 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);
}
}
您可以创建一个为您存储常量的枚举。 这也有助于通过 IDE 的自动完成功能了解 'possibilities' 来帮助用户,此外它还可以防止用户输入数字 'out of bounds',例如在您的示例中输入“4”。 (请注意,我通常写 java... 所以 C# 不是我的强项,但你可以 'something' 类似于此)
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;
}
}
每次添加新的可能性时都必须编辑 class 的 "issue" 是没有实际意义的,因为你每次这样做都必须编辑这个 class,现在你只需要编辑 'PossibleShapes' class。
(请注意,我仍然不认为这是工厂模式的正确用法,因为我不知道 'color' 和 'thickness' 值的来源,但至少这比使用反射更好)
这是一个 Builder Pattern 示例,我认为它是一个更好的示例,它为您封装了您的对象创建。 (您可以使用工厂方法模式,而不是为每个要在构建器中 'get' 的形状使用不同的命名方法)
此外,这允许用户自己轻松设置 color/thickness(仍然可以有默认值,但我没有将其放入此代码示例中)
表示由构建器创建的产品
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 否则没有办法解决这个问题。必须对某处的 builder/factory/etc 进行一些编辑。