您当前的位置: 首页 > 

java持续实践

暂无认证

  • 2浏览

    0关注

    746博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

设计模式 抽象工厂模式

java持续实践 发布时间:2022-03-16 22:20:44 ,浏览量:2

文章目录
      • 抽象工厂模式介绍
      • 抽象工厂模式的实战
        • 不使用抽象工厂模式的写法
        • 使用抽象工厂模式的写法
          • 定义适配接口
          • 创建不同集群缓存的实现
          • 创建代理类
      • 抽象工厂在Spring中的应用

抽象工厂模式介绍

抽象工厂模式是创建其他工厂的模式. 一个标准(接口)有不同的实现.

抽象工厂模式的实战

案例是采用系统中有不同的缓存服务. 对不同的缓存服务做适配.

不使用抽象工厂模式的写法

创建tutorials-5.0-0 模块 pom中如下




    4.0.0

    org.example
    1.0-SNAPSHOT
    tutorials-5.0-0

    
        
            com.alibaba
            fastjson
            1.2.62
        
        
            junit
            junit
            4.12
            test
        
        
        
            org.slf4j
            slf4j-api
            1.7.5
        
        
            org.slf4j
            jcl-over-slf4j
            1.7.5
        
        
            ch.qos.logback
            logback-classic
            1.0.9
            
                
                    slf4j-api
                    org.slf4j
                
            
        
    

创建一个RedisUtils 缓存工具类, 实现缓存的增删改查功能.

public class RedisUtils {
    private Logger logger = LoggerFactory.getLogger(RedisUtils.class);

    private Map dataMap = new ConcurrentHashMap();

    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);
    }
}

CacheService 缓存服务的接口

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);
}

缓存服务的实现类CacheServiceImpl

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);
    }
}

EGM 类实现EGM的缓存服务

public class EGM {

    private Logger logger = LoggerFactory.getLogger(EGM.class);

    private Map dataMap = new ConcurrentHashMap();

    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);
    }
}

IIR 实现IIR的缓存服务

public class IIR {

    private Logger logger = LoggerFactory.getLogger(IIR.class);

    private Map dataMap = new ConcurrentHashMap();

    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);
    }
}

tutorials-5.0-1 创建改模块, 用于在不使用设计模式时的缓存兼容. pom如下: 引用了tutorials-5.0-0



    
        mydesign-study
        org.example
        1.0-SNAPSHOT
    
    4.0.0

    tutorials-5.0-1


    
        
            com.alibaba
            fastjson
            1.2.62
        
        
            junit
            junit
            4.12
            test
        
        
            org.slf4j
            slf4j-api
            1.7.5
        
        
            org.slf4j
            jcl-over-slf4j
            1.7.5
        
        
            ch.qos.logback
            logback-classic
            1.0.9
            
                
                    slf4j-api
                    org.slf4j
                
            
        

        
            org.example
            1.0-SNAPSHOT
            tutorials-5.0-0
        
    

创建CacheService接口

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);
}

创建CacheServiceImpl 类如下 , 用if else去判断不同的实现缓存

package com.thc.design.cuisine.impl;

import com.thc.design.CacheService;
import com.thc.design.RedisUtils;
import com.thc.design.matter.EGM;
import com.thc.design.matter.IIR;

import java.util.concurrent.TimeUnit;

/**
 * 类名称:CacheServiceImpl
 * @author: taohongchao
 * 创建时间:2022/3/16 10:33
 */
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);
        }

    }

    public void set(String key, String value, long timeout, TimeUnit timeUnit, int redisType) {
        if (1 == redisType) {
            egm.setEx(key, value, timeout, timeUnit);
        }

        if (2 == redisType) {
            iir.setExpire(key, value, timeout, timeUnit);
        }
        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);
    }
}

创建测试类ApiTest

public class ApiTest {
    @Test
    public void test_cacheService() {
        CacheService cacheService = new CacheServiceImpl();
        cacheService.set("user_name1", "周杰伦", 1);

        String value = cacheService.get("user_name1", 1);
        System.out.println("测试结果: "+ value);

        cacheService.set("user_name2", "周润发", 2);
        String value2 = cacheService.get("user_name2", 2);
        System.out.println("测试结果: "+ value2);
    }
}

控制台打印如下

21:52:10.966 [main] INFO com.thc.design.matter.EGM - EGM 写入数据 key: user_name1 , val : 周杰伦 21:52:10.968 [main] INFO com.thc.design.matter.EGM - EGM获取数据 key: user_name1 测试结果: 周杰伦 21:52:10.969 [main] INFO com.thc.design.matter.IIR - IIR写入数据 key:user_name2 val:周润发 21:52:10.969 [main] INFO com.thc.design.matter.IIR - IIR获取数据 key: user_name2 测试结果: 周润发

可以看到通过传递type 不同, 实现了走不同的缓存 .

使用抽象工厂模式的写法 定义适配接口

ICacheAdapter

public interface ICacheAdapter {
    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);
}
创建不同集群缓存的实现

EGMCacheAdapter

import java.util.concurrent.TimeUnit;

/**
 * 类名称:EGMCacheAdapter
 * 类描述: egm 缓存适配器
 * @author: https://javaweixin6.blog.csdn.net/
 * 创建时间:2022/3/16 20:49
 */
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);
    }
}

IIRCacheAdapter

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);
    }
}
创建代理类
public class JDKProxy {
    // jdk动态代理 通过类加载器获取类
    public static  T getProxy(Class interfaceClass, ICacheAdapter cacheAdapter) {
        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 com.thc.design.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 primitiveSet = new HashSet();

    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    对象具体类
     * @return 对象实例
     * @throws Exception 没有找到方法,或者无法处理,或者初始化方法异常等
     */
    public static  T newInstance(Class 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 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             
关注
打赏
1658054974
查看更多评论
0.0912s