エレガントな解決ツールクラス設計
82154 ワード
目次
エレガントなケース1
問題思考:設計ツールクラスを考えるとき、ほとんどの場合、私はクラスに関連し、静的メソッドを定義し、この静的メソッドを呼び出して多重化することに慣れています.大体次のようになります.
例:タイプ変換ツールクラス、beanとmapの変換、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
続行...