返回实现接口的私有类,保持实现私有

时间:2012-08-04 23:06:55

标签: java

静态方法M返回实现接口A的对象:

interface A { ... }
static A M() { ... }

M内我想构建一个B类型的对象并返回该对象,假设B实现了A

class B implements A { ... }

我不希望客户端代码知道有关B如何实现的任何内容,我希望首选 B不要成为static类,{ {1}} 必须是不可变的,并且可能会有不同的B传递给不同的客户端。我想不惜一切代价阻止B方法B的实例化(没有反思,正如一位用户所评论的那样)。

我如何实现上述目标?我应该在哪里以及如何实施M?你能提供一个简短的代码示例吗?

我的主要问题是:我怎么能有“不同B s?”

3 个答案:

答案 0 :(得分:4)

静态内部类可能是你最好的选择。您将无法“不惜一切代价阻止B实例化”,因为通过反射,客户端代码可以绕过所有访问修饰符。

答案 1 :(得分:3)

您可以使用不会被称为B(匿名)的匿名内部类,但会实现A,例如

interface A {
    void someMethod();
}

public class Test {
    static A M() {
        return new A() {// it will create and return object of anonymous 
                        // class that implements A
            @Override
            public void someMethod() {
            }
        };
    }
}

不使用匿名类的反射对象只能通过方法M创建。它也不能扩展,因此它是不可变性的良好第一步。

答案 2 :(得分:0)

您还可以使用Proxy实现来进一步隐藏实现类

public interface A {
    public Object getValue();
}

public class Factory {
    public static A newInstance() {
        return new ProxyA(AImpl);
    }
}

public class ProxyA implements A {
    private A proxy;
    public ProxyA(A proxy) {
        this.proxy = proxy;
    }

    public Object getValue() {
        return proxy.getValue();
    }
}

所有这一切实际上都是将A的实现隐藏在另一个布局下,并且难以创建ProxyA的实例

但正如@Asaph指出的那样,通过反思,几乎不可能真正防止人们访问类和对象的各个部分......

您还可以通过不同的Classloaders分离您的接口和实现,这样您只需将接口公开给开发人员,并通过动态类在运行时加载它们来实现。虽然没有解决潜在的问题,但它会使那些试图规避工厂的人更加复杂化。

IMHO