08 创建型模式-工厂模式

1.定义

08 创建型模式-工厂模式_第1张图片

2.案例场景

为了让我们的案例更加贴近实际开发, 这里我们来模拟一下互联网电商中
促销拉新下的业务场景, 新用户注册立即参与抽奖活动 ,奖品的种类有: 打折券,
免费优酷会员,小礼品

08 创建型模式-工厂模式_第2张图片
(1)不考虑设计原则,不使用设计模式的方式进行开发,代码如下:
08 创建型模式-工厂模式_第3张图片

import java.util.Map;

/**
 * 获奖信息实体类
 **/
public class AwardInfo {

    private String uid; //用户id

    private Integer awardTypes; //奖品类型: 1 打折券 ,2 优酷会员 , 3 小礼品

    private String awardNumber; //奖品编号

    private Map<String,String> extMap; //额外信息

    public AwardInfo() {
    }

    @Override
    public String toString() {
        return "AwardInfo{" +
                "uid='" + uid + '\'' +
                ", awardTypes=" + awardTypes +
                ", awardNumber='" + awardNumber + '\'' +
                ", extMap=" + extMap +
                '}';
    }

    public String getUid() {
        return uid;
    }

    public void setUid(String uid) {
        this.uid = uid;
    }

    public Integer getAwardTypes() {
        return awardTypes;
    }

    public void setAwardTypes(Integer awardTypes) {
        this.awardTypes = awardTypes;
    }

    public String getAwardNumber() {
        return awardNumber;
    }

    public void setAwardNumber(String awardNumber) {
        this.awardNumber = awardNumber;
    }

    public Map<String, String> getExtMap() {
        return extMap;
    }

    public void setExtMap(Map<String, String> extMap) {
        this.extMap = extMap;
    }
}
/**
 * 打折券信息实体类
 **/
public class DiscountInfo {

    //属性信息省略......
}
/**
 * 优酷会员实体类
 **/
public class YouKuMember {

    //属性信息省略

}
/**
 * 小礼品实体类
 **/
public class SmallGiftInfo {

    private String userName;

    private String userPhone;

    private String orderId;

    private String address;

    @Override
    public String toString() {
        return "SmallGiftInfo{" +
                "userName='" + userName + '\'' +
                ", userPhone='" + userPhone + '\'' +
                ", orderId='" + orderId + '\'' +
                ", address='" + address + '\'' +
                '}';
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getUserPhone() {
        return userPhone;
    }

    public void setUserPhone(String userPhone) {
        this.userPhone = userPhone;
    }

    public String getOrderId() {
        return orderId;
    }

    public void setOrderId(String orderId) {
        this.orderId = orderId;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }
}

/**
 * 打折券响应信息封装实体类
 **/
public class DiscountResult {

    private String status; //状态码

    private String message; //信息


    public DiscountResult(String status, String message) {
        this.status = status;
        this.message = message;
    }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}
2)服务层:

08 创建型模式-工厂模式_第4张图片

/**
 * 打折券服务
 **/
public class DiscountService {

    public DiscountResult sendDiscount(String uid, String awardNumber){

        System.out.println("向用户发送一张打折券: " + uid +  " , " + awardNumber);
        return new DiscountResult("200","发放打折券成功!");
    }

}
/**
 * 小礼品服务
 **/
public class SmallGiftService {

    public Boolean giveSmallGift(SmallGiftInfo smallGiftInfo){

        System.out.println("小礼品已发送,获奖用户注意查收! " + JSON.toJSON(smallGiftInfo));
        return true;
    }
}
/**
 * 优酷会员
 **/
public class YouKuMemberService {

    public void openMember(String bindMobile, String awardNumber){

        System.out.println("发放优酷会员: " + bindMobile + " , " + awardNumber);
    }

}
3) 控制层

08 创建型模式-工厂模式_第5张图片

/**
 * 发放奖品接口
 **/
public class DeliverController {

    /**
     * 按照类型的不同发放奖品
     *      奖品类型: 1 打折券 ,2 优酷会员 , 3 小礼品, 4 优惠券
     * @param awardInfo
     */
    public void awardToUser(AwardInfo awardInfo){

        if(awardInfo.getAwardTypes() == 1){ //打折券
            DiscountService discountService = new DiscountService();
            DiscountResult discountResult = discountService.sendDiscount(awardInfo.getUid(), awardInfo.getAwardNumber());
            System.out.println("打折券发放成功!" + discountResult );

        }else if(awardInfo.getAwardTypes() == 2){//优酷会员

            String phone = awardInfo.getExtMap().get("phone");

            YouKuMemberService youKuMemberService = new YouKuMemberService();
            youKuMemberService.openMember(phone,awardInfo.getAwardNumber());
            System.out.println("优酷会员发放成功!");

        } else if(awardInfo.getAwardTypes() == 3){//小礼品
            //封装收获人信息
            SmallGiftInfo info = new SmallGiftInfo();
            info.setUserPhone(awardInfo.getExtMap().get("phone"));
            info.setUserName(awardInfo.getExtMap().get("username"));
            info.setAddress(awardInfo.getExtMap().get("address"));
            info.setOrderId(UUID.randomUUID().toString());

            SmallGiftService smallGiftService = new SmallGiftService();
            Boolean aBoolean = smallGiftService.giveSmallGift(info);
            if(aBoolean){
                System.out.println("小礼品发放成功!");
            }
        }

    }

}
4) 测试

通过单元测试,来对上面的接口进行测试,验证代码质量

public class TestApi01 {

    DeliverController deliverController = new DeliverController();

    //测试发放奖品接口
    @Test
    public void test01(){

        //1. 发放打折券优惠
        AwardInfo info1 = new AwardInfo();
        info1.setUid("1001");
        info1.setAwardTypes(1);
        info1.setAwardNumber("DEL12345");

        deliverController.awardToUser(info1);

    }

    @Test
    public void test02(){
        //2. 发放优酷会员
        AwardInfo info2 = new AwardInfo();
        info2.setUid("1002");
        info2.setAwardTypes(2);
        info2.setAwardNumber("DW12345");
        Map<String,String> map = new HashMap<>();
        map.put("phone","13512341234");
        info2.setExtMap(map);

        deliverController.awardToUser(info2);
    }

    @Test
    public void test03(){
        //2. 发放小礼品
        AwardInfo info3 = new AwardInfo();
        info3.setUid("1003");
        info3.setAwardTypes(3);
        info3.setAwardNumber("SM12345");
        Map<String,String> map2 = new HashMap<>();
        map2.put("username","大远");
        map2.put("phone","13512341234");
        map2.put("address","北京天安门");
        info3.setExtMap(map2);

        deliverController.awardToUser(info3);
    }
}

对于上面的实现方式,如果我们有想要添加的新的奖品时,势必要改动
DeliverController的代码,违反开闭原则.而且如果有的抽奖接口出现问题,那么对
其进行重构的成本会非常高.
除此之外代码中有一组if分支判断逻辑,现在看起来还可以,但是如果经历几次迭
代和拓展,后续ifelse肯定还会增加.到时候接手这段代码的研发将会十分痛苦.

你可能感兴趣的:(设计模式,java)