一、工厂模式
工厂模式又叫做工厂方法模式,是一种创建型设计模式,一般是在父类中提供一个创建对象的方法,允许子类决定实例化对象的类型。
1.1 工厂模式介绍
工厂模式是Java 中比较常见的一种设计模式,实现方法是定义一个统一创建对象的接口,让其子类自己决定去实例化那个工厂类,解决不同条件下创建不同实例的问题。工厂方法模式在实际使用时会和其他的设计模式一起结合,而不是单独使用。比如在Lottery 项目中奖品的发放就是工厂+模板+策略模式。
更多学习资料获取方式:评论区留言或是私信获取到哦
1.2 工厂模式实现
举个例子,比如要实现不同奖品的发放业务,有优惠券、实体商品和会员电子卡这些奖品,那么我们可以定义这三种类型奖品的接口:
序号 | 类型 | 接口 | 描述 |
---|---|---|---|
1 | 优惠券 | CouponResult sendCoupon(String uId, String couponNumber, String uuid) |
返回优惠券信息(对象类型) |
2 | 实体商品 | Boolean deliverGoods(DeliverReq req) |
返回是否发送实体商品(布尔类型) |
3 | 爱奇艺会员电子卡 | void grantToken(String bindMobileNumber, String cardId) |
执行发放会员卡(空类型) |
从上表可以看出,不同的奖品有不同的返回类型需求,那么我们该如何处理这些数据,并对应返回呢?常规思路可以想到通过统一的入参AwardReq
,出参AwardRes
,外加上一个PrizeController
来具体实现这些奖品的数据处理任务:
AwardReq
AwardRes
PrizeController
但是这样势必会造成PrizeController
这个类中逻辑判断过多,后期如果要继续扩展奖品类型,是非常困难和麻烦的。比如可以看看PrizeController
中的代码:
public class PrizeController {
private Logger logger = LoggerFactory.getLogger(PrizeController.class);
public AwardRes AwardToUser(AwardReq awardReq) {
String reqJson = JSON.toJSONString(awardReq);
AwardRes awardRes = null;
try {
logger.info("奖品发放开始{}。 awardReq:{}", awardReq.getuId(), reqJson);
if (awardReq.getAwardType() == 1) {
CouponService couponService = new CouponService();
CouponResult couponResult = couponService.sendCoupon(awardReq.getuId(), awardReq.getAwardNumber(), awardReq.getBizId());
if ("0000".equals(couponResult.getCode())) {
awardRes = new AwardRes(0000, "发放成功");
} else {
awardRes = new AwardRes(0001, "发送失败");
}
} else if (awardReq.getAwardType() == 2) {
GoodsService goodsService = new GoodsService();
DeliverReq deliverReq = new DeliverReq();
deliverReq.setUserName(queryUserName(awardReq.getuId()));
deliverReq.setUserPhone(queryUserPhoneNumber(awardReq.getuId()));
deliverReq.setSku(awardReq.getAwardNumber());
deliverReq.setOrderId(awardReq.getBizId());
deliverReq.setConsigneeUserName(awardReq.getExtMap().get("consigneeUserName"));
deliverReq.setConsigneeUserPhone(awardReq.getExtMap().get("consigneeUserPhone"));
deliverReq.setConsigneeUserAddress(awardReq.getExtMap().get("consigneeUserAddress"));
Boolean isSuccess = goodsService.deliverGoods(deliverReq);
if (isSuccess) {
awardRes = new AwardRes(0000, "发放成功");
} else {
awardRes = new AwardRes(0001, "发送失败");
}
} else {
IQiYiCardService iQiYiCardService = new IQiYiCardService();
iQiYiCardService.grantToken(queryUserPhoneNumber(awardReq.getuId()), awardReq.getAwardNumber());
awardRes = new AwardRes(0000, "发送成功");
}
logger.info("奖品发放完成{}。", awardReq.getuId());
} catch (Exception e) {
logger.error(