一天一个设计模式:简单工厂模式

存在的目的:

  解耦,在a类中如何想使用b类的某种功能,必须new 一个b对象出来,假如有一个c类,跟b实现了同一个接口,后续想要将b替换成c就需要更改在a中的代码,以此类推,代码的耦合度会随着项目复杂度越来越高,维护成本也会越来越高。

  使用简单工厂,使a类与工厂做耦合,然后工厂来提供接口的实现类即可,这样只需要对工厂进行维护就可以实现替换了成功解耦。

核心思想:

  不在乎工厂是如何生产产品的,而是将产品的生产与产品的使用分开。        注:这里的产品指的是功能类的对象

实际的应用:

  jdk中的线程池:ThreadPoolExecutor,根据自己的需求传入corePoolSize、maximumPoolSize、keepAliveTimem、keepAliveTimem、unit、threadFactory、handler这几个参数,new一个指定的ThreadPoolExecutor出来。

  jdk提供了Executors这个类,让开发者对线程池的使用与生产分离开,开发者只需要调用不同的方法就可以获取到不同的线程池,开发者不用关心线程池的实现细节,只需要调用api即可获取不同的线程池。

      如:Executors.newSingleThreadExecutor()        获取单线程的线程池              Executors.newCachedThreadPool()        获取无界线程池

优点:     简单优化了软件体系结构,明确了各自功能模块的职责和权力,     通过工厂类,外界不需要直接创建具体产品对象,只需要负责消费,不需要关心内部如何创建对象。 缺点:     如果只是使用简单的if else这样来做生产,随着产品的增多,势必要对工厂类进行不断的维护,     使用反射的工厂效率会低一些。

实现案例

以登录系统为例,支持多种登录体系:口令登录、域登录。那么需要建立一个各种登录方式都适合的接口,uml图如下:

登录接口:

public interface Login {
    //登录验证
    public boolean verify(String name , String password);
}

域登录:

public class DomainLogin implements Login {

    @Override
    public boolean verify(String name, String password) {
        // TODO Auto-generated method stub
        /**
         * 业务逻辑
         */
        return true;
    }

}

口令登录:

public class PasswordLogin implements Login {

    @Override
    public boolean verify(String name, String password) {
        // TODO Auto-generated method stub
        /**
         * 业务逻辑
         */
        return true;
    }

}

工厂类LoginManager,根据需求创建对象,如果不合法就跑出异常,会返回一个Runtime异常

public class LoginManager {
    public static Login factory(String type){
        if(type.equals("password")){
            
            return new PasswordLogin();
            
        }else if(type.equals("passcode")){
            
            return new DomainLogin();
            
        }else{
            /**
             * 这里抛出一个自定义异常会更恰当
             */
            throw new RuntimeException("没有找到登录类型");
        }
    }
}

测试类:

public class Test {
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        String loginType = "password";
        String name = "name";
        String password = "password";
        Login login = LoginManager.factory(loginType);
        boolean bool = login.verify(name, password);
        if (bool) {
            /**
             * 业务逻辑
             */
        } else {
            /**
             * 业务逻辑
             */
        }
    }
}

实际上的结构图:

基于上面的,使用反射来实现

public class LoginManager {
    public static Login factory(String path) {
        Class<?> c = Class.forName(fruitPath);
        return (Fruit)c.newInstance();
    }   
}

这样仅需要控制入参就可以获取对应的实例了,不需要那么多if else了结构上更加清爽。

 参考链接:

https://www.cnblogs.com/java-my-life/archive/2012/03/22/2412308.html

https://www.cnblogs.com/xrq730/p/4902597.html

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏WindCoder

Java设计模式学习笔记—桥接模式

文章最后“Java设计模式笔记示例代码整合”为本系列代码整合,所有代码均为个人手打并运行测试,不定期更新。本节内容位于其Bridge包(package)中。

10610
来自专栏iKcamp

翻译连载 | 第 10 章:异步的函数式(下)-《JavaScript轻量级函数式编程》 |《你不知道的JS》姊妹篇

原文地址:Functional-Light-JS 原文作者:Kyle Simpson-《You-Dont-Know-JS》作者 第 10 章:异步的函数式(下)...

20350
来自专栏开源优测

[快学Python3]日期和时间处理

概述 在python中, date、time、datetime类提供了一系列处理日期、时间和时间间隔的函数。 在Python里我们大致可以把其实现日期时间类分为...

29470
来自专栏申龙斌的程序人生

零基础学编程002:Hello World

昨天介绍了codecademy在线学编程的网站,不知道大家动手试验了没有?是不是太简单,一下子就完成了许多练习? 第一课的内容只有一条输出语句,点击保存并提交...

29570
来自专栏腾讯Bugly的专栏

如何定位Obj-C野指针随机Crash(三):如何让Crash自报家门

本文主要介绍如何利用OC Runtime的特性,让OC野指针对象主动抛出自己的信息,秒杀某些全系统栈Crash。 ? 陈其锋,腾讯SNG即通产品部音视频技术中心...

94040
来自专栏walterlv - 吕毅的博客

应该抛出什么异常?不应该抛出什么异常?(.NET/C#)

2018-02-04 13:25

19320
来自专栏听雨堂

【4】通过简化的正则表达式处理字符串

阅读目录 常见字符串操作 使用正则表达式处理字符串 “前后限定”查找目标 自动处理转义字符 界定串的通用化 多个目标的匹配 进一步扩展 结论 在...

25860
来自专栏小詹同学

为什么你的Python代码质量如此不堪……

作者:笑虎(Python爱好者,关注爬虫、数据分析、数据挖掘、数据可视化等) 原文链接:http://codebay.cn/post/7953.html

20440
来自专栏CSDN技术头条

C#秒杀Java的五个不可替代的特性,完美的编程语言并不存在

如果我们可以同时拥有 C# 和 Java 世界的最好特性,那会是什么样呢? 完美的编程语言并不存在,我希望我们可以在这一点上达成一致。开发新语言往往是为了克服...

261100
来自专栏编程

Shell 中的命令替换及参数扩展

今天和大家分享的主要是 “命令替换” 以及 “参数扩展” 。 -- 季文康 本文导航 ◈ 前言 00% ◈ 什么是命令替换 14% ◈ 1、一层 SHELL 嵌...

21890

扫码关注云+社区

领取腾讯云代金券