02-工厂模式实践

一 什么是工厂模式

       客户端不主动创建接口对象,而是由工厂来创建接口对象,将客户端和实现解耦的一种设计模式

       一般情况下,工厂模式分为三种类型:简单工厂、工厂方法和抽象工厂。在 GoF 的《设计模式》一书中,它将简单工厂模式看

作是工厂方法模式的一种特例,所以工厂模式只被分成了工厂方法和抽象工厂两类。

二 简单工厂

       假设我们有一个这样的业务场景:我们需要给登录、注册、修改密码、修改手机号码发送验证码,我们将通过不同的功能形成不同的 key 放入redis 里面。简单工厂代码如下:

public class VerifyCodeServer {
    public String getVerifyCodeKey(String function) {
        return KeyFactory.createVerifyCodeKey(function);
    }
}


public class KeyFactory {
  public static String createVerifyCodeKey(String function) {
    String verifyCodeKey = null;
    if ("login".equalsIgnoreCase(function)) {
      verifyCodeKey = "login_mobile_key:%s";
    } else if ("signup".equalsIgnoreCase(function)) {
      verifyCodeKey = "signup_mobile_key:%s";
    } else if ("modify_mobile".equalsIgnoreCase(function)) {
      verifyCodeKey = "modify_mobile_key:%s";
    } else if ("forget_password".equalsIgnoreCase(function)) {
      verifyCodeKey = "forget_password_mobile_key:%s";
    }
    return verifyCodeKey;
  }
}

       大部分工厂类都是以“Factory”这个单词结尾的,但也不是必须的,比如 Java 中的 DateFormat、Calender。除此之外,工厂类中创建对象的方法一般都是 create 开头,比如代码中的 createParser(),但有的也命名为 getInstance()、createInstance()、newInstance(),有的甚至命名为 valueOf()(比如 Java String 类的 valueOf() 函数)等等,这个我们根据具体的场景和习惯来命名就好。

三 工厂方法

       如果我们非得要将 if 分支逻辑去掉,那该怎么办呢?比较经典处理方法就是利用多态。按照多态的实现思路,对上面的代码进行重构。重构之后的代码如下所示:

public class VerifyCodeServer {
    public String getVerifyCodeKey(String function) {
        return new KeyFactoryMap().getKeyFactory(function).createVerifyCodeKey();
    }
}

public interface KeyFactory {
    String createVerifyCodeKey();
    String getFunName();
}

public class LoginKeyFactory implements KeyFactory {
    @Override
    public String createVerifyCodeKey() {
        return "login_mobile_key:%s";
    }
    @Override
    public String getFunName() {
        return "login";
    }
}

public class SignupKeyFactory implements KeyFactory {
    @Override
    public String createVerifyCodeKey() {
        return "signup_mobile_key:%s";
    }
    @Override
    public String getFunName() {
        return "signup";
    }
}

public class ForgetPasswordKeyFactory implements KeyFactory {
    @Override
    public String createVerifyCodeKey() {
        return "forget_password_mobile_key:%s";
    }
    @Override
    public String getFunName() {
        return "foregt_password";
    }
}

public class ModifyMobileKeyFactory implements KeyFactory {
    @Override
    public String createVerifyCodeKey() {
        return "modify_mobile_key:%s";
    }
    @Override
    public String getFunName() {
        return "modify_mobile";
    }
}

public class KeyFactoryMap {
    private static final Map<String, KeyFactory> factoryMap = new HashMap<>();

    public KeyFactoryMap(List<KeyFactory> list) {
        list.forEach(keyFactory -> factoryMap.put(keyFactory.getFunName(), keyFactory));
    }
    public KeyFactory getKeyFactory(String function) {
        return factoryMap.get(function);
    }
}

四 简单工厂和工厂方法使用场景

       如果代码逻辑比较简单,不复杂用简单工厂就好;如果代码逻辑负责,需要拆分成多个类和函数才能更清晰用工厂方法。

五 工厂模式好处

  • 封装变化:创建逻辑有可能变化,封装成工厂类之后,创建逻辑的变更对调用者透明。
  • 代码复用:创建代码抽离到独立的工厂类之后可以复用。
  • 隔离复杂性:封装复杂的创建逻辑,调用者无需了解如何创建对象。
  • 控制复杂度:将创建代码抽离出来,让原本的函数或类职责更单一,代码更简洁。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值