设计模式之工厂模式

工厂模式其实是创建的模式,何为创建模式,就是为了方便对象的创建。拿最简单的登录来说,咱们系统需要接入,掘金、微信、QQ等三个接口,我们可以创建不同Service,在里面登录。在controller中判断是哪一个登录类型,然后进行ifelse判断,又是一大堆的ifelse。现在我们写一下相关代码。

String reqJson = JSON.toJSONString(req);
LoginRes loginRes = null;
try {
    logger.info("登录开始{}。req:{}", req.getuId(), reqJson);
    // 按照不同类型方法登录[1掘金、2微信、3QQ]
    if (req.getLoginType() == 1) {
        JuejinService juejinService = new JuejinService();
        JuejinResult juejinResult = juejinService.Login(data);
        if ("0000".equals(juejinResult.getCode())) {
            loginRes = new LoginRes("0000", "登录成功");
        } else {
            loginRes = new LoginRes("0001", JuejinResult.getInfo());
        }
    } else if (req.getLoginType() == 2) {
        WeixinService weixinService = new WeixinService();
        Boolean isSuccess = WeixinService.Login(data);
        if (isSuccess) {
            loginRes = new loginRes("0000", "登录成功");
        } else {
            loginRes = new AwardRes("0001", "登录失败");
        }
    } else if (req.getLoginType() == 3) {
        
        QQService qQService = new QQService();.
        Boolean isSuccess = qQService.Login(data);
         if (isSuccess) {
            loginRes = new loginRes("0000", "登录成功");
        } else {
            loginRes = new AwardRes("0001", "登录失败");
        }
    }
    logger.info("登录完成{}。", req.getuId());
} catch (Exception e) {
    logger.error("登录失败{}。req:{}", req.getuId(), reqJson, e);
    loginRes = new LoginRes("0001", e.getMessage());
}

return LoginRes;

这样如果我们继续加登录方法,会不断的写ifelse,同时这样看 你是不是觉得更加像 “shi”山了。
下面我们来用我们的工厂模式写一下。
首先自定义Login接口

public interface Login {

    void login(String uId, , Map<String, String> extMap) throws Exception;

}

所有登录方式、虚拟还是第三⽅,都需要通过我们的程序实现此接⼝进⾏处理,以保证最 终⼊参出参的统⼀性。 接⼝的⼊参包括; ⽤户ID、扩展字段等(再次举例子)
我们所有的无论是JuejinService WeixinService QQService 都需要实现这个接口然后再login内部进行自己的逻辑判断等等。
下面就是我们的重磅工厂了LoginFactory
再次我们进行判断。


public class LoginFactory {

    public Login getLoginService(Integer LoginType) {
        if (null == LoginType) return null;
        if (1 == LoginType) return new JuejinService();
        if (2 == LoginType) return new WeixinService();
        if (3 == LoginType) return new QQService();
        throw new RuntimeException("不存在的登录类型");
    }

}

这样是不是有条理多了。


@Test
public void test_commodity() throws Exception {
    LoginFactory loginFactory = new LoginFactory();

    // 1. Juejin
    Login loginService_1 = loginFactory.getLoginService(1);
    loginService_1.sendCommodity(data);

    // 2. Weixin
    Login loginService_2 = loginFactory.getLoginService(2);
    loginService_2.sendCommodity(data);

    // 3. QQ
    Login loginService_3 = loginFactory.getLoginService(3);
    loginService_3.login(data);

}

从上到下的优化来看,⼯⼚⽅法模式并不复杂,甚⾄这样的开发结构在你有所理解后,会发现更加简单了。 那么这样的开发的好处知道后,也可以总结出来它的优点;避免创建者与具体的产品逻辑耦合、满⾜单⼀职责,每⼀个业务逻辑实现都在所属⾃⼰的类中完成 、满⾜开闭原则,⽆需更改使⽤调⽤⽅就可以在程序中引⼊新的登录类型 。但这样也会带来⼀些问题。每次增加一个登录方式时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。这并不是什么好事。所以还需要与其他设计模式相结合,才能打造出我开文提到的让一个产品走向更好(收尾呼应点题)。

上一篇:微软采取强硬措施:从Windows清理Flash插件


下一篇:【SpringCloud-Alibaba系列教程】10.gateway网关