エレガントな解決ツールクラス設計

82154 ワード

目次

  • エレガントなケース
  • クラスを使用して論理
  • をカプセル化する.
  • ポリシー統合
  • エレガントなケース2
  • デコレーション拡張機能
  • エレガントなケース3
  • エレガントなケース1


    問題思考:設計ツールクラスを考えるとき、ほとんどの場合、私はクラスに関連し、静的メソッドを定義し、この静的メソッドを呼び出して多重化することに慣れています.大体次のようになります.
    例:タイプ変換ツールクラス、beanとmapの変換、2つのシーンを説明します.
  • bean 2 mapはbean変換mapの実装であり、私たちの多くはこのように設計されたツールクラス
  • である.
  • map 2 Beanとmap 2 Bean 2はmapステアリングbeanの2つの異なる実装であり、機能は一致する
  • である.
    public class PropertyUtils {
    	public static Map<String, Object> bean2Map(Object object)
    			throws IntrospectionException, IllegalAccessException, InstantiationException, InvocationTargetException {
    		BeanInfo beanInfo = Introspector.getBeanInfo(object.getClass());
    		PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
    
    		Map<String, Object> map = new HashMap<>();
    		for (PropertyDescriptor pd : propertyDescriptors) {
    			if (pd.getPropertyType().isAssignableFrom(Class.class)) {
    				continue;
    			}
    			String propertyName = pd.getName();
    			Method readMethod = pd.getReadMethod();
    			if (!readMethod.isAccessible()) {
    				readMethod.setAccessible(true);
    			}
    			Object propertyValue = readMethod.invoke(object);
    			map.put(propertyName, propertyValue);
    		}
    		return map;
    	}
    
    	public static <T> T map2Bean(Class<T> type, Map<String, Object> map)
    			throws IntrospectionException, IllegalAccessException, InstantiationException, InvocationTargetException {
    		BeanInfo beanInfo = Introspector.getBeanInfo(type);
    		PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
    		T obj = type.newInstance();
    		for (PropertyDescriptor pd : propertyDescriptors) {
    			if (pd.getPropertyType().isAssignableFrom(Class.class)) {
    				continue;
    			}
    			String propertyName = pd.getName();
    			if (map.containsKey(propertyName)) {
    				Object value = map.get(propertyName);
    				Method setter = pd.getWriteMethod();
    				if (!setter.isAccessible()) {
    					setter.setAccessible(true);
    				}
    				setter.invoke(obj, value);
    			}
    		}
    		return obj;
    	}
    
    	public static <T> T map2Bean2(Class<T> type, Map<String, Object> map)
    			throws IntrospectionException, IllegalAccessException, InstantiationException, InvocationTargetException {
    		T obj = type.newInstance();
    		for (Entry<String, Object> entry : map.entrySet()) {
    			String key = entry.getKey();
    			Object value = entry.getValue();
    			PropertyDescriptor pd = new PropertyDescriptor(key, type);
    			Method writeMethod = pd.getWriteMethod();
    			if (!writeMethod.isAccessible()) {
    				writeMethod.setAccessible(true);
    			}
    			writeMethod.invoke(obj, value);
    		}
    		return obj;
    	}
    }
    

    クラスを使用して論理をカプセル化


    bean 2 mapの問題に対して、タイプの転換なため、私達はとても容易に適当な者の思想を思い付きます抽象インタフェース
    /**
     * Created by it
     * Created in 2019 3 26 
     * Description:  
     */
    public abstract class AbstracAdapter<T, D> {
    	
    	protected T t;
    	
    	public AbstracAdapter(T t) {
    		this.t = t;
    	}
    	
    	public abstract D conver() throws Exception;
    	
    }
    

    具体的には、ここでは拡張を残すことができ、Bean 2 map Adapterは他の方法を追加することができる.
    /**
     * Created by it
     * Created in 2019 3 26 
     * Description:  
     */
    public class Bean2MapAdapter extends AbstracAdapter<Object, Map<String, Object>> {
    	
    	public Bean2MapAdapter(Object t) {
    		super(t);
    	}
    	
    	public Map<String, Object> conver() throws IntrospectionException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
    		Map<String, Object> map = new HashMap<>();
    		BeanInfo beanInfo = Introspector.getBeanInfo(t.getClass());
    		PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
    
    		for (PropertyDescriptor pd : propertyDescriptors) {
    			if (pd.getPropertyType().isAssignableFrom(Class.class)) {
    				continue;
    			}
    			String propertyName = pd.getName();
    			Method readMethod = pd.getReadMethod();
    			if (!readMethod.isAccessible()) {
    				readMethod.setAccessible(true);
    			}
    			Object propertyValue = readMethod.invoke(t);
    			map.put(propertyName, propertyValue);
    		}
    		return map;
    	}
    	
    }
    
    

    エレガントなパッケージツールクラスを
    /**
     * 
     * Created by it
     * Created in 2019 3 25 
     * Description:  bean 
     */
    public class PropertyUtils {
    	
    	/**
    	 * bean -> Map
    	 */
    	public static Map<String, Object> bean2Map(Object object) {
    		Bean2MapAdapter adapter = new Bean2MapAdapter(object);
    		try {
    			return adapter.conver();
    		} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | IntrospectionException e) {
    			throw new RuntimeException(e);
    		}
    	}
    }
    

    戦略者の統合


    map 2 Beanとmap 2 Bean 2の2つの異なる実装に対して,異なる実装パッケージクラスに対して戦略者モードを容易に考えることができる.
    ちゅうしょうしゅつインタフェース
    public interface AbstractMap2Bean {
    	<T> T map2Bean(Class<T> type, Map<String, Object> map) throws Exception;
    }
    

    具体的には、ここでは2種類、任意の種類を拡張することもできます
    /**
     * Created by it
     * Created in 2019 3 26 
     * Description:  
     */
    public class Bean2MapAdapter extends AbstracAdapter<Object, Map<String, Object>> {
    	
    	public Bean2MapAdapter(Object t) {
    		super(t);
    	}
    	
    	public Map<String, Object> conver() throws IntrospectionException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
    		Map<String, Object> map = new HashMap<>();
    		BeanInfo beanInfo = Introspector.getBeanInfo(t.getClass());
    		PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
    
    		for (PropertyDescriptor pd : propertyDescriptors) {
    			if (pd.getPropertyType().isAssignableFrom(Class.class)) {
    				continue;
    			}
    			String propertyName = pd.getName();
    			Method readMethod = pd.getReadMethod();
    			if (!readMethod.isAccessible()) {
    				readMethod.setAccessible(true);
    			}
    			Object propertyValue = readMethod.invoke(t);
    			map.put(propertyName, propertyValue);
    		}
    		return map;
    	}
    	
    }
    
    

    エレガントなパッケージツールクラスを
    /**
     * 
     * Created by it
     * Created in 2019 3 25 
     * Description:  bean 
     */
    public class PropertyUtils {
    	
    	/**
    	 * bean -> Map
    	 */
    	public static Map<String, Object> bean2Map(Object object) {
    		Bean2MapAdapter adapter = new Bean2MapAdapter(object);
    		try {
    			return adapter.conver();
    		} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | IntrospectionException e) {
    			throw new RuntimeException(e);
    		}
    	}
    }
    

    元のツールクラスメソッドmap 2 Beanを次の2つにカプセル化
    /**
     * Created by it
     * Created in 2019 3 26 
     * Description:  bean 
     */
    public class DefaultMap2Bean implements AbstractMap2Bean {
    
    	@Override
    	public <T> T map2Bean(Class<T> type, Map<String, Object> map) throws IntrospectionException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
    		BeanInfo beanInfo = Introspector.getBeanInfo(type);
    		PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
    		T obj = type.newInstance();
    		for (PropertyDescriptor pd : propertyDescriptors) {
    			if (pd.getPropertyType().isAssignableFrom(Class.class)) {
    				continue;
    			}
    			String propertyName = pd.getName();
    			if (map.containsKey(propertyName)) {
    				Object value = map.get(propertyName);
    				Method setter = pd.getWriteMethod();
    				if (!setter.isAccessible()) {
    					setter.setAccessible(true);
    				}
    				setter.invoke(obj, value);
    			}
    		}
    		return obj;
    	}
    
    }
    
    

    第2種
    /**
     * Created by it
     * Created in 2019 3 26 
     * Description:  map 
     */
    public class PriorityMap4Map2Bean implements AbstractMap2Bean {
    
    	@Override
    	public <T> T map2Bean(Class<T> type, Map<String, Object> map) throws IntrospectionException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
    		T obj = type.newInstance();
    		for (Entry<String, Object> entry : map.entrySet()) {
    			String key = entry.getKey();
    			Object value = entry.getValue();
    			PropertyDescriptor pd = new PropertyDescriptor(key, type);
    			Method writeMethod = pd.getWriteMethod();
    			if (!writeMethod.isAccessible()) {
    				writeMethod.setAccessible(true);
    			}
    			writeMethod.invoke(obj, value);
    		}
    		return obj;
    	}
    	
    }
    
    

    工具類を修正して、ここでは前を優雅にして、 spring , spring ,
    /**
     * Created by it
     * Created in 2019 3 26 
     * Description:  bean 
     */
    public class PropertyUtils {
    
    	/**
    	 * Map -> bean
    	 */
    	public static <T> T map2Bean(Class<T> type, Map<String, Object> map) {
    		try {
    			AbstractMap2Bean delegate = new DefaultMap2Bean();
    			return delegate.map2Bean(type, map);
    		} catch (Exception e) {
    			throw new RuntimeException(e);
    		}
    	}
    
    	/**
    	 * Map -> bean
    	 */
    	public static <T> T map2Bean2(Class<T> type, Map<String, Object> map) {
    		try {
    			AbstractMap2Bean delegate = new PriorityMap4Map2Bean();
    			return delegate.map2Bean(type, map);
    		} catch (Exception e) {
    			throw new RuntimeException(e);
    		}
    	}
    }
    

    複数の実装クラスの選択に対して、ここでは委任エージェントクラスを導入するために最適化することもできます.
    /**
     * Created by it
     * Created in 2019 3 26 
     * Description:  , 
     */
    public class RouteMap2Bean implements AbstractMap2Bean {
    	
    	private AbstractMap2Bean delegate;
    	
    	public RouteMap2Bean() {
    		this(false);
    	}
    
    	/**
    	 *  
    	 */
    	public RouteMap2Bean(boolean mapPriority) {
    		if (mapPriority) {
    			this.delegate = new PriorityMap4Map2Bean();
    		} else {
    			this.delegate = new DefaultMap2Bean();
    		}
    	}
    
    	@Override
    	public <T> T map2Bean(Class<T> type, Map<String, Object> map) throws Exception {
    		return delegate.map2Bean(type, map);
    	}
    	
    }
    

    修正ツールクラスは次のとおりです.
    /**
     * Created by it
     * Created in 2019 3 26 
     * Description:  bean 
     */
    public class PropertyUtils {
    
    	/**
    	 * Map -> bean
    	 */
    	public static <T> T map2Bean(Class<T> type, Map<String, Object> map) {
    		return map2Bean(type, map, false);
    	}
    	
    	public static <T> T map2Bean(Class<T> type, Map<String, Object> map, boolean mapPriority) {
    		try {
    			AbstractMap2Bean delegate = new RouteMap2Bean(mapPriority);
    			return delegate.map2Bean(type, map);
    		} catch (Exception e) {
    			throw new RuntimeException(e);
    		}
    	}
    }
    

    エレガントなケース2


    デコレーション拡張機能


    装飾者が元のオブジェクトの機能を動的に強化することによって、ファイルの復号化を実現し、復号化を包装オブジェクトにカプセル化し、対外的に包装オブジェクトを提供して復号化し、暗号化の実装
    /**
     * 
     * Created by it
     * Created in 2019 3 31 
     * Description:  
     */
    public class DesEncryptOutputStream extends FilterOutputStream{
    	
    	public DesEncryptOutputStream(OutputStream out) {
    		super(out);
    	}
    	
    	public void encrypt(byte[] buffers) throws IOException {
    		try {
    			String encrypt = AESUtil.encrypt(new String(buffers), Keys.DES);
    			super.write(encrypt.getBytes());
    		} catch (IOException e) {
    			throw new RuntimeException(e);
    		}
    	}
    }
    

    暗号化の実装
    /**
     * 
     * Created by it
     * Created in 2019 3 31 
     * Description:  
     */
    public class DesDecryptptInputStream extends FilterInputStream {
    	
    	protected DesDecryptptInputStream(InputStream in) {
    		super(in);
    	}
    	
    	public byte[] decrypt() {
    		try {
    			//  
    			int size = in.available();
    			byte[] data = new byte[size];
    			super.read(data);
    			//  
    			String decrypt = AESUtil.decrypt(new String(data), Keys.DES);
    			return decrypt.getBytes();
    		} catch (IOException e) {
    			throw new RuntimeException(e);
    		}
    	}
    }
    

    mainテストコード、
    public class Test {
    
    	public static void main(String[] args) throws Exception {
    		String name = " kjkjlk 12345";
    		//  
    		DesEncryptOutputStream outputStream = new DesEncryptOutputStream(new FileOutputStream("1.txt"));
    		outputStream.encrypt(name.getBytes());
    		outputStream.close();
    
    		//  
    		DesDecryptptInputStream inputStream = new DesDecryptptInputStream(new FileInputStream("1.txt"));
    		byte[] decrypt = inputStream.decrypt();
    		System.out.println(new String(decrypt));
    		inputStream.close();
    	}
    
    }
    

    エレガントなケース3


    前に書いたコードをもう一つ挙げます
    優雅なツールクラス実装.TimeUnitの実装を参考にする
    public enum CompressUtil {
    	DEFLATER {
    		Compress compress = new DeflaterCompress();
    
    		public byte[] compress(byte[] data) throws IOException {
    			return compress.compress(data);
    		}
    
    		public byte[] uncompress(byte[] data) throws IOException {
    			return compress.uncompress(data);
    		}
    	},
    	BZIP2 {
    		Compress compress = new LzoCompress();
    
    		public byte[] compress(byte[] data) throws IOException {
    			return compress.compress(data);
    		}
    
    		public byte[] uncompress(byte[] data) throws IOException {
    			return compress.uncompress(data);
    		}
    	},
    	GZIP {
    		Compress compress = new GzipCompress();
    
    		public byte[] compress(byte[] data) throws IOException {
    			return compress.compress(data);
    		}
    
    		public byte[] uncompress(byte[] data) throws IOException {
    			return compress.uncompress(data);
    		}
    	},
    	LZ4 {
    		Compress compress = new Lz4Compress();
    
    		public byte[] compress(byte[] data) throws IOException {
    			return compress.compress(data);
    		}
    
    		public byte[] uncompress(byte[] data) throws IOException {
    			return compress.uncompress(data);
    		}
    	},
    	LZO {
    		Compress compress = new LzoCompress();
    
    		public byte[] compress(byte[] data) throws IOException {
    			return compress.compress(data);
    		}
    
    		public byte[] uncompress(byte[] data) throws IOException {
    			return compress.uncompress(data);
    		}
    	},
    	SNAPPY {
    		Compress compress = new SnappyCompress();
    
    		public byte[] compress(byte[] data) throws IOException {
    			return compress.compress(data);
    		}
    
    		public byte[] uncompress(byte[] data) throws IOException {
    			return compress.uncompress(data);
    		}
    	};
    
    	public byte[] compress(byte[] data) throws IOException {
    		throw new AbstractMethodError();
    	}
    
    	public byte[] uncompress(byte[] data) throws IOException {
    		throw new AbstractMethodError();
    	}
    }
    
    
    

    2つの異なる呼び出しが優雅です
    	CompressUtil.GZIP.compress(bytes);
    	CompressUtil.LZ4.compress(bytes);
    

    JAvaでよく使われる圧縮と解凍の具体的な実現:https://blog.csdn.net/dengjili/article/details/86554012
    続行...