简单工厂模式

一、简单工厂模式定义

       简单工厂模式不是一种设计模式,反而比较像一种编程习惯。

       简单工厂模式又叫静态工厂方法模式(static Factory Method pattern),它使用静态

       方法接收接收不同的参数返回不同的实例对象。

二、实现方式

       定义一个工厂类,根据传入的参数不同返回不同的实例,被创建的实例有共同的父类或接口

三、适用场景

       1、被创建的对象较少

        2、客户端不关心对象创建的过程

四、简单工厂结构

       1、简单工厂包含如下角色:

             1)抽象产品:定义了产品的规范,描述了产品的主要特性和功能

              2)具体产品:实现或继承抽象产品的子类

              3)产品工厂:提供了创建产品的方法,调用者通过该方法来获取产品

               

五、简单工厂模式使用示例

       1、需求

             现有一个需求,模拟抽奖活动的奖品发送流程,现有3种奖品:打折卷、优酷会员和

             小礼品,需要把这3种奖品发到中奖人手中。

        2、不使用设计模式方式实现

              对于上边的需求,如果是一个小白来实现,不考虑代码后期的扩展性,可能会这样实现:

                      1)分别为每种奖品和获奖人创建一个实体类,如下所示:

                       2)为每种奖品的发放创建一个奖品发放业务类

                       3)创建客户端类,在客户端类通过奖品类型来区分发放那种奖品,

               2.1)UML类图如下

                    

               2.2)代码如下:

                     



/*******************************************************
 * 小礼品信息对应实体类
 *******************************************************/
@Data
public class SmallGiftInfo {

    /**
     * 用户名称
     */
    private String userName;
    /**
     * 手机号
     */
    private String phone;
    /**
     * 礼品标识
     */
    private String orderId;
    /**
     * 地址
     */
    private String address;
}



/*******************************************************
 * 获奖信息实体类
 * 不使用设计模式,原始方式实现
 *******************************************************/
@Data
public class AwardInfo {
    /**
     * 用户id
     */
    private String uid;
    /**
     * 奖品类型,1-打折卷,2-优酷会员,3-小礼品
     */
    private Integer awardTypes;
    /**
     * 奖品编号
     */
    private String awardNumber;
    /**
     * 额外信息
     */
    private Map<String,String> extMap;

}

/*******************************************************
 *
 * 打折卷操作响应结果类
 *
 *******************************************************/
@Data
public class ResponseResult {

    private String status;

    private String message;

    public Object data;


    public ResponseResult(String status, String message) {
        
        this(status,message,null);

    }

    public ResponseResult(String status, String message,Object data) {
        this.status = status;
        this.message = message;
        this.data = data;
    }

   
}


              发送奖品业务逻辑代码

/*******************************************************
 *
 * 打折卷service
 *******************************************************/
public class DiscountService {

    public ResponseResult sendDiscount(String uid,String awardNumber){

        System.out.println("向用户发送一张打折卷:"+uid+" , "+awardNumber);

        return new ResponseResult("200","发送打折卷成功 ");
    }
}


/*******************************************************
 * 小礼品发放业务逻辑
 *******************************************************/
public class SmallGifService {

    public Boolean giveSmallGif(SmallGiftInfo smallGiftInfo){
        System.out.println("小礼品已经发送,获奖用户请注意查收: "+ JSON.toJSON(smallGiftInfo));

        return true;
    }
}


/*******************************************************
 * 优酷会员发放业务逻辑
 *******************************************************/
public class YouKuMemberService {

    public void openMember(String bingPhone,String awardNumber){

        System.out.println("发送优酷会员卷:"+bingPhone+", "+awardNumber);
    }
}


/*******************************************************
 *
 *  发放奖品操作
 *
 *******************************************************/
public class DeliverController {

    public void awardToUser(AwardInfo awardInfo){

        /**
         * 根据奖品类型发送奖品
         * 奖品类型,1-打折卷,2-优酷会员,3-小礼品
         */
        if(awardInfo.getAwardTypes() == 1){
            DiscountService discountService = new DiscountService();
            discountService.sendDiscount(awardInfo.getUid(),awardInfo.getAwardNumber());
            System.out.println("打折卷发送成功");
        }else if(awardInfo.getAwardTypes() == 2){

            String phone = awardInfo.getExtMap().get("phone");
            YouKuMemberService youku = new YouKuMemberService();
            youku.openMember(phone,awardInfo.getAwardNumber());
            System.out.println("优酷会员发送成功");
        }else if(awardInfo.getAwardTypes() == 3){
            String username = awardInfo.getExtMap().get("username");
            String phone = awardInfo.getExtMap().get("phone");
            String address = awardInfo.getExtMap().get("address");

            SmallGiftInfo info = new SmallGiftInfo();
            info.setOrderId(UUID.randomUUID().toString());
            info.setUserName(username);
            info.setPhone(phone);
            info.setAddress(address);

            SmallGifService service = new SmallGifService();
            //发送小礼品
            Boolean bool = service.giveSmallGif(info);
            if(bool){
                System.out.println("小礼品发送成功");
            }

        }
    }
}

    

         3、使用简单工厂模式重构上边代码

              3.1)简单工厂模式下类图如下:

                      

              3.2)代码如下:

/*******************************************************
 * 产品工厂
 * 根据礼品类型不同,返回对应的 IFreeGoods 实现类
 *******************************************************/
public class FreeGoodsFactory {

    public static IFreeGoods getInstance(Integer type){

        if(type == 1){
            return new DiscountFreeGoods();
        }else if(type == 2){
            return new YouKuMemberFreeGoods();
        }else if(type == 3){
            return new SmallGifFreeGoods();
        }

        return null;
    }
}


/**
 * 奖品发送接口
 */
public interface IFreeGoods {

    ResponseResult sendGoods(AwardInfo award);
}

/*******************************************************
 *
 * 发放打折卷
 *
 *******************************************************/
public class DiscountFreeGoods implements IFreeGoods {
    @Override
    public ResponseResult sendGoods(AwardInfo award) {

        String uid = award.getUid();
        String awardNumber = award.getAwardNumber();

        return new ResponseResult("200","给用户 "+uid+"发送打折卷成功 "+awardNumber);
    }
}



/*******************************************************
 *
 * 发送小礼品
 *
 *******************************************************/
public class SmallGifFreeGoods implements IFreeGoods {
    @Override
    public ResponseResult sendGoods(AwardInfo award) {
        SmallGiftInfo smallGiftInfo = new SmallGiftInfo();
        smallGiftInfo.setUserName(award.getExtMap().get("username"));
        smallGiftInfo.setPhone(award.getExtMap().get("phone"));
        smallGiftInfo.setAddress(award.getExtMap().get("address"));
        smallGiftInfo.setOrderId(UUID.randomUUID().toString());

        System.out.println("小礼品发送成功,请注意查收!");
        return new ResponseResult("200","小礼品发送成功",smallGiftInfo);
    }
}

/*******************************************************
 *
 * 发送优酷会员
 *
 *******************************************************/
public class YouKuMemberFreeGoods implements IFreeGoods {
    @Override
    public ResponseResult sendGoods(AwardInfo award) {

        String phone = award.getExtMap().get("phone");
        System.out.println("发放优酷会员成功。绑定手机号:"+phone);
        return new ResponseResult("200","发放优酷会员成功。绑定手机号:"+phone);
    }
}


/*******************************************************
 *
 * 客户端
 * 发放奖品
 *
 *******************************************************/
public class DeliverController {

    public ResponseResult awardToUser(AwardInfo awardInfo){
        IFreeGoods freeGoods = FreeGoodsFactory.getInstance(awardInfo.getAwardTypes());
        return freeGoods.sendGoods(awardInfo);
    }
}


             

六、简单工厂模式优缺点

       5.1)简单工厂模式优点

                1)封装了创建对象的过程,可以通过参数直接获取对象,把对象的创建与业务

                      逻辑分开,避免了后边可能修改业务代码的问题。

                 2)提高了代码的可扩展性,如果要增加新产品,则只需要修改工厂类,不需要

                      修改源代码,降低了客户端修改代码的可能性,更容易扩展。

        5.2)简单工厂模式缺点

                 1)在增加新产品的时候还需要修改代码,违背了开闭原则;

                      注意:

                             “开闭原则”:对扩展开放,对修改关闭,并不是说旧代码一点也不能

                              修改;在实际开发中,很多时候业务扩展对旧代码完全不修改是很难

                              办到的;如果修改的代码量很少的话,还是可以接受的。

  • 9
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值