java - 客户端请求Bucket信息的设计

标签 java oop design-patterns

我正在尝试找到设计“存储桶”客户端存储的最佳方法。解释一下,服务器发送如下信息:

{
    'buckets': {
        'some_cool_bucket' : 'val1',
        'another_bucket' : 'name'
    }
}

值可以在哪里

'some_cool_bucket' : 'val1' |  'val2' | 'val3'
'another_bucket' : 'name' | 'cool' | 'other'

基本上,所有这些存储桶都是枚举,其中包含客户端和服务器都知道的所有可能值,尽管没有共同的约束,例如存储桶可以具有任意数量的可能值(没有大小限制)和任何命名方案。

我正在努力对抗 Java 来找到我满意的设计。忘记解析 JSON,等等,从设计的角度来看,我想知道我可以存储满足这些要求的数据:

  1. 每个存储桶都需要能够存储默认值,以防服务器不发送默认值
  2. bucket.isBucket(...) 应该是类型安全的,即,如果我们在这里使用枚举,则您不应该能够在不出现错误的情况下传入不属于的存储桶。
  3. 轻松、简单的访问。 Buckets.some_cool_bucket.is(val1) 是理想的选择。
  4. 添加新存储桶的样板最少
  5. 不困惑的设计

忽略这些要求,我们可以按如下方式实现:

enum Bucket {
    some_cool_bucket('val1'),
    another_bucket('name');

    Bucket(String default) {
        [...]
    }

    // Assume this retrieves the stored value sent down from the server.
    String getVal() {
        [...]
    }

    boolean is(String val) {
        return getVal().equals(val);
    }
}

使用Bucket.some_cool_bucket.is('val1')。当然,我们希望通过更改 is() 的类型签名来扩展它,以接受 some_cool_bucket 定义的某些 val 枚举。由于存储桶可以采用的值并不统一,因此我们必须在 some_cool_bucket 枚举中定义它。但是在 Java 中不能在枚举中包含枚举。

好的,重置。让我们再试一次:

public abstract class BaseBucket<E extends Enum<E>> {

    private final Class<E> mClazz;
    private final E mDefaultBucket;

    public BaseBucket(Class<E> clazz, E defaultBucket) {
        mClazz = clazz;
        mDefaultBucket = defaultBucket;
    }

    // Assume this retrieves the stored value sent down from the server, uses
    // getName() to match with the data.
    protected E getVal() {
        [...]
    }

    protected abstract String getName();

    public boolean is(E test) {
        return getVal() == test;
    }
}

public class SomeCoolBucket extends BaseBucket<Val> {
    public SomeCoolBucket() {
        super(Val.class, Val.val1);
    }

    @Override
    public String getName() {
        return "some_cool_bucket";
    }

    public enum Val {
        val1, val2, val3;
    }
}

public Buckets {
    public static final SomeCoolBucket some_cool_bucket = new SomeCoolBucket();
}

好的,这有效!伟大的。它满足所有功能要求,但很麻烦,而且我讨厌必须为每个存储桶创建一个新类。我发现很难证明所有代码的合理性,尽管我相信这些要求是合理的。

有没有人有更好的解决方案?

最佳答案

在这种情况下,您可以做的是拥有抽象 BaseBucket 类,但删除泛型位。基类可以有一个Enum类型的实例变量。要在没有泛型的情况下执行此操作,您可以使用 Strategy设计模式。使用它,您可以使所有枚举类型实现一个通用接口(interface)。作为示例,您可以调用此 IBucketEnum。因此,您的 BaseBucket 类将有一个 IBucketEnum 类型的实例变量,如下所示:

public abstract class BaseBucket{
    private IBucketEnum enum;
    //other instance vars

    public String getName(){
        enum.getName();
    }
}

从那里您可以拥有不同版本的 BaseBucket,它们将具有从基础版本继承的实现和实例变量,但可以使用您需要的其他内容进行扩展。 希望这会有所帮助。

关于java - 客户端请求Bucket信息的设计,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27699216/

相关文章:

javascript - 检查上传文件是否受 Javascript 或 jQuery 密码保护

Java .split 方法匹配空字符串怪异行为

java - 将 AWS 项目从 git 导入到本地计算机

java - 是否可以在 Java 的派生类中取消实现接口(interface)?

c++ - 使用原始指针或智能指针在 C++ 中组合?

java多线程未利用所有核心

java - 在哪些情况下我们将变量设为公有而将方法设为私有(private)?

model-view-controller - 在 node.js 模块中异步初始化导出可以吗?

algorithm - 替换嵌套循环的设计模式

java - 最佳使用的创意设计模式