控制何时创建对象

时间:2012-06-06 16:01:13

标签: java

假设我需要按如下方式创建一个对象并设置一些值

    FileMetaData fileMeta = fileContainer.getMetaData();

    fileMeta.setFileName("file name");
    fileMeta.setServer("my box");
    fileMeta.setDirectory("/path/to/dir");
    fileMeta.setFileType(FileType.PROPERTIES);

我后来打算使用这个对象引用做一些有用的事情。

我想要认识到系统用户可能没有设置某些字段这一事实,例如,人们可能会忘记

    fileMeta.setDateModified(12345);

以某种方式可以保证在使对象可用之前设置所有(或某些特定的)字段吗?

3 个答案:

答案 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框架来实现。