1

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

    FileMetaData fileMeta = fileContainer.getMetaData();

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

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

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

    fileMeta.setDateModified(12345);

是否有可能保证在使对象可用之前设置所有(或某些特定)字段?

4

3 回答 3

2

语言中没有任何东西可以强制执行此操作(除了有一个单独的可见构造函数,它接受所有必需的参数),但您可以通过构建器模式的变体和一些方法链接来惯用地执行此操作:

FileMetaData fileMeta = new FileMetaDataBuilder(fileContainer.getMetaData())
    .setFileName("file name")
    .setServer("my box")
    .setDirectory("/path/to/dir")
    .setFileType(FileType.PROPERTIES)
    .build();

build()方法可以确保在FileMetaData使用所有必需参数调用适当的构造函数之前设置所有必需的字段。

于 2012-06-06T16:08:10.000 回答
1

使用构建器模式并将引用传递给构建器。当您在顶部完成添加附加内容后,调用 .build 并捕获返回的 FileMetaData 实例。

您可以通过在设置所有先决条件之前不允许构建成功来限制它。

于 2012-06-06T16:04:21.933 回答
0

基本上我可以分为以下3种方式。

首先是基于类本身。您可以将方法添加isReady()到您的课程中。此方法将执行所有检查并返回 true 或 false。

其他方法是使用工厂或生成器模式以及可能的对象存储库。factory 和 builder 都保证创建处于就绪状态的对象。存储库可用于在那里“发布”就绪对象,因此其他代码请求对象并仅在就绪状态下接收它们。

另一种方法是使用包装器(装饰器)模式。

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

于 2012-06-06T16:10:05.000 回答