您的位置:首页 > 其它

使用反射建立一个用于生产短信对象的工厂方法

2017-10-11 20:40 597 查看
先说说场景,一个系统,有几个功能需要用到短信功能,比如登录,忘记密码,更改手机号,更改密码等。那么需要一个接口,统一发送这些短信,从代码重用和抽象的角度来讲,需要实现一个短信积累,具有一些短信的具体功能,并且通过客户端的参数可以自动选择发送内容。

我提供的内容是在原有基础上更改过多次的,先贴出代码,短信鸡肋,他可以存放phone(手机号)和type(短信的具体类别,一般从客户端传来)

public abstract class AbstractMessage {
private String phone;
private String type;

public String getPhone() {
return phone;
}

public void setPhone(String phone) {
this.phone = phone;
}

public String getType() {
return type;
}

public void setType(String type) {
this.type = type;
}

AbstractMessage(){
super();
}

AbstractMessage(String type){
setType(type);
}
}

然后是几个短信子类,他们的特点就是构造方法里调用了setType方法,为什么要这样调用后面再说

public class LoginMessage extends AbstractMessage{

public static final String type = "3";
LoginMessage(){
setType(type);
}
}

public class RegisterMessage extends AbstractMessage {

public static final String type = "2";

RegisterMessage(){
setType(type);
}
}

public class RememberPasswordMessage extends AbstractMessage {

public static final String type = "1";

public RememberPasswordMessage() {
setType(type);
}
}

最后看看工厂方法类,这个类相当于一个工具类,他的create方法可以返回短信实体,从面向对象角度来讲返回值类型为基础类可以让这个方法返回基类的各种子类。

看调用create前,static里的代码就已经被执行完毕了,这个是static的特性,然后里面创建了一个map对象,对象存放了3个键值对,而key就是之前子类的type值,value是子类的class路径,在调用create方法时,会通过客户端传来的type找到map里对应的实体类class路径,然后通过反射创建对象,对象的类型是AbstractMessage的。需要注意的是子类的type必须和客户端传来的type值一样,那样才能正常创建对象,否则会出现异常。其实这个模式的思想就是把短信的创建权利交给客户端,而且如果要新增类只要添加class和在工厂类的static块里多一个put操作,和开闭原则相符,即对新增开放对修改关闭,不过实际开发中并不一定要死报着这个思想,要灵活运用。

public abstract class MessageFactory {
private static Map<String,String>messageType;
static {
messageType = new HashMap<>();
messageType.put(RememberPasswordMessage.type,"create.factory.customFactory.RememberPasswordMessage");
messageType.put(LoginMessage.type, "create.factory.customFactory.LoginMessage");
messageType.put(RegisterMessage.type,"create.factory.customFactory.RegisterMessage");
}

public static AbstractMessage createMessage(String type){
String className = messageType.get(type);
try {
Class<?> aClass = Class.forName(className);
return (AbstractMessage) aClass.newInstance();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
}
return null;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐