假设我正在开发一个HttpClient框架,我希望动态配置框架的特性,如是否使用KeepAlive,阻塞等待响应的最长时间等。这里介绍一个简单的方式实现一些特性的配置。
Feature
这个枚举中的每个元素维护一个掩码mask,每个元素代表一个特性
package config;
public enum Feature {
KEEP_ALIVE, //是否长连接
CONNECTION_POOL, //是否使用连接池
FEATURE1,
FEATURE2,
FEATURE3,
FEATURE4
;
//当前特性的掩码
private int mask;
private Feature() {
//这里是关键,生成的mask,只有一位是1,其他位是0
mask = 1 << ordinal();
}
public int getMask() {
return mask;
}
/**
* 配置某个特性
*/
public static int config(int features, Feature feature, boolean use) {
if (use) {
features |= feature.getMask(); //或,将相应位置1
} else {
features &= ~feature.getMask(); //设置相应位为0
}
return features;
}
/**
* 确认某个特性是否启用
*/
public static boolean isUsing(int features, Feature feature) {
return (features & feature.getMask()) != 0;
}
}
在框架中使用:
package config;
public class HttpClient {
private int features = 0;
{
//设置初始特性,使用KeepAlive和Feature4
features = Feature.config(features, Feature.KEEP_ALIVE, true);
features = Feature.config(features, Feature.FEATURE4, true);
}
public void config(Feature feature, boolean use) {
features = Feature.config(features, feature, use);
}
public boolean isUsing(Feature feature) {
return Feature.isUsing(features, feature);
}
public static void main(String[] args) {
//验证正确性
HttpClient client = new HttpClient();
System.out.println(client.isUsing(Feature.KEEP_ALIVE));
System.out.println(client.isUsing(Feature.CONNECTION_POOL));
}
}
这种方式的好处是节省空间,并且效率也不差。
当然,可配置的特性不超过32个才能使用int类型,如果特性超过32个可以考虑使用long类型
还可以完全使用Int
package config;
public class StaticFeatures {
public static final int KEEP_ALIVE = 1 << 0; //是否长连接
public static final int CONNECTION_POOL = 1 << 1; //是否长连接
public static final int FEATURE1 = 1 << 2; //是否长连接
public static final int FEATURE2 = 1 << 3; //是否长连接
public static final int FEATURE3 = 1 << 4; //是否长连接
public static final int FEATURE4 = 1 << 5; //是否长连接
/**
* 启用多个特性
*/
public static int config(int sourceFeature, int newFeatures) {
return sourceFeature |= newFeatures;
}
/**
* 配置某个特性
*/
public static int config(int features, int feature, boolean use) {
if (use) {
features |= feature; //或,将相应位置1
} else {
features &= ~feature; //设置相应位为0
}
return features;
}
/**
* 确认某个特性是否启用
*/
public static boolean isUsing(int features, int feature) {
return (features & feature) != 0;
}
}
package config;
public class HttpClient {
private int features = 0;
{
//一个更令人兴奋的特性,可以用或运算启用多个特性
features = StaticFeatures.CONNECTION_POOL | StaticFeatures.KEEP_ALIVE;
}
public int getFeatures() {
return features;
}
public static void main(String[] args) {
//验证正确性
HttpClient client = new HttpClient();
System.out.println(StaticFeatures.isUsing(client.getFeatures(), StaticFeatures.KEEP_ALIVE));
System.out.println(StaticFeatures.isUsing(client.getFeatures(), StaticFeatures.CONNECTION_POOL));
}
}