之前项目有个需求,审批流程的时候要根据配置发送信息:发送短信、发送邮件。当时看到这个就想到要用工厂模式,为什么要用工厂模式呢?用工厂模式进行大型项目的开发,可以很好的进行项目并行开发。就是一个程序员和另一个程序员可以同时去书写代码,而不是一个程序员等到另一个程序员写完以后再去书写代码。其中的粘合剂就是接口和配置文件。
通过简单的工厂设计模式可以达到类的 解耦合目的,但是之前的工厂设计模式依然存在问题,那就是在增加一个子类时都需要修改工厂类,这样很麻烦。现在就可以通过反射机制修改工厂类,这样肯定会 非常麻烦。学习完反射机制之后,实际上,此时就可以通过反射机制来改善工厂类,让其在增加子类时可以不用做任何的修改,就能达到功能的扩充,如下:
/****/
packagecom.factoryTest;importjava.util.Date;importjava.util.List;/***
* 描述:邮件短信消息记录
*@author小当家
* @created 2018年1月11日*/
public class MessageDTO implementsjava.io.Serializable{/*** serialVersionUID : long.*/
private static final long serialVersionUID = -1985834353259521222L;/*** 消息ID*/
privateLong messageId;/*** 需要发送短信的手机号码,多个用,隔开*/
privateString smsPhone;/*** 需要发送短信的短信内容*/
privateString content;/*** 邮件收件人*/
privateString mailRecipient;/*** 邮件标题*/
privateString mailSubject;/*** 邮件抄送人*/
privateString messageCC;/*** 邮件附件ID*/
privateLong attachId;/*** 消息发送时间*/
privateDate sendDate;/*** 消息发送用于什么模块*/
privateString module;/*** 发送状态,1:发送成功 0:发送失败*/
privateString sendStatus;/*** 发送消息类型:00000000->不发送 、00000001->短信、00000010->邮件、00000100->系统、00000011->短信和邮件以此类推*/
privateString sendType;/*** 发送用户*/
privateString userCode;/*** 接收用户,多用户可用逗号隔开*/
privateString recipientCode;/*** 备注*/
privateString note;/*** 附件名称*/
privateString attachmentName;/*** 附件地址*/
privateString attachPath;private ListattachIds;
get set ...}
定义一个发送邮件的接口
/***/
packagecom.factoryTest;/*** 描述:发送信息基础类
*@author小当家
* @created 2018年1月11日*/
public interfaceSendTypeBase {/***
* 描述
*@author小当家
* @created 2018年1月11日*/
public voidsendMessage(MessageDTO dto);
}
写一个发送邮件的类实现接口
/***/
packagecom.factoryTest;/*** 描述:发送邮件
*@author小当家
* @created 2018年1月11日*/
public class SendMail implementsSendTypeBase{
@Overridepublic voidsendMessage(MessageDTO dto) {
System.out.println(dto.getUserCode()+"发送邮件");
}
}
实现一个发送短信的类实现接口
/***/
packagecom.factoryTest;/*** 描述:发送短信
*@author小当家
* @created 2018年1月11日*/
public class SendSms implementsSendTypeBase{
@Overridepublic voidsendMessage(MessageDTO dto) {
System.out.println(dto.getUserCode()+"发送短信");
}
}
注意:
对比下简单工厂,如:
/***/
packagecom.factoryTest;/*** 描述
*@author小当家
* @created 2018年1月11日 下午4:25:27*/
public classSimpleFactory {publicSendTypeBase SendMessage(String type) {if("sms".equals(type)) {return newSendSms();
}else{return newSendMail();
}
}
}
下面是通过反射实现的工厂类
/***/
packagecom.factoryTest;importjava.lang.reflect.Constructor;importjava.util.HashMap;importjava.util.Map;/*** 描述:发送信息工厂类
*@author小当家
* @created 2018年1月11日*/
public classSendMessageFactory {private final static Map MESSAGE_MAP = new HashMap();static{//短信
MESSAGE_MAP.put("SMS", "com.factoryTest.SendSms");//邮件
MESSAGE_MAP.put("EMAIL", "com.factoryTest.SendMail");
}
@SuppressWarnings("rawtypes")public static SendTypeBase createClass(String type) throwsException {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();
}
}
这里类型其实可以通过配置文件来处理,这样增加一个子类,就不需要改工厂类了。