我试图将类构造函数隐藏在包范围之外(以及其他一些设置器),并强制潜在的包用户仅通过其构建器获取这个特定的类(为了清晰和验证原因)。
到目前为止,我一直通过将该类及其构建器放在同一个包中并为我想隐藏的所有方法声明包可见性来实现这一目标。然而,这有一些缺点。它强加了更僵硬的包结构并限制了用户扩展类构建器的可能性。
我对任何替代解决方案或模式感到好奇?不久前我听说过关于向 Java 引入“模块”可见性修饰符的传言(我认为这可以解决问题),但我猜他们放弃了这个想法。
-使用protected
访问修饰符来限制对该包之外的构造函数代码的访问。
例如:
public class FilePro {
protected FilePro(){ // This block is accessible only
// within this package
}
}
首先,我建议在产品中进行全面验证(和可变值的复制),而不是信任客户。
如果您想将客户端正在使用的构建器接口与产品分开,请添加该间接层。
最简单的方法是让产品公开一个带有大量参数列表的构造函数并执行通常的构造函数职责(复制可变参数、验证参数并确保对象初始化为可用状态)。构建器可以在不同的依赖包/模块/jar/库中并使用构造函数接口。
所以现在我们回到大构造函数。您可以通过多种方式解决此问题。例如,您可以在同一个类/包/模块中拥有一个规范的构建器,其他对象可以使用该构建器。
或者你可以有一个带有“get”方法的接口(去掉get
前缀,它在gets类型中没有意义)替换构造函数中的每个参数。产品构造函数现在只需要一个参数并且可以提取每个参数。当需要完成产品构建时,每个构建器都可以将接口实现为匿名内部类(例如)。
使用公共 Builder 静态内部类:
public class OuterClass{
private MyType1 field1;
private MyType2 field2;
private OuterClass(MyType1 field1, MyType2 field2){....}
public static class Builder{
private static final MyType1 DEFAULT_VALUE_1 = something;
private static final MyType2 DEFAULT_VALUE_2 = somethingelse;
private MyType1 field1=DEFAULT_VALUE_1;
private MyType2 field2=DEFAULT_VALUE_2;
public Builder() {...}
public setFiled1(MyType1 field1) { this.field1 = field1)
public setFiled2(MyType2 field2) { this.field2 = field2)
public OuterClass build() { return new OuterClass(field1,field2);}
}
}
为了进一步的稳健性,使你的领域在 outerClass final
我没有用 Java 做太多工作,但我相信你可以做的是声明一个创建类实例的静态方法
public static build()
{
return new FilePro();
}
这样您就可以仅从同一个包中创建该类的新实例,并且可以不受任何限制地扩展该类