【问题标题】:Using reflection in a factory在工厂中使用反射
【发布时间】:2013-03-27 16:16:19
【问题描述】:

我有一个工厂,可以构建多种类型的对象,并且它可能会增长。

使用反射返回所有不同的类型而不是调用getPrototypes() 方法中的每个方法会是一个好主意吗?

反射后看起来像这样:

public final class ShapeFactory
{
    private ShapeFactory(){} // no instance

    public static Shape buildSquare()
    {
        return new Square(2);
    }

    public static Shape buildCircle()
    {
        return new Circle(2);
    }

    public static Shape buildTriangle()
    {
        return new Triangle(2, 2, 2);
    }

    // and many more shapes...

    public static List<Shape> getPrototypes()
    {
        final List<Shape> prototypes = new ArrayList<>();

        // using reflection, call every build function
        final Method[] methods = ShapeFactory.class.getMethods();
        for(final Method picked : methods)
        {
            if(picked.getReturnType() == Shape.class && picked.getParameterTypes().length == 0)
            {
                try
                {
                    prototypes.add((Shape)picked.invoke(null));
                }
                catch(final Exception e)
                {
                    // this is an example, do not ignore
                    // exceptions in real code
                }
            }
        }

        return prototypes;
    }
}

很抱歉使用 Shape 示例。

编辑:形状是可克隆的原型。 编辑 #2:改进示例以防有人使用它。

【问题讨论】:

标签: java oop design-patterns reflection coding-style


【解决方案1】:

使用反射返回所有不同的类型而不是调用 getPrototypes() 方法中的每个方法会是一个好主意吗?

这是一件合理的事情。反射代码更加复杂和脆弱,但这意味着您在添加新的形状生成器方法时不需要更改getPrototypes()。这取决于哪个对您更重要。

但是,您不应该像您正在做的那样压制异常。也许您应该对用于创建原型的方法更具选择性。 (如果您添加的方法返回 Shape 但需要参数...或者不是构建器,则当前版本将失败。)

【讨论】:

  • 是的,这仅用于示例。
  • 我在示例中添加了关于忽略异常的警告。
【解决方案2】:

这实际上取决于您是希望在编译时完成类型检查,还是希望以牺牲编译时检查为代价来实现运行时探索的灵活性。

这两个选项都是完全有效的方法。

【讨论】:

  • 在这种情况下,我认为反射使它更干净、更灵活。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多