Java —— 泛型&抽象工厂的设想

问题

增加对象类型需要增加对应工厂类。同时要将相应的工厂类设置到需要生成对象的模块中。强类型绑定增加过多的类似代码。

目标

使用泛型抽象要生成的对象,使用抽象工厂,动态化设定工厂类型。

实现
  • 默认类型
// 一个简单的消息对象,内部类设计并不友好
public class DefaultPacket {
    private static DefaultPacket dp = new DefaultPacket();

    private int cmd;
    private Content content;
    private String seq;

    private DefaultPacket() {
        this.seq = UUID.randomUUID().toString();
    }

    public DefaultPacket(int cmd, Content content) {
        this();
        this.cmd = cmd;
        this.content = content;
    }

    public int getCmd() {
        return cmd;
    }

    public void setCmd(int cmd) {
        this.cmd = cmd;
    }

    public Content getContent() {
        return content;
    }

    public void setContent(Content content) {
        this.content = content;
    }

    public String getSeq() {
        return seq;
    }

    public void setSeq(String seq) {
        this.seq = seq;
    }

    @Override
    public String toString() {
        return this.getClass().getName() + " [cmd=" + cmd + ", content=" + content + ", seq=" + seq + "]";
    }

    public static Content newContent(String msg, int status, int result, String desc) {
        return dp.new Content(msg, status, result, desc);
    }

    public class Content {
        private String msg;
        private int status;
        private int result;
        private String desc;

        public Content(String msg, int status, int result, String desc) {
            super();
            this.msg = msg;
            this.status = status;
            this.result = result;
            this.desc = desc;
        }

        public String getMsg() {
            return msg;
        }

        public void setMsg(String msg) {
            this.msg = msg;
        }

        public int getStatus() {
            return status;
        }

        public void setStatus(int status) {
            this.status = status;
        }

        public int getResult() {
            return result;
        }

        public void setResult(int result) {
            this.result = result;
        }

        public String getDesc() {
            return desc;
        }

        public void setDesc(String desc) {
            this.desc = desc;
        }

        @Override
        public String toString() {
            return "Content [msg=" + msg + ", status=" + status + ", result=" + result + ", desc=" + desc + "]";
        }
    }

}
  • 带着点抽风的工厂类
public abstract class PacketFactory {
    private static Map<String, PacketFactory> factorys;

    // 私有构造方法,不允许直接生成对象
    private PacketFactory() {
    }

    /**
     * 构造工厂实体
     * @param clazz 用于生成目标的对象类型
     * @return Factory build packet with clazz type
     */
    public static PacketFactory getFactory(Class<? extends DefaultPacket> clazz) {
        if (factorys == null) {
            factorys = new HashMap<>();
        }


        String name = clazz.getName();
        PacketFactory factory;
        // 力所能及的加个缓存
        if ((factory = factorys.get(name)) == null) {
            factory = new PacketFactory() {
                @SuppressWarnings("unchecked")
                @Override
                public <T extends DefaultPacket> T getPacket(int cmd, Content content) {
                    DefaultPacket packet = null;
                    Constructor<? extends DefaultPacket> constructor = null;
                    try {
                        constructor = clazz.getConstructor(int.class, Content.class);
                        packet = constructor.newInstance(cmd, content);
                    } catch (Exception e) {
                        e.printStackTrace();
                        throw new RuntimeException(
                                String.format("%s构造方法不符合约定参数列表(int cmd,Content content)", clazz.getName()));
                    }
                    return (T) packet;
                }
            };
            factorys.put(name, factory);
        }
        return factory;
    }

    /**
     *  直接获得生成默认类型的工厂
     * @return PacketFactory with defaultPacket
     */
    public static PacketFactory getFactory() {
        return getFactory(DefaultPacket.class);
    }

    /**
     * 获得消息对象
     * @param cmd
     * @param content
     * @return
     */
    public abstract <T extends DefaultPacket> T getPacket(int cmd, Content content);
}
参考

mybatis中泛型在内部进行强制类型转换。
以抽象类直接获得对象实例。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值