首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >轻松看懂java设计模式简单工厂模式

轻松看懂java设计模式简单工厂模式

作者头像
好好学java
发布于 2018-09-21 07:41:30
发布于 2018-09-21 07:41:30
62700
代码可运行
举报
运行总次数:0
代码可运行

一、什么是简单工厂模式

简单工厂模式属于类的创建型模式,又叫做静态工厂方法模式。通过专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。

二、简单工厂模式的角色和职责

1.工厂(Creator)角色简单工厂模式的核心,它负责实现创建所有实例的内部逻辑。工厂类可以被外界直接调用,创建所需的产品对象。

2.抽象(Product)角色简单工厂模式所创建的所有对象的父类,它负责描述所有实例所共有的公共接口。

3.具体产品(Concrete Product)角色简单工厂模式所创建的具体实例对象

三、简单工厂模式的UML图

sports:抽象角色

Basketball和Football:具体产品角色

sportsFactory:工厂角色

四、简单工厂模式代码

这个例子,用运动作为抽象角色,足球和篮球作为具体的产品角色来讲解,下面看具体代码。

首先我们创建一个抽象类sports,同时有一个运动的方法

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public interface Sports {
    /*
     * 运动
     */
    public void play();
}

然后,定义了一个足球类篮球类,同样有运动方法

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class Basketball implements Sports{
    /*
     * 运动
     */
    public void play(){
        System.out.println("打篮球...");
    }
}
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class Football implements Sports{
    /*
     * 运动
     */
    public void play(){
        System.out.println("踢足球啦...");
    }
}

最后写一个工厂类,用来创造足球运动篮球运动

这里创建的方式有很多种方式,我们从简单的开始,逐步优化代码。

4.1、单独创建实例方法
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class SportsFactory {
    /*
     * 获得Basketball类的实例

    public static  Sports getBasketball() {
        return new Basketball();
    }

    /*
     * 获得Football类实例
     */
    public static Sports getFootball() {
        return new Football();
    }
}

这种方法,直接用两个不同的方法直接创建两个实例对象。

4.2、逻辑判断的方式
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class SportsFactory {

    /*
     * getSports方法,获得所有产品对象
     */
    public static Sports getSports(String type) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
        if(type.equalsIgnoreCase("Basketball")) {
            return Basketball.class.newInstance();

        } else if(type.equalsIgnoreCase("Football")) {
            return Football.class.newInstance();
        } else {
            System.out.println("找不到相应的实例化类");
            return null;
        }

    }
}

先传入一个类型参数,然后判断,再用反射的方式返回对象。

前面这两种方式都不是最优的方式,因为他们都违背了开闭原则

开闭原则定义:一个软件实体如类、模块和函数应该对扩展开放,对修改关闭。

开放-封闭原则的意思就是说,你设计的时候,时刻要考虑,尽量让这个类是足够好,写好了就不要去修改了,如果新需求来,我们增加一些类就完事了,原来的代码能不动则不动。这个原则有两个特性,一个是说“对于扩展是开放的”,另一个是说“对于更改是封闭的”。面对需求,对程序的改动是通过增加新代码进行的,而不是更改现有的代码。这就是“开放-封闭原则”的精神所在。

下面,我们再优化一下。

4.3、反射实现方式
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class SportsFactory {

    /*
     * getSports方法,获得所有产品对象
     */
    public static Sports getSports(String type) throws InstantiationException, IllegalAccessException, ClassNotFoundException {

        Class Sports = Class.forName(type);
        return (Sports) Sports.newInstance();

    }
}

这种方法,通过反射的方式实现,不管我们还需要扩展什么其他功能都不用再更改这个工厂类的代码了,所以就符合开闭原则了。

五、测试

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class MainClass {
    public static void main(String[] args) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
    //方法一测试
//        //实例化一个Basketball
//        Basketball Basketball = new Basketball();
//        //实例化一个Football
//        Football Football = new Football();
//        
//        Basketball.play();
//        Football.play();

        //方法二测试
//        //实例化一个Basketball,用到了多态
//        Sports Basketball = new Basketball();
//        Sports Football = new Football();
//        Basketball.play();
//        Football.play();

//        //实例化一个Basketball
//        Sports Basketball = SportsFactory.playBasketball();
//        Sports Football = SportsFactory.playFootball();
//        Basketball.play();
//        Football.play();

        //方法三测试
        Sports Basketball = SportsFactory.getSports("Basketball");
        Sports Football = SportsFactory.getSports("Football");
        Basketball.play();
        Football.play();

    }
}

运行结果:

六、简单工厂模式应用场景

优点:工厂类是整个模式的关键.包含了必要的逻辑判断,根据外界给定的信息,决定究竟应该创建哪个具体类的对象.通过使用工厂类,外界可以从直接创建具体产品对象的尴尬局面摆脱出来,仅仅需要负责“消费”对象就可以了。而不必管这些对象究竟如何创建及如何组织的.明确了各自的职责和权利,有利于整个软件体系结构的优化

缺点:由于工厂类集中了所有实例的创建逻辑,违反了开闭原则,将全部创建逻辑集中到了一个工厂类中;它所能创建的类只能是事先考虑到的,如果需要添加新的类,则就需要改变工厂类了。当系统中的具体产品类不断增多时候,可能会出现要求工厂类根据不同条件创建不同实例的需求.这种对条件的判断和对具体产品类型的判断交错在一起,很难避免模块功能的蔓延,对系统的维护和扩展非常不利;

觉得有用就转发分享一下吧

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-09-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 好好学java 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
【每周小结】2023-Week4
在面向对象开发的场景下,我们经常会写高度重复的Go代码。为了帮助大家形成一定的方法论,这里以一个具体场景为例,分享我的三个技巧。
junedayday
2023/02/18
2540
【每周小结】2023-Week4
【每周小结】2023-Week3
本周,我的工作模式正式从远程办公回到了现场办公。恰逢过年,整体工作节奏放缓,切换的过程很顺畅。
junedayday
2023/02/18
5500
【每周小结】2023-Week3
【每周小结】2023-Week6
本周Go语言1.20版本正式发布,我们对其重要特性进行简单分析,为后续掌握Go的发展脉络做好铺垫。
junedayday
2023/02/18
3080
【每周小结】2023-Week6
【每周小结】2023-Week5
Go官方最近开放了一个问卷,里面收集了用户的相关意见。整个问卷是全英文的,全部填完需要15min左右,有很多是收集用户背景与满意度的常规问题。
junedayday
2023/02/18
2920
【每周小结】2023-Week5
Spring:声明式事务
Spring 框架对 JDBC 进行封装,使用 JdbcTemplate 方便实现对数据库操作
愷龍
2023/02/10
7560
Spring:声明式事务
【每周小结】2023-Week7
在Go语言开发的过程中,我们或多或少会引入并发模式,常见的如go、channel、sync.WaitGroup等。这些并发原语使用起来很方便,但常常会阻碍相关代码的单元测试,如依赖的channel发生阻塞,mutex被锁等,导致想验证的重要代码根本跑不到。
junedayday
2023/02/18
3190
【每周小结】2023-Week7
手把手教你整合最优雅SSM框架:SpringMVC + Spring + MyBatis
本文发表于2016年6月,写于作者学生时期。文中使用到的技术和框架可能不是当下最佳实践,甚至很不“优雅”。但对于刚接触JavaEE和Spring的同学来说,还是能有很多收获的,大牛轻拍= =
全栈程序员站长
2022/07/31
4490
手把手教你整合最优雅SSM框架:SpringMVC + Spring + MyBatis
21.<基于Spring图书管理系统②(图书列表+删除图书+更改图书)(非强制登录版本完结)>
针对先上线的程序而言 比如后端接口从A改成了B。(前端接口也要修改) 如果后端先上线:前端调用就会出错,找不到A接口 如果前端先上线,前端调用依然会报错,找不到B接口。因为此时后端还没上线。 正确的做法:后端对之前的接口进行兼容,如果兼容则同时存在A和B接口 实现方式 实现开闭原则的方式主要包括:
用户11288958
2024/11/21
1810
21.<基于Spring图书管理系统②(图书列表+删除图书+更改图书)(非强制登录版本完结)>
Spring-JDBCTemplate
今天开始学习我自己总结的 Java-学习路线 中的《Spring-JDBCTemplate》,小简从 0 开始学 Java 知识,并不定期更新所学笔记,期待一年后的蜕变吧!
小简
2023/01/04
4000
springboot第18集:SpringMVC我的春天
MVC是一种常用的软件设计规范,它将一个应用程序分为三个不同的部分:模型(Model)、视图(View)、控制器(Controller)。这三个部分相互协作,共同完成应用程序的各项任务。
达达前端
2023/10/08
2080
springboot第18集:SpringMVC我的春天
AIDL源码解析in、out和inout
为什么会想写这篇文章,只因为一个error idl.exe E 4928 5836 type_namespace.cpp:130] 'Book' can be an out type, so you must declare it as in, out or inout. 看过上一篇文章Android:IPC之AIDL的学习和总结的同学都知道这是因为在AIDL文件中使用非常规类型作为参数传递的时候没有标记指向tag,那么到底为什么会是这样子的呢,作为一个好奇宝宝我想好好看看。
静默加载
2020/05/29
2K0
原分布式系统架构实战demo:SSM+Dubbo
        对于传统的单一构架,也就是打成的war或者ear包部署在同一个Web容器里的构架,它虽然开发、测试、部署简单,但随着业务的不断发展,维护成本增加,可扩展性差,而且一台Tomcat的并发
我叫刘半仙
2018/04/16
2.7K0
原分布式系统架构实战demo:SSM+Dubbo
Spring:声明式事务
Spring 框架对 JDBC 进行封装,使用 JdbcTemplate 方便实现对数据库操作
愷龍
2023/02/09
7510
一文解读spring中事务管理
数据库事务( transaction)是访问并可能操作各种数据项的一个数据库操作序列,这些操作要么全部执行,要么全部不执行,是一个不可分割的工作单位。事务由事务开始与事务结束之间执行的全部数据库操作组成。
一个风轻云淡
2023/10/15
3640
一文解读spring中事务管理
初步使用Druid连接池+代码示例:对图书进行增删改查
1.创建数据库,向里面添加数据 数据库名:BookShop #用户表 CREATE TABLE USER( id INT(11) PRIMARY KEY AUTO_INCREMENT, username VARCHAR(20) NOT NULL, PASSWORD VARCHAR(32) NOT NULL, realname VARCHAR(20), email VARCHAR(50) NOT NULL, gender VARCHAR(50) NOT NULL, flag INT(11), role IN
2020/10/23
1K0
初步使用Druid连接池+代码示例:对图书进行增删改查
手把手整合SSM框架
目录包括 main、resources、mapper、webapp,不一一介绍,不熟悉查看前面文章。
JavaPub
2020/07/12
7371
手把手整合SSM框架
Spring6 JdbcTemplate和事务
Spring 框架对 JDBC 进行封装,使用 JdbcTemplate 方便实现对数据库操作
鱼找水需要时间
2023/06/17
4080
Spring6 JdbcTemplate和事务
购物车的实现(jsp的session+Java的Map的结合)
1:电商如此发达的现在,作为一个web开发程序猿,如果不会写购物车,真是有点不好意思找工作。所以抓紧练习啊,从上篇博客中抽离出如何实现购物车的功能。 2:首先需要理解购物车实现的一些基本步骤。   2
别先生
2018/01/02
5.1K1
购物车的实现(jsp的session+Java的Map的结合)
Java 编程进阶实操之工具集整合组件封装方法与使用指南详解
下面我将为你提供Hutool工具集和图书管理系统相关组件的封装方法及使用示例,帮助你更好地应用这些技术。
啦啦啦191
2025/05/31
1130
Java 编程进阶实操之工具集整合组件封装方法与使用指南详解
【愚公系列】2023年10月 Java教学课程 162-Spring MVC框架的SSM整合
SSM整合指的是将Spring、Spring MVC、MyBatis三个框架集成在一起,以便更好地开发Java Web应用程序。它们之间的整合可以提高开发效率,简化配置,减少重复代码,提高代码重用性。Spring作为IoC容器和AOP框架,可以管理Bean的生命周期,简化代码结构;Spring MVC作为Web框架,可以方便地处理请求和响应;MyBatis作为持久层框架,可以简化数据库操作。SSM整合后,可以通过注解来简化配置,使开发更加高效快速。
愚公搬代码
2025/05/28
910
【愚公系列】2023年10月 Java教学课程 162-Spring MVC框架的SSM整合
相关推荐
【每周小结】2023-Week4
更多 >
交个朋友
加入腾讯云官网粉丝站
蹲全网底价单品 享第一手活动信息
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档