您当前的位置: 首页 > 

java持续实践

暂无认证

  • 3浏览

    0关注

    746博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

设计模式 工厂方法模式

java持续实践 发布时间:2022-03-14 23:22:37 ,浏览量:3

文章目录
      • 工厂方法模式
      • 工厂方法模式实战
        • 不使用工厂方法模式的写法
        • 使用工厂方法模式的写法

工厂方法模式

定义: 是一种创建型模式, 其在父类中提供一个创建对象的方法, 允许子类决定实例化对象的类型.

案例: 多钟类型商品不同接口, 统一发奖服务搭建.

工厂方法模式实战

设定需求为 发放三种类型的礼品 视频网站充值卡, 优惠券, 实物商品.

不使用工厂方法模式的写法

创建tutorials-4.0-0模块 pom中如下

    org.example
    1.0-SNAPSHOT
    tutorials-4.0-0

视频网站充值卡 信息

public class IQiYiCard {

    // 卡券的一些信息
}
public class IQiYiCardService {

    public void grantToken(String bindMobileNumber, String cardId) {
        System.out.println("模拟发一张爱奇艺会员卡一张: " + bindMobileNumber + ", " + cardId);
    }
}

优惠券信息:

public class CouponInfo {

    // 优惠券信息
}

public class CouponResult {
    // 编码
    private String code;
    // 描述
    private String info;

    public CouponResult() {

    }

    public CouponResult(String code, String info) {
        this.code = code;
        this.info = info;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getInfo() {
        return info;
    }

    public void setInfo(String info) {
        this.info = info;
    }
}
public class CouponService {

    public CouponResult sendCoupon(String uId, String couponNumber, String uuid) {
        System.out.println("模拟发放优惠券一张: "+ uId +", "+ couponNumber + "," + uuid);
        return new CouponResult("0000", "发放成功");
    }
}

实物商品信息

public class DeliverReq {

    private String userName; // 姓名
    private String userPhone; // 手机号
    private String sku; // sku
    private String orderId; // 订单id
    private String consigneeUserName; //  收货人姓名
    private String consigneeUserPhone; // 收货人手机号
    private String consigneeUserAddress; // 收货人地址

   // 省略 get set
}
public class GoodsInfo {

}
public class GoodsService {
    public Boolean deliverGoods(DeliverReq req) {
        System.out.println("模拟发货实物商品: " + JSON.toJSONString(req));
        return true;
    }
}

创建tutorials-4.0-1 模块, 不使用工厂方法模式 , 对奖品进行发放. pom


        
            junit
            junit
            4.12
            test
        
        
            com.alibaba
            fastjson
            1.2.62
        
        
            org.slf4j
            slf4j-api
            1.7.5
        
        
            org.slf4j
            jcl-over-slf4j
            1.7.5
        
        
            ch.qos.logback
            logback-classic
            1.0.9
            
                
                    slf4j-api
                    org.slf4j
                
            
        
        
            org.example
            1.0-SNAPSHOT
            tutorials-4.0-0
        
    

其中引入了tutorials-4.0-0 . 定义请求和响应类

public class AwardReq {

    private String uId;  // 用户id
    private Integer awardType;  // 奖品类型 1优惠券、2实物商品、3第三方兑换卡(爱奇艺)
    private String awardNumber; //  奖品编号sku、couponNumber、cardId
    private String bizId;   // 业务id  防止重复
    private Map extMap; // 扩展信息

	....get  set 
}

public class AwardRes {

    private String code; // 编码

    private String info; // 描述

    public AwardRes(String code, String info) {
        this.code = code;
        this.info = info;
    }
    ....get  set 
}

发放奖品的类. 用的是比较原始的if 判断的方式.

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", "发放失败");
                }
            } 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.info("奖品发放失败:{}, 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";
    }
}

测试类

public class ApiTest {

    private Logger logger = LoggerFactory.getLogger(ApiTest.class);

    @Test
    public void test_awardToUser() {
        PrizeController prizeController = new PrizeController();
        logger.info("模拟优惠券发放测试");

        AwardReq req01 = new AwardReq();
        req01.setuId("10001");
        req01.setAwardType(1); // 按照不同类型发放商品 1. 优惠券  2. 实物商品  3. 第三方兑换卡 (爱奇艺)
        req01.setAwardNumber("EGM10239333888");
        req01.setBizId("7910988888");
        AwardRes awardRes01 = prizeController.awardToUser(req01);

        logger.info("请求参数: {}", JSON.toJSON(req01));
        logger.info("测试结果: {}", JSON.toJSON(awardRes01));

        logger.info("模拟方法实物商品");
        AwardReq req02 = new AwardReq();
        req02.setuId("10001");
        req02.setAwardType(2);
        req02.setAwardNumber("9820198721311");
        req02.setBizId("1023000020112221113");
        req02.setExtMap(new HashMap(){{
            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("兑换爱奇艺");
        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));
    }
}

运行后 , 控制台打印如下

23:09:43.355 [main] INFO com.thc.test.ApiTest - 模拟优惠券发放测试 23:09:43.435 [main] INFO com.thc.design.PrizeController - 奖品发放开始: 10001 req: {“awardNumber”:“EGM10239333888”,“awardType”:1,“bizId”:“7910988888”,“uId”:“10001”} 模拟发放优惠券一张: 10001, EGM10239333888,7910988888 23:09:43.438 [main] INFO com.thc.design.PrizeController - 奖品发放完成: 10001 23:09:43.440 [main] INFO com.thc.test.ApiTest - 请求参数: {“uId”:“10001”,“bizId”:“7910988888”,“awardNumber”:“EGM10239333888”,“awardType”:1} 23:09:43.442 [main] INFO com.thc.test.ApiTest - 测试结果: {“code”:“0000”,“info”:“发放成功”} 23:09:43.442 [main] INFO com.thc.test.ApiTest - 模拟方法实物商品 23:09:43.446 [main] INFO com.thc.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”} 23:09:43.449 [main] INFO com.thc.design.PrizeController - 奖品发放完成: 10001 23:09:43.449 [main] INFO com.thc.test.ApiTest - 请求参数: {“extMap”:{“consigneeUserName”:“谢飞机”,“consigneeUserAddress”:“吉林省.长春市.双阳区.XX街道.檀溪苑小区.#18-2109”,“consigneeUserPhone”:“15200292123”},“uId”:“10001”,“bizId”:“1023000020112221113”,“awardNumber”:“9820198721311”,“awardType”:2} 23:09:43.450 [main] INFO com.thc.test.ApiTest - 测试结果: {“code”:“0000”,“info”:“发放成功”} 兑换爱奇艺 23:09:43.450 [main] INFO com.thc.design.PrizeController - 奖品发放开始: 10001 req: {“awardNumber”:“AQY1xjkUodl8LO975GdfrYUio”,“awardType”:3,“uId”:“10001”} 模拟发一张爱奇艺会员卡一张: 15200101232, AQY1xjkUodl8LO975GdfrYUio 23:09:43.451 [main] INFO com.thc.design.PrizeController - 奖品发放完成: 10001 23:09:43.451 [main] INFO com.thc.test.ApiTest - 请求参数:{“uId”:“10001”,“awardNumber”:“AQY1xjkUodl8LO975GdfrYUio”,“awardType”:3} 23:09:43.451 [main] INFO com.thc.test.ApiTest - 测试结果:{“code”:“0000”,“info”:“发放成功”}

使用工厂方法模式的写法

定义发放奖品的接口

public interface ICommodity {
    // 发放奖品
    void sendCommodity(String uId,
                       String commodityId,
                       String bizId,
                       Map extMap) throws Exception;

}

创建视频网站兑换卡的实现类

public class CardCommodityService implements ICommodity {

    private Logger logger = LoggerFactory.getLogger(CardCommodityService.class);

    private IQiYiCardService iQiYiCardService = new IQiYiCardService();

    public void sendCommodity(String uId, String commodityId, String bizId, Map extMap) throws Exception {
        String mobile = queryUserMobile(uId);
        iQiYiCardService.grantToken(mobile, bizId);
        logger.info("请求参数[爱奇艺兑换卡] => uId:{} commodityId:{} bizId:{} extMap:{}", uId, commodityId, bizId, JSON.toJSON(extMap));
        logger.info("爱奇艺兑换卡兑换成功!");
    }

    private String queryUserMobile(String uId) {
        return "15200101232";
    }
}

创建优惠券实现类

public class CouponCommodityService implements ICommodity {

    private Logger logger = LoggerFactory.getLogger(CouponCommodityService.class);

    private CouponService couponService = new CouponService();

    @Override
    public void sendCommodity(String uId, String commodityId, String bizId, Map extMap) throws Exception {
        CouponResult couponResult = couponService.sendCoupon(uId, commodityId, bizId);
        logger.info("请求参数[优惠券] => uId:{} commodityId:{} bizId:{} extMap:{}", uId, commodityId, bizId, JSON.toJSON(extMap));
        logger.info("测试结果 [优惠券]:  {}", JSON.toJSON(couponResult));

        if (!"0000".equals(couponResult.getCode())) {
            throw new RuntimeException(couponResult.getInfo());
        }
    }
}

创建实物商品实现类

public class GoodsCommodityService implements ICommodity {

    private Logger logger = LoggerFactory.getLogger(GoodsCommodityService.class);

    private GoodsService goodsService = new GoodsService();

    @Override
    public void sendCommodity(String uId, String commodityId, String bizId, Map extMap) throws Exception {
        DeliverReq deliverReq = new DeliverReq();
        deliverReq.setUserName(queryUserName(uId));
        deliverReq.setUserPhone(queryUserPhoneNumber(uId));
        deliverReq.setSku(commodityId);
        deliverReq.setOrderId(bizId);
        deliverReq.setConsigneeUserName(extMap.get("consigneeUserName"));
        deliverReq.setConsigneeUserPhone(extMap.get("consigneeUserPhone"));
        deliverReq.setConsigneeUserAddress(extMap.get("consigneeUserAddress"));

        Boolean isSuccess = goodsService.deliverGoods(deliverReq);
        logger.info("请求参数[实物商品] => uId:{} commodityId:{} bizId:{} extMap:{}", uId, commodityId, bizId, JSON.toJSON(extMap));
        logger.info("测试结果[实物商品]:{}", isSuccess);

        if (!isSuccess) throw new RuntimeException("实物商品发放失败");
    }

    private String queryUserName(String uId) {
        return "花花";
    }

    private String queryUserPhoneNumber(String uId) {
        return "15200101232";
    }
}

创建奖品工厂类 StoreFactory. 该工厂类使用了2种创建对象的方式 , 一种是根据类型, 一种是直接传递class类.

public class StoreFactory {

    public ICommodity getCommodityService(Integer commodityType) {
        if (commodityType == null) return null;
        if (1 == commodityType) return new CouponCommodityService();
        if (2 == commodityType) return new GoodsCommodityService();
        if (3 == commodityType) return new CardCommodityService();
        throw new RuntimeException("不存在的奖品服务类型");
    }

    // 奖品类信息方式实例化
    public ICommodity getCommodityService(Class clazz) throws IllegalAccessException, InstantiationException {
        if (null == clazz) {
            return null;
        }
        return clazz.newInstance();
    }
}

测试类: 传递数字类型的测试


   // 通过传递数字类型从工厂创建对象
    @Test
    public void test_storeFactory() throws Exception {
        StoreFactory storeFactory = new StoreFactory();

        // 1. 优惠券
        ICommodity commodityService1 = storeFactory.getCommodityService(1);
        commodityService1.sendCommodity("10001", "EGM1023938910232121323432", "791098764902132", null);

        // 2. 实物商品
        ICommodity commodityService2 = storeFactory.getCommodityService(2);
        commodityService2.sendCommodity("100001", "55544444", "24234fsgggg", new HashMap(){{
            put("consigneeUserName", "谢");
            put("consigneeUserPhone", "15200292123");
            put("consigneeUserAddress", "吉林省.长春市.双阳区.XX街道.檀溪苑小区.#18-2109");
        }});

        // 3. 第三方兑换卡
        ICommodity commodityService3 = storeFactory.getCommodityService(3);
        commodityService3.sendCommodity("10003","AQY1xjkUodl8LO975GdfrYUio", null, null);
    }

控制台打印如下

模拟发放优惠券一张: 10001, EGM1023938910232121323432,791098764902132 23:20:43.708 [main] INFO c.t.d.impl.CouponCommodityService - 请求参数[优惠券] => uId:10001 commodityId:EGM1023938910232121323432 bizId:791098764902132 extMap:null 23:20:43.743 [main] INFO c.t.d.impl.CouponCommodityService - 测试结果 [优惠券]: {“code”:“0000”,“info”:“发放成功”} 模拟发货实物商品: {“consigneeUserAddress”:“吉林省.长春市.双阳区.XX街道.檀溪苑小区.#18-2109”,“consigneeUserName”:“谢”,“consigneeUserPhone”:“15200292123”,“orderId”:“24234fsgggg”,“sku”:“55544444”,“userName”:“花花”,“userPhone”:“15200101232”} 23:20:43.750 [main] INFO c.t.d.impl.GoodsCommodityService - 请求参数[实物商品] => uId:100001 commodityId:55544444 bizId:24234fsgggg extMap:{“consigneeUserName”:“谢”,“consigneeUserAddress”:“吉林省.长春市.双阳区.XX街道.檀溪苑小区.#18-2109”,“consigneeUserPhone”:“15200292123”} 23:20:43.750 [main] INFO c.t.d.impl.GoodsCommodityService - 测试结果[实物商品]:true 模拟发一张爱奇艺会员卡一张: 15200101232, null 23:20:43.751 [main] INFO c.t.design.impl.CardCommodityService - 请求参数[爱奇艺兑换卡] => uId:10003 commodityId:AQY1xjkUodl8LO975GdfrYUio bizId:null extMap:null 23:20:43.751 [main] INFO c.t.design.impl.CardCommodityService - 爱奇艺兑换卡兑换成功!

直接传递class类的测试

    // 通过传递class  创建对象
    @Test
    public void test_StoreFactory() throws Exception{
        StoreFactory storeFactory = new StoreFactory();
        ICommodity commodityService = storeFactory.getCommodityService(CouponCommodityService.class);
        commodityService.sendCommodity("100005","EGM1023938910232121323432", "791098764902132", null);
    }

控制台打印如下

模拟发放优惠券一张: 100005, EGM1023938910232121323432,791098764902132 23:22:05.051 [main] INFO c.t.d.impl.CouponCommodityService - 请求参数[优惠券] => uId:100005 commodityId:EGM1023938910232121323432 bizId:791098764902132 extMap:null 23:22:05.085 [main] INFO c.t.d.impl.CouponCommodityService - 测试结果 [优惠券]: {“code”:“0000”,“info”:“发放成功”}

关注
打赏
1658054974
查看更多评论
立即登录/注册

微信扫码登录

0.0512s