提交 efe56256 编写于 作者: 小傅哥's avatar 小傅哥

小傅哥 | 重学 Java 设计模式:实战抽象工厂模式

上级 74616939
/itstack-demo-design-1-00/itstack-demo-design-1-00.iml
/itstack-demo-design-1-01/itstack-demo-design-1-01.iml
/itstack-demo-design-1-02/itstack-demo-design-1-02.iml
/itstack-demo-design-2-00/itstack-demo-design-2-00.iml
/itstack-demo-design-2-02/itstack-demo-design-2-02.iml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>itstack-demo-design</artifactId>
<groupId>org.itstack</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>itstack-demo-design-2-00</artifactId>
</project>
\ No newline at end of file
package org.itstack.demo.design;
import java.util.concurrent.TimeUnit;
public interface CacheService {
String get(final String key);
void set(String key, String value);
void set(String key, String value, long timeout, TimeUnit timeUnit);
void del(String key);
}
package org.itstack.demo.design;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
public class RedisUtils {
private Logger logger = LoggerFactory.getLogger(RedisUtils.class);
private Map<String, String> dataMap = new ConcurrentHashMap<String, String>();
public String get(String key) {
logger.info("Redis获取数据 key:{}", key);
return dataMap.get(key);
}
public void set(String key, String value) {
logger.info("Redis写入数据 key:{} val:{}", key, value);
dataMap.put(key, value);
}
public void set(String key, String value, long timeout, TimeUnit timeUnit) {
logger.info("Redis写入数据 key:{} val:{} timeout:{} timeUnit:{}", key, value, timeout, timeUnit.toString());
dataMap.put(key, value);
}
public void del(String key) {
logger.info("Redis删除数据 key:{}", key);
dataMap.remove(key);
}
}
package org.itstack.demo.design.impl;
import org.itstack.demo.design.CacheService;
import org.itstack.demo.design.RedisUtils;
import java.util.concurrent.TimeUnit;
public class CacheServiceImpl implements CacheService {
private RedisUtils redisUtils = new RedisUtils();
public String get(String key) {
return redisUtils.get(key);
}
public void set(String key, String value) {
redisUtils.set(key, value);
}
public void set(String key, String value, long timeout, TimeUnit timeUnit) {
redisUtils.set(key, value, timeout, timeUnit);
}
public void del(String key) {
redisUtils.del(key);
}
}
package org.itstack.demo.design.matter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
public class EGM {
private Logger logger = LoggerFactory.getLogger(EGM.class);
private Map<String, String> dataMap = new ConcurrentHashMap<String, String>();
public String gain(String key) {
logger.info("EGM获取数据 key:{}", key);
return dataMap.get(key);
}
public void set(String key, String value) {
logger.info("EGM写入数据 key:{} val:{}", key, value);
dataMap.put(key, value);
}
public void setEx(String key, String value, long timeout, TimeUnit timeUnit) {
logger.info("EGM写入数据 key:{} val:{} timeout:{} timeUnit:{}", key, value, timeout, timeUnit.toString());
dataMap.put(key, value);
}
public void delete(String key) {
logger.info("EGM删除数据 key:{}", key);
dataMap.remove(key);
}
}
package org.itstack.demo.design.matter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
public class IIR {
private Logger logger = LoggerFactory.getLogger(IIR.class);
private Map<String, String> dataMap = new ConcurrentHashMap<String, String>();
public String get(String key) {
logger.info("IIR获取数据 key:{}", key);
return dataMap.get(key);
}
public void set(String key, String value) {
logger.info("IIR写入数据 key:{} val:{}", key, value);
dataMap.put(key, value);
}
public void setExpire(String key, String value, long timeout, TimeUnit timeUnit) {
logger.info("IIR写入数据 key:{} val:{} timeout:{} timeUnit:{}", key, value, timeout, timeUnit.toString());
dataMap.put(key, value);
}
public void del(String key) {
logger.info("IIR删除数据 key:{}", key);
dataMap.remove(key);
}
}
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>itstack-demo-design</artifactId>
<groupId>org.itstack</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>itstack-demo-design-2-01</artifactId>
<dependencies>
<dependency>
<groupId>org.itstack</groupId>
<artifactId>itstack-demo-design-2-00</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
package org.itstack.demo.design;
import java.util.concurrent.TimeUnit;
public interface CacheService {
String get(final String key, int redisType);
void set(String key, String value, int redisType);
void set(String key, String value, long timeout, TimeUnit timeUnit, int redisType);
void del(String key, int redisType);
}
package org.itstack.demo.design.impl;
import org.itstack.demo.design.RedisUtils;
import org.itstack.demo.design.matter.EGM;
import org.itstack.demo.design.matter.IIR;
import org.itstack.demo.design.CacheService;
import java.util.concurrent.TimeUnit;
public class CacheServiceImpl implements CacheService {
private RedisUtils redisUtils = new RedisUtils();
private EGM egm = new EGM();
private IIR iir = new IIR();
public String get(String key, int redisType) {
if (1 == redisType) {
return egm.gain(key);
}
if (2 == redisType) {
return iir.get(key);
}
return redisUtils.get(key);
}
public void set(String key, String value, int redisType) {
if (1 == redisType) {
egm.set(key, value);
return;
}
if (2 == redisType) {
iir.set(key, value);
return;
}
redisUtils.set(key, value);
}
public void set(String key, String value, long timeout, TimeUnit timeUnit, int redisType) {
if (1 == redisType) {
egm.setEx(key, value, timeout, timeUnit);
return;
}
if (2 == redisType) {
iir.setExpire(key, value, timeout, timeUnit);
return;
}
redisUtils.set(key, value, timeout, timeUnit);
}
public void del(String key, int redisType) {
if (1 == redisType) {
egm.delete(key);
return;
}
if (2 == redisType) {
iir.del(key);
return;
}
redisUtils.del(key);
}
}
package org.itstack.demo.design.test;
import org.itstack.demo.design.CacheService;
import org.itstack.demo.design.impl.CacheServiceImpl;
import org.junit.Test;
public class ApiTest {
@Test
public void test_CacheService() {
CacheService cacheService = new CacheServiceImpl();
cacheService.set("user_name_01", "小傅哥", 1);
String val01 = cacheService.get("user_name_01", 1);
System.out.println("测试结果:" + val01);
}
}
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>itstack-demo-design</artifactId>
<groupId>org.itstack</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>itstack-demo-design-2-02</artifactId>
<dependencies>
<dependency>
<groupId>org.itstack</groupId>
<artifactId>itstack-demo-design-2-00</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
package org.itstack.demo.desgin;
import java.util.concurrent.TimeUnit;
public interface CacheService {
String get(final String key);
void set(String key, String value);
void set(String key, String value, long timeout, TimeUnit timeUnit);
void del(String key);
}
package org.itstack.demo.desgin.factory;
import java.util.concurrent.TimeUnit;
public interface ICacheAdapter {
String get(String key);
void set(String key, String value);
void set(String key, String value, long timeout, TimeUnit timeUnit);
void del(String key);
}
package org.itstack.demo.desgin.factory;
import org.itstack.demo.desgin.util.ClassLoaderUtils;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class JDKInvocationHandler implements InvocationHandler {
private ICacheAdapter cacheAdapter;
public JDKInvocationHandler(ICacheAdapter cacheAdapter) {
this.cacheAdapter = cacheAdapter;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
return ICacheAdapter.class.getMethod(method.getName(), ClassLoaderUtils.getClazzByArgs(args)).invoke(cacheAdapter, args);
}
}
package org.itstack.demo.desgin.factory;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
public class JDKProxy {
public static <T> T getProxy(Class<T> interfaceClass, ICacheAdapter cacheAdapter) throws Exception {
InvocationHandler handler = new JDKInvocationHandler(cacheAdapter);
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
Class<?>[] classes = interfaceClass.getInterfaces();
return (T) Proxy.newProxyInstance(classLoader, new Class[]{classes[0]}, handler);
}
}
package org.itstack.demo.desgin.factory.impl;
import org.itstack.demo.desgin.factory.ICacheAdapter;
import org.itstack.demo.design.matter.EGM;
import java.util.concurrent.TimeUnit;
public class EGMCacheAdapter implements ICacheAdapter {
private EGM egm = new EGM();
public String get(String key) {
return egm.gain(key);
}
public void set(String key, String value) {
egm.set(key, value);
}
public void set(String key, String value, long timeout, TimeUnit timeUnit) {
egm.setEx(key, value, timeout, timeUnit);
}
public void del(String key) {
egm.delete(key);
}
}
package org.itstack.demo.desgin.factory.impl;
import org.itstack.demo.desgin.factory.ICacheAdapter;
import org.itstack.demo.design.matter.IIR;
import java.util.concurrent.TimeUnit;
public class IIRCacheAdapter implements ICacheAdapter {
private IIR iir = new IIR();
public String get(String key) {
return iir.get(key);
}
public void set(String key, String value) {
iir.set(key, value);
}
public void set(String key, String value, long timeout, TimeUnit timeUnit) {
iir.setExpire(key, value, timeout, timeUnit);
}
public void del(String key) {
iir.del(key);
}
}
package org.itstack.demo.desgin.impl;
import org.itstack.demo.desgin.CacheService;
import org.itstack.demo.design.RedisUtils;
import java.util.concurrent.TimeUnit;
public class CacheServiceImpl implements CacheService {
private RedisUtils redisUtils = new RedisUtils();
public String get(String key) {
return redisUtils.get(key);
}
public void set(String key, String value) {
redisUtils.set(key, value);
}
public void set(String key, String value, long timeout, TimeUnit timeUnit) {
redisUtils.set(key, value, timeout, timeUnit);
}
public void del(String key) {
redisUtils.del(key);
}
}
package org.itstack.demo.desgin.util;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.*;
import java.util.concurrent.TimeUnit;
public class ClassLoaderUtils {
private static Set<Class> primitiveSet = new HashSet<Class>();
static {
primitiveSet.add(Integer.class);
primitiveSet.add(Long.class);
primitiveSet.add(Float.class);
primitiveSet.add(Byte.class);
primitiveSet.add(Short.class);
primitiveSet.add(Double.class);
primitiveSet.add(Character.class);
primitiveSet.add(Boolean.class);
}
/**
* 得到当前ClassLoader
*
* @return ClassLoader
*/
public static ClassLoader getCurrentClassLoader() {
ClassLoader cl = Thread.currentThread().getContextClassLoader();
if (cl == null) {
cl = ClassLoaderUtils.class.getClassLoader();
}
return cl == null ? ClassLoader.getSystemClassLoader() : cl;
}
/**
* 得到当前ClassLoader
*
* @param clazz 某个类
* @return ClassLoader
*/
public static ClassLoader getClassLoader(Class<?> clazz) {
ClassLoader loader = Thread.currentThread().getContextClassLoader();
if (loader != null) {
return loader;
}
if (clazz != null) {
loader = clazz.getClassLoader();
if (loader != null) {
return loader;
}
return clazz.getClassLoader();
}
return ClassLoader.getSystemClassLoader();
}
/**
* 根据类名加载Class
*
* @param className 类名
* @return Class
* @throws ClassNotFoundException 找不到类
*/
public static Class forName(String className)
throws ClassNotFoundException {
return forName(className, true);
}
/**
* 根据类名加载Class
*
* @param className 类名
* @param initialize 是否初始化
* @return Class
* @throws ClassNotFoundException 找不到类
*/
public static Class forName(String className, boolean initialize)
throws ClassNotFoundException {
return Class.forName(className, initialize, getCurrentClassLoader());
}
/**
* 根据类名加载Class
*
* @param className 类名
* @param cl Classloader
* @return Class
* @throws ClassNotFoundException 找不到类
*/
public static Class forName(String className, ClassLoader cl)
throws ClassNotFoundException {
return Class.forName(className, true, cl);
}
/**
* 实例化一个对象(只检测默认构造函数,其它不管)
*
* @param clazz 对象类
* @param <T> 对象具体类
* @return 对象实例
* @throws Exception 没有找到方法,或者无法处理,或者初始化方法异常等
*/
public static <T> T newInstance(Class<T> clazz) throws Exception {
if (primitiveSet.contains(clazz)) {
return null;
}
if (clazz.isMemberClass() && !Modifier.isStatic(clazz.getModifiers())) {
Constructor constructorList[] = clazz.getDeclaredConstructors();
Constructor defaultConstructor = null;
for (Constructor con : constructorList) {
if (con.getParameterTypes().length == 1) {
defaultConstructor = con;
break;
}
}
if (defaultConstructor != null) {
if (defaultConstructor.isAccessible()) {
return (T) defaultConstructor.newInstance(new Object[]{null});
} else {
try {
defaultConstructor.setAccessible(true);
return (T) defaultConstructor.newInstance(new Object[]{null});
} finally {
defaultConstructor.setAccessible(false);
}
}
} else {
throw new Exception("The " + clazz.getCanonicalName() + " has no default constructor!");
}
}
try {
return clazz.newInstance();
} catch (Exception e) {
Constructor<T> constructor = clazz.getDeclaredConstructor();
if (constructor.isAccessible()) {
throw new Exception("The " + clazz.getCanonicalName() + " has no default constructor!", e);
} else {
try {
constructor.setAccessible(true);
return constructor.newInstance();
} finally {
constructor.setAccessible(false);
}
}
}
}
public static Class<?>[] getClazzByArgs(Object[] args) {
Class<?>[] parameterTypes = new Class[args.length];
for (int i = 0; i < args.length; i++) {
if (args[i] instanceof ArrayList) {
parameterTypes[i] = List.class;
continue;
}
if (args[i] instanceof LinkedList) {
parameterTypes[i] = List.class;
continue;
}
if (args[i] instanceof HashMap) {
parameterTypes[i] = Map.class;
continue;
}
if (args[i] instanceof Long){
parameterTypes[i] = long.class;
continue;
}
if (args[i] instanceof Double){
parameterTypes[i] = double.class;
continue;
}
if (args[i] instanceof TimeUnit){
parameterTypes[i] = TimeUnit.class;
continue;
}
parameterTypes[i] = args[i].getClass();
}
return parameterTypes;
}
public Method getMethod(Class<?> classType, String methodName, Class<?>... parameterTypes) throws NoSuchMethodException {
return classType.getMethod(methodName, parameterTypes);
}
}
package org.itstack.demo.desgin.test;
import org.itstack.demo.desgin.CacheService;
import org.itstack.demo.desgin.factory.JDKProxy;
import org.itstack.demo.desgin.factory.impl.EGMCacheAdapter;
import org.itstack.demo.desgin.factory.impl.IIRCacheAdapter;
import org.itstack.demo.desgin.impl.CacheServiceImpl;
import org.junit.Test;
public class ApiTest {
@Test
public void test_CacheService() throws Exception {
CacheService proxy_EGM = JDKProxy.getProxy(CacheServiceImpl.class, new EGMCacheAdapter());
proxy_EGM.set("user_name_01", "小傅哥");
String val01 = proxy_EGM.get("user_name_01");
System.out.println("测试结果:" + val01);
CacheService proxy_IIR = JDKProxy.getProxy(CacheServiceImpl.class, new IIRCacheAdapter());
proxy_IIR.set("user_name_01", "小傅哥");
String val02 = proxy_IIR.get("user_name_01");
System.out.println("测试结果:" + val02);
}
}
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.itstack</groupId>
<artifactId>itstack-demo-design</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<modules>
<module>itstack-demo-design-1-01</module>
<module>itstack-demo-design-1-00</module>
<module>itstack-demo-design-1-02</module>
<module>itstack-demo-design-2-00</module>
<module>itstack-demo-design-2-01</module>
<module>itstack-demo-design-2-02</module>
</modules>
<dependencies>
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.68</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- LOGGING begin -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.5</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>1.7.5</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.0.9</version>
<exclusions>
<exclusion>
<artifactId>slf4j-api</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</project>
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册