如何使构造函数仅可用于工厂类?

时间:2009-05-27 09:02:54

标签: java class oop singleton

好的,问题可能不是很清楚。我来详细说明一下:

假设我有一个名为CFactory的Shoe(CShoe)对象工厂类。 CFactory是一个单例类,使用简单的hashmap创建和存储所有instanciated鞋。然后通过静态方法访问它以使用创建的对象。

有没有办法迫使CShoe的构造函数只能由工厂调用? (换句话说,确保鞋子的制作只能由鞋厂单身人士而不是其他班级完成)

6 个答案:

答案 0 :(得分:5)

您可以Shoe inner class ShoeFactory

public class ShoeFactory {

    public static class Shoe {
        private String name;

        private Shoe() {
        }

        private Shoe(String name) {
            this.name = name;
        }
    }

    public static Shoe createShoe(String shoeName) {
        return new Shoe(shoeName);
    }
}

我认为这几乎涵盖了所有情况,除了...... reflection

public class SmellyShoe {

    public static void main(String[] args) {
        try {
            java.lang.reflect.Constructor c = Shoe.class.getDeclaredConstructors()[0];
            c.setAccessible(true);
            Shoe smelly = (Shoe)c.newInstance(null);
            // grr
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }
}

答案 1 :(得分:4)

你可以给CShoe构造函数包访问,并将CShoe和CFactory放在同一个包中。

答案 2 :(得分:1)

由于您希望将每个对象添加到地图中,您也可以将此逻辑移动到CShoe构造函数 - 该对象将自行添加。

答案 3 :(得分:1)

首先,如果保留所有已创建的实例,则称为泄漏。我将继续假设您指的是非强引用,有界或某些此类缓存,并且Shoe也是不可变的。

只需使用static方法返回工厂。

public final class Shoe implements Footwear {
    private static final FootwearFactory<Shoe,Something> FACTORY =
        new FootwearFactory<Shoe,Something>() {
            ...
            public Shoe get(Something value) {
                value = new Something(value);
                ...
                return new Show(value);
            }
        };
    private static FootwearFactory<Shoe,Something> getFactory() {
        return FACTORY;
    }

    private final Something value;
    private Shoe(Something value) {
        this.value = value;
    }
    ...
}

答案 4 :(得分:0)

您可以将工厂对象传递给构造函数吗?

public CShoe(CFactory factory)
{
    if (factory == null ||
          !factory.isValid()) // or whatever
    {
        throw new IllegalArgumentException();
    }
}

答案 5 :(得分:0)

难道你不能只将调用者实例作为鞋子的静态成员的参数传递,并且在那里做一个像“isInstanceOf”这样的检查,如果为真,它会调用构造函数吗?