我就问你,会不会工厂模式?(上)

简介: 简单工厂模式(Simple Factory Pattern)是指由一个工厂对象决定创建出哪一种产品类的实例。简单工厂适用于工厂类负责创建的对象较少的场景,且客户端只需要传入工厂类的参数,对于如何创建对象的逻辑不需要关心。

简单工厂

简单工厂模式(Simple Factory Pattern)是指由一个工厂对象决定创建出哪一种产品类的实例。简单工厂适用于工厂类负责创建的对象较少的场景,且客户端只需要传入工厂类的参数,对于如何创建对象的逻辑不需要关心。

接下来我们来看代码,还是以课程为例。我们定义一个课程标准 ICourse 接口:

public interface ICourse {
    //录制视频
    void record();
}

创建一个 Java 课程的实现 JavaCourse 类:

public class JavaCourse implements ICourse {
    @Override
    public void record() {
        System.out.println("录制java视频");
    }
}

看客户端调用代码,一般我们会这样写:

public class SimpleFactoryTest {
    public static void main(String[] args) {
        ICourse course = new JavaCourse();
        course.record();
    }
}

看上面的代码,父类 ICourse 指向子类 JavaCourse 的引用,应用层代码需要依赖JavaCourse,如果业务扩展,我继续增加 PythonCourse 甚至更多,那么我们客户端的依赖会变得越来越臃肿。因此,我们要想办法把这种依赖减弱,把创建细节隐藏。虽然目前的代码中,我们创建对象的过程并不复杂,但从代码设计角度来讲不易于扩展。现在,我们用简单工厂模式对代码进行优化。先增加课程 PythonCourse 类:

public class PythonCourse implements ICourse {
    @Override
    public void record() {
        System.out.println("录制Python视频");
    }
}

创建 CourseFactory 工厂类:

public class CourseFactory {
    public static ICourse create(String name){
        if("java".equals(name)){
            return new JavaCourse();
        }else if("python".equals(name)){
            return new PythonCourse();
        }else {
            return null;
        }
    }
}

修改测试代码:

public class SimpleFactoryTest {
    public static void main(String[] args) {
        //ICourse course = new JavaCourse();
        ICourse course = CourseFactory.create("java");
        course.record();
    }
}

现在客户端调用是不是就简单了呢,但如果我们业务继续扩展,要增加前端课程,那么工厂中的 create()就要根据产品的增加每次都要修改代码逻辑。不符合开闭原则。因此,我们对简单工厂还可以继续优化,可以采用反射技术:

public class CourseFactory {
    public static ICourse create(String className){
        //这里没有引入springUtil相关的jar包,也没有自己封装,将就吧
        if(className != null && !"".equals(className)){
            try {
                return (ICourse) Class.forName(className).newInstance();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return null;
    }
}

修改测试代码:

public class SimpleFactoryTest {
    public static void main(String[] args) {
        //ICourse course = new JavaCourse();
        //ICourse course = CourseFactory.create("java");
        ICourse course = CourseFactory.create("com.cl.factory.simplefactory.JavaCourse");
        course.record();
    }
}

优化之后,产品不断丰富不需要修改 CourseFactory 中的代码。但是,有个问题是,方法参数是字符串,可控性有待提升,而且还需要强制转型。我们再修改一下代码:

public class CourseFactory {
    public static ICourse create(Class<? extends ICourse> clazz){
        if(clazz != null){
            try {
                return clazz.newInstance();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return null;
    }
}

优化测试代码:

public class SimpleFactoryTest {
    public static void main(String[] args) {
        //ICourse course = new JavaCourse();
        //ICourse course = CourseFactory.create("java");
        //ICourse course = CourseFactory.create("com.cl.factory.simplefactory.JavaCourse");
        ICourse course = CourseFactory.create(JavaCourse.class);
        course.record();
    }
}
相关文章
|
机器学习/深度学习 传感器 自动驾驶
狂风暴雨依旧YOLO | 全新数据集,全新任务,促进极端降雨条件下目标检测的优化和发展
狂风暴雨依旧YOLO | 全新数据集,全新任务,促进极端降雨条件下目标检测的优化和发展
690 0
ThinkPHP 通用的API格式封装
本文介绍了在ThinkPHP框架中如何统一封装API返回格式的方法,包括创建状态码枚举类、编写统一格式化函数以及在BaseController和Error控制器中重写`__call`方法来处理不存在的方法或控制器调用,以实现统一的错误处理和返回格式。
ThinkPHP 通用的API格式封装
|
存储 运维 负载均衡
构建高可用性GraphRAG系统:分布式部署与容错机制
【10月更文挑战第28天】作为一名数据科学家和系统架构师,我在构建和维护大规模分布式系统方面有着丰富的经验。最近,我负责了一个基于GraphRAG(Graph Retrieval-Augmented Generation)模型的项目,该模型用于构建一个高可用性的问答系统。在这个过程中,我深刻体会到分布式部署和容错机制的重要性。本文将详细介绍如何在生产环境中构建一个高可用性的GraphRAG系统,包括分布式部署方案、负载均衡、故障检测与恢复机制等方面的内容。
642 4
构建高可用性GraphRAG系统:分布式部署与容错机制
贪吃蛇游戏(代码篇)
贪吃蛇游戏(代码篇)
358 0
|
机器学习/深度学习 人工智能 自然语言处理
软件测试中的人工智能革命:提升测试效率与质量的新篇章
随着人工智能技术的不断成熟,其在软件测试领域的应用正逐渐改变传统测试方式。本文将探讨AI在软件测试中的应用现状、优势以及面临的挑战,并通过具体案例分析展示AI如何提高测试效率和质量。最后,我们将讨论未来AI在软件测试中的发展趋势及其对人类测试工程师角色的影响。
1088 4
|
前端开发 Apache 数据库
ThinkPHP+Bootstrap简约自适应网址导航网站源码
使用 ThinkPHP+bootstrap 开发,后台采用全局 ajax 无刷新加载,前后台自适应,前台页面非常简洁适合自己收藏网站或做导航网站。
378 1
|
SQL 数据采集 数据挖掘
SQL DISTINCT关键字的使用
SQL DISTINCT关键字的使用
|
数据采集 数据安全/隐私保护 UED
芝麻代理快代理神龙代理天启代理阿布云极光代理?…选代理IP避开这几点
随着代理IP在互联网中的作用愈发重要,其不仅提升了用户体验和隐私保护,还在数据安全、网络爬虫效率、市场研究及内容分发等方面产生了深远影响。然而,如何选择合适的代理IP仍困扰许多人。本文将探讨选择代理IP时应注意的关键点:IP数量并非越多越好,关键在于纯净度与可用率;需关注带宽与速度;不能仅看价格,还需综合考量实际使用效果。通过实际测试,才能找到最适合的服务商。
|
机器学习/深度学习 人工智能 供应链
人工智能在社会中的影响与未来展望
人工智能(AI)作为一项重要的技术革新,正在深刻地改变着我们的生活方式、工作方式以及社会结构。本文旨在探讨人工智能在社会中的影响,并展望其未来发展趋势。首先,我们回顾了人工智能的发展历程,从其起源到当前的发展阶段,概述了人工智能技术的基本原理和应用领域。其次,我们分析了人工智能对各个行业的影响,包括但不限于医疗保健、金融、制造业、交通运输和教育等领域。人工智能的广泛应用使得这些行业更加智能化、高效化,但也带来了一些挑战,如就业岗位的变化、隐私安全问题等。接着,我们讨论了人工智能在社会中的伦理和道德问题,包括人工智能算法的公平性、透明性和责任问题。最后,我们展望了人工智能的未来发展,包括强化学习
805 0