软件设计模式-创建型模式之工厂进阶版

本文探讨了工厂模式在Java中的应用,特别是通过万能工厂类实现对象的动态实例化,利用反射技术和重载方法支持有参和无参构造。然而,这种方式存在一个缺点,即在运行时才能检查参数类型是否匹配构造方法,导致编译时无法发现问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

简介: 所谓工厂模式,创建一个对象的接口,让子类决定实例化哪一个工厂类,使其创建过程延迟到了子类。
所谓的万能工厂类,通过反射调用的方式,获取到子类对象,并实例化返回,此外本案例还通过重载的方式,允许了有参和无参两种获取到实例的方式。

  /**
 * @author: demo
 * @date: 2021/8/7
 * @describe:
 */
public class MyFactory {
    /**
     * 构造器私有化
     */
    private MyFactory() {
    }

    /**
     * 获得实例
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> T getInstance(Class<T> clazz) {
        T instance = null;
        try {
            instance = clazz.getDeclaredConstructor().newInstance();
        } catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
            e.printStackTrace();
        }
        return instance;
    }

    /**
     * 重载,获得实例
     * @param clazz
     * @param obj
     * @param <T>
     * @return
     */
    public static <T> T getInstance(Class<T> clazz, Object... obj) {
        T instance = null;
        Class[] c = new Class[obj.length];
        Object[] o = new Object[obj.length];
        try {
            for (int i = 0; i < obj.length; i++) {
                c[i] = getType(obj[i]);
                o[i] = obj[i];
            }
            instance = clazz.getDeclaredConstructor(c).newInstance(o);
        } catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException | NullPointerException e) {
            e.printStackTrace();
        }
        return instance;
    }

    /**
     * 防止集合的匿名内部类赋值返回直接父类的class对象,造成找不到对应方法异常
     * @param obj
     * @return
     */
    private static Class getType(Object obj) {
        if (obj instanceof Map) {
            return Map.class;
        } else if (obj instanceof List) {
            return List.class;
        } else if (obj instanceof Set) {
            return Set.class;
        } else {
            return obj.getClass();
        }
    }
}

测试代码:

  /**
 * 使用了Lombok插件快速生成代码
 * @author: demo
 * @date: 2021/8/7
 * @describe:
 */
@Data
public class Person {
    private String name;
    private Map<String, List> map;

    public Person() {
    }

    public Person(String name) {
        this.name = name;
    }

    public Person(String name, Map<String, List> map) {
        this.name = name;
        this.map = map;
    }

    public static void main(String[] args) {
        Person person = MyFactory.getInstance(Person.class, "a", new HashMap<String, List>() {
            {
                put("a", new ArrayList() {
                    {
                        add("aaaaa");
                    }
                });
            }
        });
        System.out.println(person.toString());
    }
}

测试结果:
image

但是,利用反射进行传参进行有参构造的实例化固好,但有一个无法避免的问题,即无法在编译期间发现参数类型是否与构造方法的类型相匹配。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

红烧土豆泥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值