栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

设计模式 抽象工厂模式

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

设计模式 抽象工厂模式

文章目录

抽象工厂模式介绍抽象工厂模式的实战

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

定义适配接口创建不同集群缓存的实现创建代理类 抽象工厂在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;


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;


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

    
    public static ClassLoader getCurrentClassLoader() {
        ClassLoader cl = Thread.currentThread().getContextClassLoader();
        if (cl == null) {
            cl = ClassLoaderUtils.class.getClassLoader();
        }
        return cl == null ? ClassLoader.getSystemClassLoader() : cl;
    }

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

    
    public static Class forName(String className)
            throws ClassNotFoundException {
        return forName(className, true);
    }

    
    public static Class forName(String className, boolean initialize)
            throws ClassNotFoundException {
        return Class.forName(className, initialize, getCurrentClassLoader());
    }

    
    public static Class forName(String className, ClassLoader cl)
            throws ClassNotFoundException {
        return Class.forName(className, true, cl);
    }

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

创建JDKInvocationHandler 反射执行方法

package com.thc.design.factory;

import com.thc.design.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);
    }
}

创建CacheServiceImpl

import com.thc.design.CacheService;
import com.thc.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);
    }
}

创建测试类

import com.thc.design.factory.JDKProxy;
import com.thc.design.factory.impl.EGMCacheAdapter;
import com.thc.design.factory.impl.IIRCacheAdapter;
import com.thc.design.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_02", "苏有朋");
        String val02 = proxy_IIR.get("user_name_02");
        System.out.println("测试结果: "+val02);
    }
}

控制台打印如下 :

22:02:30.050 [main] INFO com.thc.design.matter.EGM - EGM 写入数据 key: user_name_01 , val : 林俊杰
22:02:30.054 [main] INFO com.thc.design.matter.EGM - EGM获取数据 key: user_name_01
测试结果: 林俊杰
22:02:30.055 [main] INFO com.thc.design.matter.IIR - IIR写入数据 key:user_name_02 val:苏有朋
22:02:30.055 [main] INFO com.thc.design.matter.IIR - IIR获取数据 key: user_name_02
测试结果: 苏有朋

成功通过动态代理和抽象工厂模式实现了对不同缓存的使用.

抽象工厂在Spring中的应用

Spring中的BeanFactory是一个顶级的抽象工厂.
其底层实现类中, 有两个类是在学习Spring中所熟悉的.
FileSystemXmlApplicationContext 和 ClassPathXmlApplicationContext
两种不同的方式(从文件系统中加载配置和从类路径中加载配置.)
目的都是为了加载bean的配置.
其抽象是 AbstractXmlApplicationContext

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/770136.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号