利用Java反射机制优化简单工厂设计模式

之前项目有个需求,审批流程的时候要根据配置发送信息:发送短信、发送邮件。当时看到这个就想到要用工厂模式,为什么要用工厂模式呢?用工厂模式进行大型项目的开发,可以很好的进行项目并行开发。就是一个程序员和另一个程序员可以同时去书写代码,而不是一个程序员等到另一个程序员写完以后再去书写代码。其中的粘合剂就是接口和配置文件。

通过简单的工厂设计模式可以达到类的 解耦合目的,但是之前的工厂设计模式依然存在问题,那就是在增加一个子类时都需要修改工厂类,这样很麻烦。现在就可以通过反射机制修改工厂类,这样肯定会 非常麻烦。学习完反射机制之后,实际上,此时就可以通过反射机制来改善工厂类,让其在增加子类时可以不用做任何的修改,就能达到功能的扩充,如下:

/**
 * 
 */
package com.factoryTest;

import java.util.Date;
import java.util.List;

/**
 * 
 * 描述:邮件短信消息记录
 * @author 小当家
 * @created 2018年1月11日 
 */
public class MessageDTO implements java.io.Serializable{
    
    /**
     * serialVersionUID : long.
     */
    private static final long serialVersionUID = -1985834353259521222L;
    
    /**
     * 消息ID
     */
    private Long messageId;
    
    /**
     * 需要发送短信的手机号码,多个用,隔开
     */
    private String smsPhone;
    
    /**
     * 需要发送短信的短信内容
     */
    private String content;
    
    /**
     * 邮件收件人
     */
    private String mailRecipient;
    
    /**
     * 邮件标题
     */
    private String mailSubject;
    
    /**
     * 邮件抄送人
     */
    private String messageCC;
    
    /**
     * 邮件附件ID
     */
    private Long attachId;
    
    /**
     * 消息发送时间
     */
    private Date sendDate;
    
    /**
     * 消息发送用于什么模块
     */
    private String module;
    
    /**
     * 发送状态,1:发送成功   0:发送失败
     */
    private String sendStatus;
    
    /**
     * 发送消息类型:00000000->不发送 、00000001->短信、00000010->邮件、00000100->系统、00000011->短信和邮件以此类推
     */
    private String sendType;
    
    /**
     * 发送用户
     */
    private String userCode;
    
    /**
     * 接收用户,多用户可用逗号隔开
     */
    private String recipientCode;
    
    /**
     * 备注
     */
    private String note;
    
    /**
     * 附件名称
     */
    private String attachmentName;
    
    /**
     * 附件地址
     */
    private String attachPath;
    
    
    private List<Long> attachIds;
    
  get set ...

}

定义一个发送邮件的接口

/*
 *
 */
package com.factoryTest;

/**
 * 描述:发送信息基础类
 * @author 小当家
 * @created 2018年1月11日 
 */
public interface SendTypeBase {
    /**
     * 
     * 描述
     * @author 小当家
     * @created 2018年1月11日 
     */
    public void sendMessage(MessageDTO dto);
}

写一个发送邮件的类实现接口

/*
 *
 */
package com.factoryTest;

/**
 * 描述:发送邮件
 * @author 小当家
 * @created 2018年1月11日 
 */
public class SendMail implements SendTypeBase{

    @Override
    public void sendMessage(MessageDTO dto) {
        System.out.println(dto.getUserCode()+"发送邮件");
        
    }

}

实现一个发送短信的类实现接口

/*
 *
 */
package com.factoryTest;

/**
 * 描述:发送短信
 * @author 小当家
 * @created 2018年1月11日 
 */
public class SendSms implements SendTypeBase{

    @Override
    public void sendMessage(MessageDTO dto) {
        System.out.println(dto.getUserCode()+"发送短信");
        
    }

}

 

注意:

对比下简单工厂,如:

/*
 *
 */
package com.factoryTest;

/**
 * 描述
 * @author 小当家
 * @created 2018年1月11日 下午4:25:27
 */
public class SimpleFactory {
    public SendTypeBase SendMessage(String type) {
        if("sms".equals(type)) {
            return new SendSms();
        }else {
            return new SendMail();
        }
    }
}

 

下面是通过反射实现的工厂类

 

/*
 *
 */
package com.factoryTest;

import java.lang.reflect.Constructor;
import java.util.HashMap;
import java.util.Map;

/**
 * 描述:发送信息工厂类
 * @author 小当家
 * @created 2018年1月11日 
 */
public class SendMessageFactory {

    private final static Map<String, String> MESSAGE_MAP = new HashMap<String, String>();
    static {
        //短信
        MESSAGE_MAP.put("SMS", "com.factoryTest.SendSms");
        //邮件
        MESSAGE_MAP.put("EMAIL", "com.factoryTest.SendMail");
    
    }
    
    @SuppressWarnings("rawtypes")
    public static SendTypeBase createClass(String type) throws Exception {
        if(MESSAGE_MAP.get(type) == null) {
            throw new Exception("未配置发送信息类型");
        }
        Class classType = Class.forName(MESSAGE_MAP.get(type)); 
        @SuppressWarnings("unchecked")
        Constructor constructor = classType.getDeclaredConstructor();
        return (SendTypeBase) constructor.newInstance();
    }
}

 

这里类型其实可以通过配置文件来处理,这样增加一个子类,就不需要改工厂类了。

 

posted @ 2018-01-12 15:20  程序小当家  阅读(468)  评论(0编辑  收藏  举报