继承关系下怎样使用Builder 模式
程序员文章站
2022-06-04 17:10:12
...
以微信图文消息推送为例
需要组装的消息体
{
"touser" : "UserID1|UserID2|UserID3",
"toparty" : "PartyID1|PartyID2",
"totag" : "TagID1 | TagID2",
"msgtype" : "text",
"agentid" : 1,
"text" : {
"content" : "你的快递已到,请携带工卡前往邮件中心领取。\n出发前可查看<a href=\"http://work.weixin.qq.com\">邮件中心视频实况</a>,聪明避开排队。"
},
"safe":0
}
一、基础的字段放到父类 BaseMessage 中
public class BaseMessage {
/**
* 消息类型:text、textcard、
*/
private String msgtype;
/**
* 应用id
*/
private Integer agentid;
/**
* 加密方式。默认不传或传0传2不进行任何解密处理直接发送文本 。传1对整个文本内容将进行base64解密。传3对整个文本内容进行UrlEncode编码
*/
private String touser;
/**
* 部门ID列表,多个接收者用‘|’分隔,最多支持100个。部门id请查询OA接口获取部门id。注:使用该参数会对整个部门的全部人员进行群发,请慎重使用
*/
private String toparty;
/**
* 标签ID列表,多个接收者用‘|’分隔,最多支持100个。当touser为@all时忽略本参数。
*/
private String totag;
/**
* 表示是否是保密消息,0表示否,1表示是,默认0
*/
private Integer safe;
public BaseMessage(String msgtype) {
this.msgtype = msgtype;
}
public BaseMessage() {
}
public <T extends BaseMessageBuilder> BaseMessage(BaseMessageBuilder builder) {
this.msgtype = builder.msgtype;
this.agentid = builder.agentid;
this.touser = builder.touser;
this.toparty = builder.toparty;
this.totag = builder.totag;
this.safe = builder.safe;
}
public String getMsgtype() {
return msgtype;
}
public Integer getAgentid() {
return agentid;
}
public String getTouser() {
return touser;
}
public String getToparty() {
return toparty;
}
public String getTotag() {
return totag;
}
public Integer getSafe() {
return safe;
}
/**
* 在父类中使用泛型 根据调用的子类不同 返回子类对应的Builder
*/
public static class BaseMessageBuilder<T extends BaseMessageBuilder> {
private String msgtype;
private Integer agentid;
private String touser;
private String toparty;
private String totag;
private Integer safe;
public BaseMessageBuilder(String msgtype) {
this.msgtype = msgtype;
}
public T agentid(Integer agentid) {
this.agentid = agentid;
return (T) this;
}
public T touser(String touser) {
this.touser = touser;
return (T) this;
}
public T toparty(String toparty) {
this.toparty = toparty;
return (T) this;
}
public T totag(String totag) {
this.totag = totag;
return (T) this;
}
public T safe(Integer safe) {
this.safe = safe;
return (T) this;
}
}
}
二、 不同种类型的消息只需要继承父类 然后加上独有字段
public class WorkWeiXinContentText extends BaseMessage {
private static final String MSGTYPE = "text";
private Text text;
public WorkWeiXinContentText(String content) {
super(MSGTYPE);
this.text = new Text(content);
}
public WorkWeiXinContentText(WorkWeiXinContentTextBuilder builder) {
/**
* 调用的是父类的构造方法 public <T extends BaseMessageBuilder> BaseMessage(BaseMessageBuilder builder)
*/
super(builder);
this.text = builder.text;
}
public static WorkWeiXinContentTextBuilder builder() {
return new WorkWeiXinContentTextBuilder(MSGTYPE);
}
public Text getText() {
return text;
}
/**
* 如果先赋值子类的属性 则返回的是子类的WorkWeiXinContentTextBuilder ,如果先赋值父类的属性 不加泛型的话 返回的是父类的 BaseMessageBuilder 无法转换为子类对象 WorkWeiXinContentText
*/
public static class WorkWeiXinContentTextBuilder extends BaseMessageBuilder<WorkWeiXinContentTextBuilder> {
private Text text;
WorkWeiXinContentTextBuilder(String msgtype) {
super(msgtype);
}
public WorkWeiXinContentTextBuilder text(Text text) {
this.text = text;
return this;
}
public WorkWeiXinContentText build() {
return new WorkWeiXinContentText(this);
}
}
}
public class Text {
private String content;
public Text(String content) {
this.content = content;
}
public Text() {
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
三、使用
public static void main(String[] args) {
String content="你的快递已到,请携带工卡前往邮件中心领取。\n出发前可查看<a href=\"http://work.weixin.qq.com\">邮件中心视频实况</a>,聪明避开排队。";
WorkWeiXinContentText msgBody =WorkWeiXinContentText.builder()
.touser("UserID1|UserID2|UserID3")
.toparty("PartyID1|PartyID2")
.totag("TagID1 | TagID2")
.agentid(1)
.safe(0)
.text(new Text(content))
.build();
// do something
}