位运算配置Feature

假设我正在开发一个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));
	}
}


猜你喜欢

转载自blog.csdn.net/qq_21508059/article/details/80328483