在字段中存储各种类型的模式

Pattern for storing various types in a field

在属于库的 Java class 中,我有一个字段 size 指示图像的大小。它必须是int,但有些值取决于设备,因此其他开发人员可以为其设置各种类型:

  1. 缩略图(值取决于设备)
  2. 实际大小(值取决于设备)
  3. 自定义(任意整数)

我想限制其他开发人员(使用此库的)使用一组特定且有意义的选项中的一个选项来设置 size 的值 options.My 目的是显示 [=14= 的列表] 开发人员以及 type safety,如 Enum。但我认为仅通过 enum 是不可能做到这一点的,所以我创建了一个接口和一些 classes:

public interface SizeMode {
}

public enum DevicePreDefinedImageSizeMode implements SizeMode {
    THUMBNAIL, REAL_SIZE
}

public enum CustomImageSizeMode implements SizeMode {
    CUSTOM_SIZE
}

public abstract class Size {

    private final SizeMode mode;

    public SizeMode getMode() {
        return mode;
    }

    public abstract int getDownSampleFactor();

    protected Size(SizeMode mode) {
        this.mode = mode;
    }
}

public class DevicePreDefinedImageSize extends Size {

    public DevicePreDefinedImageSize(DevicePreDefinedImageSizeMode mode) {
        super(mode);
    }

    @Override
    public int getDownSampleFactor() {
        throw new UnknownError("????");
    }

}

public class CustomImageSize extends Size {
    private final int downSampleFactor;

    private CustomImageSize(CustomImageSizeMode mode, int downSampleFactor) {
        super(mode);
        this.downSampleFactor = downSampleFactor;
    }

    @Override
    public int getDownSampleFactor() {
        return downSampleFactor;
    }

}

现在我可以声明 Size class 类型的字段 size 并且其他开发人员被限制使用 Size 的子 classes 和使用 THUMBNAILREAL_SIZECUSTOM_SIZE.

初始化它们

但是有没有更好的方法来实现我的目的?

另一种选择是使用 Size 只能使用一组静态工厂方法(如果需要,也可以使用构建器模式)创建的实现:

public class Size {
    private final int sampleFactor;

    private Size(int sampleFactor) {
        this.sampleFactor = sampleFactor;
    }

    public static Size thumbnail() {
        return new Size(THUMBNAIL_FACTOR);
    }

    public static Size real() {
        return new Size(REAL_FACTOR);
    }

    public static Size custom(int factor) {
        return new Size(factor);
    }
}

在 java 中,枚举是 类,它们可以有成员。

public interface ISize {
  public int getDownSampleSize();
}

enum Size implements ISize {

    THUMBNAIL(THUMBNAIL_SIZE); // Defined elsewhere.

    private int downSampleSize;

    Size(int downSampleSize) {this.downSampleSize = downSampleSize;}
    public int getDownSampleSize() {return downSampleSize;}
}

public class RealSize implements ISize {
  public int getDownSampleSize() {return /* do something complicated */;}
}

public class CustomSize implements ISize {
  private final int downSampleSize;

  public CustomSize(int downSampleSize) {
    this.downSampleSize = downSampleSize;
  }

  public int getDownSampleSize() {return downSampleSize;}
}

那么用法为:

ISize s;
void resize() {
  int downSampleSize = s.getDownSampleSize();
  ...
}

这与您所做的类似,但更简洁一些。它使您不必同时拥有 SizeSizeMode