Java 我如何保护我的班级';其他开发人员的实现?

Java 我如何保护我的班级';其他开发人员的实现?,java,interface,constructor,factory,Java,Interface,Constructor,Factory,考虑这个接口 public interface IDoSomething { void DoAAA(); void DoBBB(); void DoCCC(); } 这两种实现 public class MyObject1 implements IDoSomething { public MyObject(int a, xObjx x) .. } public class MyObject2 implements IDoSomething { p

考虑这个
接口

public interface IDoSomething {
   void DoAAA();
   void DoBBB();
   void DoCCC();
}
这两种实现

public class MyObject1 implements IDoSomething {
   public MyObject(int a, xObjx x)
    ..
}   

public class MyObject2 implements IDoSomething {
    public MyObject(int a, xObjx x)
    ..
}   
我如何才能不向其他开发人员公开实现类?具体来说,我如何防止以下情况

IDoSomething C = new  MyObject2();
使用工厂级是最佳实践吗

public class DoSomethingFactory {
    static IDoSomething getDoSomething(int a, xObjx x) {
        ...
    }
}

如何扩展此模式以包括具有不同构造函数的实现

如果您总是要在自己的代码中构造MyObject1/2实例,那么您可以将它们设置为包私有(默认权限)。“构建器”模式也可能有意义


你能详细说明一下,如果对象的构造函数被公开了,这有什么关系吗?接口只是定义功能需求,而不是构造需求。

好的软件是在
需要知道的基础上编写的。组件越是不了解它的同伴类如何更好地完成任务。这就是接口所服务的目的。它们允许故意无知的程序员在
需要知道的基础上编写代码

一个问题是,一个想
知道
的程序员几乎总是
知道
。即使您可以阻止您无法阻止的赋值,他们也可以将经过模糊处理的对象强制转换到其实现中,使用反射检查其属性和方法,或者将jar导入十六进制编辑器。这真的不是你能阻止的

你所能做的就是编写代码,使
需要了解的程序员的生活更容易,清楚地传达你的设计意图,并减少程序员作弊的诱惑(使用肮脏的实现细节作为拐杖)。实现这一点的最佳方法是使用创造性模式

参考您关于构造函数不同的观点,所有基本的创建模式都很好地处理了这一点。因为它们提供了对构造函数的抽象。你可以决定暴露多少细节。也许你有一个像下面这样的构造函数:

public ColorThing(int r ,int g, int b)
接受数字颜色值的。在创造性模式的实现中,您可能会决定通过使构造函数
私有化并只允许访问静态工厂方法来简化此过程

private ColorThing(int r , int g, int b){
    ...
}
public static ColorThing buildRedColorThing(){
    return new ColorThing(100,0,0);
}
这将限制
ColorThing
类的使用者只能构造
red
东西

下面列出了几种基本的创作模式,它们可以满足你的需求。它们为
抽象工厂模式
提供了不同程度的模糊处理,这产生了最高程度的封装,但也需要最多的模板

静态工厂法

这是上面的
ColorThing
示例中的人物。这只是在类上提供了一个公共静态方法,用于保护构造函数的基本细节。非常适合简化对具有大量参数的
构造函数的访问。在这种情况下,您可以将构造函数设置为私有的,并根据需要提供尽可能多的静态工厂方法

public class MyObject1 implements IDoSomething {
    private int prop a;
    public static IDoSomething getAnObject(int a){
       return new MyObject(a, new xObjx());
    }
    private MyObject(int a, xObjx x)
        ...
}
构建器模式

构建器模式有一个负责创建类的附带类。它使用java的作用域规则来确保以安全的方式访问构造函数。如果您想拥有大量伸缩构造函数参数,这也非常有用,因为您可以依赖生成器类的方法(
new MyObject1.MyObjectBuilder().setA(2.build()
)的
点链接

抽象工厂

抽象工厂模式
允许您完全封装类的构造。这将只公开每个接口,但它也有最多的锅炉板,因为您必须为要制造的每个类族创建一个
工厂
和一组
产品
实现和接口。是此模式中的类如何关联的教科书示例。此模式具有高度的可扩展性,您将在许多库代码中看到它的使用效果。这是因为这些库的设计者通常不知道他们的框架代码需要支持的全部实现。通过使用
抽象工厂模式
,他们可以让未来的开发人员在他们的代码上构建,同时限制他们的假设施加的限制


你选择哪一个完全取决于你的情况,但你应该从满足你需要的最简单的课程开始,然后逐步学习到更复杂的课程。

我认为工厂课程是一种选择。工厂将知道如何实例化
IDoSomething
的每个不同实现的细节。接口不应定义如何构造该接口实现的实例。接口的唯一目的是定义功能,将其与提供已定义功能的特定实现分离。构造函数仅在实例化特定实例(即类)时使用,这就是为什么在接口中放置构造函数没有意义。顺便说一句,由于Java 8在
接口中有
静态
方法:您需要一些可以创建对象供其他人使用的东西。你有什么想法?基本上我不想告诉其他开发者关于MyObject1和MyObject2的事情。我希望他们只使用接口。@nsfyn55指出,任何类型的构建器、工厂等模式仍然必须返回一个对象,您的客户可以始终将该对象转换为具体类,甚至只是通过反射进行查看。完全排除用户访问您的具体类的唯一方法是将它们删除,并使用适当的调用处理程序返回所有内容,该调用处理程序模仿您的具体实现将执行的任何操作。谢谢。我没有选择
public class MyObject1 implements IDoSomething {
   private int prop a;
   private MyObject1(int a, xObjx x)
   ...

   public class MyObjectBuilder {
       private int a;

       public MyObjectBuilder setA(int a){
            this.a = a;
            return this;
       }
       public IDoSomething build(){
           return new MyObject1(a, new xObjx); 
       }
    }
}