我正在尝试找到设计“存储桶”客户端存储的最佳方法。解释一下,服务器发送如下信息:
{
'buckets': {
'some_cool_bucket' : 'val1',
'another_bucket' : 'name'
}
}
值可以在哪里
'some_cool_bucket' : 'val1' | 'val2' | 'val3'
'another_bucket' : 'name' | 'cool' | 'other'
基本上,所有这些存储桶都是枚举,其中包含客户端和服务器都知道的所有可能值,尽管没有共同的约束,例如存储桶可以具有任意数量的可能值(没有大小限制)和任何命名方案。
我正在努力对抗 Java 来找到我满意的设计。忘记解析 JSON,等等,从设计的角度来看,我想知道我可以存储满足这些要求的数据:
- 每个存储桶都需要能够存储默认值,以防服务器不发送默认值
- bucket.isBucket(...) 应该是类型安全的,即,如果我们在这里使用枚举,则您不应该能够在不出现错误的情况下传入不属于的存储桶。
- 轻松、简单的访问。 Buckets.some_cool_bucket.is(val1) 是理想的选择。
- 添加新存储桶的样板最少
- 不困惑的设计
忽略这些要求,我们可以按如下方式实现:
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/