1.狂神版
简单工厂模式
工厂方法模式
2.小傅哥版本 (工厂方法模式)
爱奇艺 会员卡服务
优惠券 服务
优惠券 结果
实体商品 服务
发货 信息
1. 未使用工厂方法模式
public class AwardReq {
private String uId; // 用户唯一ID
private Integer awardType; // 奖品类型(可以用枚举定义);1优惠券、2实物商品、3第三方兑换卡(爱奇艺)
private String awardNumber; // 奖品编号;sku、couponNumber、cardId
private String bizId;
...
public class AwardRes {
private String code; // 编码
private String info; // 描述
...
/**
* 模拟发奖服务
*/
public class PrizeController {
private Logger logger = LoggerFactory.getLogger(PrizeController.class);
public AwardRes awardToUser(AwardReq req) {
String reqJson = JSON.toJSONString(req);
AwardRes awardRes = null;
try {
logger.info("奖品发放开始{}。req:{}", req.getuId(), reqJson);
// 按照不同类型方法商品[1优惠券、2实物商品、3第三方兑换卡(爱奇艺)]
if (req.getAwardType() == 1) {
CouponService couponService = new CouponService();
CouponResult couponResult = couponService.sendCoupon(req.getuId(), req.getAwardNumber(), req.getBizId());
if ("0000".equals(couponResult.getCode())) {
awardRes = new AwardRes("0000", "发放成功");
} else {
awardRes = new AwardRes("0001", couponResult.getInfo());
}
} else if (req.getAwardType() == 2) {
GoodsService goodsService = new GoodsService();
DeliverReq deliverReq = new DeliverReq();
deliverReq.setUserName(queryUserName(req.getuId()));
deliverReq.setUserPhone(queryUserPhoneNumber(req.getuId()));
deliverReq.setSku(req.getAwardNumber());
deliverReq.setOrderId(req.getBizId());
deliverReq.setConsigneeUserName(req.getExtMap().get("consigneeUserName"));
deliverReq.setConsigneeUserPhone(req.getExtMap().get("consigneeUserPhone"));
deliverReq.setConsigneeUserAddress(req.getExtMap().get("consigneeUserAddress"));
Boolean isSuccess = goodsService.deliverGoods(deliverReq);
if (isSuccess) {
awardRes = new AwardRes("0000", "发放成功");
} else {
awardRes = new AwardRes("0001", "发放失败");
}
} else if (req.getAwardType() == 3) {
String bindMobileNumber = queryUserPhoneNumber(req.getuId());
IQiYiCardService iQiYiCardService = new IQiYiCardService();
iQiYiCardService.grantToken(bindMobileNumber, req.getAwardNumber());
awardRes = new AwardRes("0000", "发放成功");
}
logger.info("奖品发放完成{}。", req.getuId());
} catch (Exception e) {
logger.error("奖品发放失败{}。req:{}", req.getuId(), reqJson, e);
awardRes = new AwardRes("0001", e.getMessage());
}
return awardRes;
}
private String queryUserName(String uId) {
return "花花";
}
private String queryUserPhoneNumber(String uId) {
return "15200101232";
}
}
开始测试
@Test
public void test_awardToUser() {
PrizeController prizeController = new PrizeController();
System.out.println("\r\n模拟发放优惠券测试\r\n");
// 模拟发放优惠券测试
AwardReq req01 = new AwardReq();
req01.setuId("10001");
req01.setAwardType(1);
req01.setAwardNumber("EGM1023938910232121323432");
req01.setBizId("791098764902132");
AwardRes awardRes01 = prizeController.awardToUser(req01);
logger.info("请求参数:{}", JSON.toJSON(req01));
logger.info("测试结果:{}", JSON.toJSON(awardRes01));
System.out.println("\r\n模拟方法实物商品\r\n");
// 模拟方法实物商品
AwardReq req02 = new AwardReq();
req02.setuId("10001");
req02.setAwardType(2);
req02.setAwardNumber("9820198721311");
req02.setBizId("1023000020112221113");
req02.setExtMap(new HashMap<String, String>() {{
put("consigneeUserName", "谢飞机");
put("consigneeUserPhone", "15200292123");
put("consigneeUserAddress", "吉林省.长春市.双阳区.XX街道.檀溪苑小区.#18-2109");
}});
AwardRes awardRes02 = prizeController.awardToUser(req02);
logger.info("请求参数:{}", JSON.toJSON(req02));
logger.info("测试结果:{}", JSON.toJSON(awardRes02));
System.out.println("\r\n第三方兑换卡(爱奇艺)\r\n");
AwardReq req03 = new AwardReq();
req03.setuId("10001");
req03.setAwardType(3);
req03.setAwardNumber("AQY1xjkUodl8LO975GdfrYUio");
AwardRes awardRes03 = prizeController.awardToUser(req03);
logger.info("请求参数:{}", JSON.toJSON(req03));
logger.info("测试结果:{}", JSON.toJSON(awardRes03));
}
输出的结果
模拟发放优惠券测试
15:07:44.841 [main] INFO o.i.demo.design.PrizeController - 奖品发放开始10001。req:{"awardNumber":"EGM1023938910232121323432","awardType":1,"bizId":"791098764902132","uId":"10001"}
模拟发放优惠券一张:10001,EGM1023938910232121323432,791098764902132
15:07:44.848 [main] INFO o.i.demo.design.PrizeController - 奖品发放完成10001。
15:07:44.850 [main] INFO org.itstack.demo.test.ApiTest - 请求参数:{"uId":"10001","bizId":"791098764902132","awardNumber":"EGM1023938910232121323432","awardType":1}
15:07:44.852 [main] INFO org.itstack.demo.test.ApiTest - 测试结果:{"code":"0000","info":"发放成功"}
模拟方法实物商品
15:07:44.853 [main] INFO o.i.demo.design.PrizeController - 奖品发放开始10001。req:{"awardNumber":"9820198721311","awardType":2,"bizId":"1023000020112221113","extMap":{"consigneeUserName":"谢飞机","consigneeUserPhone":"15200292123","consigneeUserAddress":"吉林省.长春市.双阳区.XX街道.檀溪苑小区.#18-2109"},"uId":"10001"}
模拟发货实物商品一个:{"consigneeUserAddress":"吉林省.长春市.双阳区.XX街道.檀溪苑小区.#18-2109","consigneeUserName":"谢飞机","consigneeUserPhone":"15200292123","orderId":"1023000020112221113","sku":"9820198721311","userName":"花花","userPhone":"15200101232"}
15:07:44.856 [main] INFO o.i.demo.design.PrizeController - 奖品发放完成10001。
15:07:44.857 [main] INFO org.itstack.demo.test.ApiTest - 请求参数:{"extMap":{"consigneeUserName":"谢飞机","consigneeUserAddress":"吉林省.长春市.双阳区.XX街道.檀溪苑小区.#18-2109","consigneeUserPhone":"15200292123"},"uId":"10001","bizId":"1023000020112221113","awardNumber":"9820198721311","awardType":2}
15:07:44.857 [main] INFO org.itstack.demo.test.ApiTest - 测试结果:{"code":"0000","info":"发放成功"}
第三方兑换卡(爱奇艺)
15:07:44.857 [main] INFO o.i.demo.design.PrizeController - 奖品发放开始10001。req:{"awardNumber":"AQY1xjkUodl8LO975GdfrYUio","awardType":3,"uId":"10001"}
模拟发放爱奇艺会员卡一张:15200101232,AQY1xjkUodl8LO975GdfrYUio
15:07:44.858 [main] INFO o.i.demo.design.PrizeController - 奖品发放完成10001。
15:07:44.858 [main] INFO org.itstack.demo.test.ApiTest - 请求参数:{"uId":"10001","awardNumber":"AQY1xjkUodl8LO975GdfrYUio","awardType":3}
15:07:44.858 [main] INFO org.itstack.demo.test.ApiTest - 测试结果:{"code":"0000","info":"发放成功"}
运⾏结果正常,满⾜当前所有业务产品需求,写的还很快。但!实在难以为维护!!!!
2.使用工厂方法模式
工程结构图
活动的 商品接口
卡片商品服务
间接调用爱奇艺会员卡的服务,再添加其他业务
优惠券商品服务
实体商品 服务
仓库工厂
这里传类型可以使用 枚举类型来定义
开始测试
@Test
public void test_commodity() throws Exception {
StoreFactory storeFactory = new StoreFactory();
// 1. 优惠券
ICommodity commodityService_1 = storeFactory.getCommodityService(1);
commodityService_1.sendCommodity("10001", "EGM1023938910232121323432", "791098764902132", null);
// 2. 实物商品
ICommodity commodityService_2 = storeFactory.getCommodityService(2);
Map<String,String> extMap = new HashMap<String,String>();
extMap.put("consigneeUserName", "谢飞机");
extMap.put("consigneeUserPhone", "15200292123");
extMap.put("consigneeUserAddress", "吉林省.长春市.双阳区.XX街道.檀溪苑小区.#18-2109");
commodityService_2.sendCommodity("10001","9820198721311","1023000020112221113",new HashMap<String, String>() {{
put("consigneeUserName", "谢飞机");
put("consigneeUserPhone", "15200292123");
put("consigneeUserAddress", "吉林省.长春市.双阳区.XX街道.檀溪苑小区.#18-2109");
}});
// 3. 第三方兑换卡(爱奇艺)
ICommodity commodityService_3 = storeFactory.getCommodityService(3);
commodityService_3.sendCommodity("10001","AQY1xjkUodl8LO975GdfrYUio",null,null);
}
测试结果
模拟发放优惠券一张:10001,EGM1023938910232121323432,791098764902132
15:27:03.715 [main] INFO o.i.d.d.s.i.CouponCommodityService - 请求参数[优惠券] => uId:10001 commodityId:EGM1023938910232121323432 bizId:791098764902132 extMap:null
15:27:03.767 [main] INFO o.i.d.d.s.i.CouponCommodityService - 测试结果[优惠券]:{"code":"0000","info":"发放成功"}
模拟发货实物商品一个:{"consigneeUserAddress":"吉林省.长春市.双阳区.XX街道.檀溪苑小区.#18-2109","consigneeUserName":"谢飞机","consigneeUserPhone":"15200292123","orderId":"1023000020112221113","sku":"9820198721311","userName":"花花","userPhone":"15200101232"}
15:27:03.774 [main] INFO o.i.d.d.s.impl.GoodsCommodityService - 请求参数[优惠券] => uId:10001 commodityId:9820198721311 bizId:1023000020112221113 extMap:{"consigneeUserName":"谢飞机","consigneeUserAddress":"吉林省.长春市.双阳区.XX街道.檀溪苑小区.#18-2109","consigneeUserPhone":"15200292123"}
15:27:03.774 [main] INFO o.i.d.d.s.impl.GoodsCommodityService - 测试结果[优惠券]:true
模拟发放爱奇艺会员卡一张:15200101232,null
15:27:03.776 [main] INFO o.i.d.d.s.impl.CardCommodityService - 请求参数[爱奇艺兑换卡] => uId:10001 commodityId:AQY1xjkUodl8LO975GdfrYUio bizId:null extMap:null
15:27:03.776 [main] INFO o.i.d.d.s.impl.CardCommodityService - 测试结果[爱奇艺兑换卡]:success
那么这样的开发的好处知道后,也可以总结出来它的优点; 避免创建者与具体的产品逻辑耦合 、 满⾜单⼀职责,每⼀个业务逻辑实现都在所属⾃⼰的类中完成 、 满⾜开闭原则,⽆需更改使⽤调⽤⽅就可以
在程序中引⼊新的产品类型 。但这样也会带来⼀些问题,⽐如有⾮常多的奖品类型,那么实现的⼦
类会极速扩张。因此也需要使⽤其他的模式进⾏优化,这些在后续的设计模式中会逐步涉及到。