假设我需要按如下方式创建一个对象并设置一些值
FileMetaData fileMeta = fileContainer.getMetaData();
fileMeta.setFileName("file name");
fileMeta.setServer("my box");
fileMeta.setDirectory("/path/to/dir");
fileMeta.setFileType(FileType.PROPERTIES);
我后来打算使用这个对象引用做一些有用的事情。
我想要认识到系统用户可能没有设置某些字段这一事实,例如,人们可能会忘记
fileMeta.setDateModified(12345);
以某种方式可以保证在使对象可用之前设置所有(或某些特定的)字段吗?
答案 0 :(得分:2)
语言中没有任何内容可以强制执行此操作(除了拥有一个单独的可见构造函数以获取所有必需参数),但您可以通过构建器模式和某些方法链接的变体来惯用它:
FileMetaData fileMeta = new FileMetaDataBuilder(fileContainer.getMetaData())
.setFileName("file name")
.setServer("my box")
.setDirectory("/path/to/dir")
.setFileType(FileType.PROPERTIES)
.build();
build()
方法可以确保在调用具有所有必需参数的FileMetaData
的相应构造函数之前设置所有必需字段。
答案 1 :(得分:1)
使用构建器模式并将引用传递给构建器。当您在顶部添加额外内容时,请调用.build并捕获返回的FileMetaData实例。
您可以通过在设置所有先决条件之前不允许构建成功来约束它。
答案 2 :(得分:0)
基本上我可以分类以下3种方式。
首先是基于类本身。您可以将方法isReady()
添加到您的班级。此方法将执行所有检查并返回true或false。
其他方式是使用Factory或Builder模式以及可能的对象存储库。工厂和构建器都保证在就绪状态下创建对象。存储库可用于在那里“发布”就绪对象,因此其他代码只请求对象并将其接收到就绪状态。
其他方法是使用Wrapper(Decorator)模式。
interface Foo {
public void foo(); //business method
}
class FooImpl implements Foo {
public void foo(){} // does the work
}
class FooDecorator implmeents Foo {
Foo foo;
public void foo(){
if (isInitialized()) {
foo.foo();
}
throw IllegalStateException("Not initialized");
}
}
此解决方案可以使用动态代理或使用AOP框架来实现。