IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> 【设计模式】简单工厂模式 -> 正文阅读

[Java知识库]【设计模式】简单工厂模式

微信搜索:码农StayUp
主页地址:https://gozhuyinglong.github.io
源码分享:https://github.com/gozhuyinglong/blog-demos

简单工厂模式(Simple Factory Pattern)是工厂模式的一种简单实现方式,它属于创建型模式。简单工厂模式中只有一个“工厂”类,它可以根据类型来创建不同的“产品”实例。

也就是说,创建“产品”的实例,不再是通过直接new的方式,而是通过“工厂”进行生成,客户端无需关心实例创建的细节。

在简单工厂模式中,创建“产品”实例的方法通常是静态方法,因此简单工厂模式又叫作静态工厂方法模式(Static Factory Method Pattern)。

简单工厂模式并不在GoF 23种设计模式之列,有资料说它不是一种设计模式,而更像是一种编程习惯。但由于它逻辑简单,经常被使用,还是有必要深入了解一下的。

角色

通过上面的介绍可以看出,简单工厂模式主要有下面几种角色:

  • 抽象产品(Product):它是所有具体产品的公共接口。在工厂类中的创建产品实例方法,应该返回此接口(面向接口编程)。
  • 具体产品(ConcreteProduct):是工厂类中创建的对象。
  • 工厂(Factory):它是简单工厂模式的核心类,负责实现所有产品实例的创建逻辑。它有一个通过类型来创建产品实例的方法,该方法通常是静态的。
  • 客户端(Client):上面的工厂就是为客户端服务的,客户端调用工厂类中方法,来获取产品实例。

下面是该模式的UML类图:

实现

下面通过一个手机的案例,来讲解该模式的实现。

抽象产品接口:Phone

创建一个手机接口,它可以打电话和发短信。

/**
 * 手机接口
 */
public interface Phone {

    /**
     * 打电话
     */
    void call();

    /**
     * 发短信
     */
    void sendSMS();
}

两个具体产品类:XiaomiPhone和RedmiPhone

为手机接口创建两个实现类,一个是小米手机,一个是红米手机,当然也可以有更多的实现类。

/**
 * 小米手机实现类
 */
public class XiaomiPhone implements Phone {
    @Override
    public void call() {
        System.out.println("使用小米手机打电话");
    }

    @Override
    public void sendSMS() {
        System.out.println("使用小米手机发短信");
    }
}

/**
 * 红米手机实现类
 */
public class RedmiPhone implements Phone {
    @Override
    public void call() {
        System.out.println("使用红米手机打电话");
    }

    @Override
    public void sendSMS() {
        System.out.println("使用红米手机发短信");
    }
}

工厂类:PhoneFactory

创建一个手机工厂类,该类可以根据手机类型获取手机实例。

注:在通常情况下,这个类型应该使用枚举类来表示

/**
 * 手机工厂类
 */
public class PhoneFactory {

    /**
     * 根据类型获取手机
     *
     * @param type
     * @return
     */
    public static Phone createPhone(String type) {
        switch (type) {
            case "xiaomi":
                return new XiaomiPhone();
            case "redmi":
                return new RedmiPhone();
            default:
                return null;
        }
    }
}

客户端类:Client

创建一个客户端类,用于调用手机工厂类,来生成手机实例。

/**
 * 客户端类
 */
public class Client {

  public static void main(String[] args) {
        System.out.println("================小米手机================");
        Phone xiaomiPhone = PhoneFactory.createPhone("xiaomi");
        if (xiaomiPhone != null) {
            xiaomiPhone.call();
            xiaomiPhone.sendSMS();
        }

        System.out.println("================红米手机================");
        Phone redmiPhone = PhoneFactory.createPhone("redmi");
        if (redmiPhone != null) {
            redmiPhone.call();
            redmiPhone.sendSMS();
        }

    }
}

运行结果

运行客户端main方法,会打印如下内容:

================小米手机================
使用小米手机打电话
使用小米手机发短信
================红米手机================
使用红米手机打电话
使用红米手机发短信

优缺点

优点:

  • 使对象的创建和使用分离,对象的创建交给专门的工厂类负责,客户端不需要关心是怎么创建的,只关心如何使用就行了。
  • 只有一个工厂类,逻辑清晰,便于理解。

缺点:

  • 工厂类不够灵活,每增加一个产品,就要修改工厂类,代码耦合性太高。
  • 工厂类负责所有产品的创建,违反了单一职责

典型应用

java.util.Calendar类是Java自带的日历抽象类,它是典型的简单工厂模式。

该类的角色,即是工厂,也是抽象产品。它有三个子类:BuddhistCalendarJapaneseImperialCalendarGregorianCalendar ,这个三子类是具体产品角色。

Calendar类有多个获取实例的重载方法getInstance(),但最终都会调用createCalendar()方法,来生成具体的实例。从下面代码片段也可以看出,它是根据不同的区域类型,来创建对应实例的。

// 获取默认时区和区域的日历实例
public static Calendar getInstance()
{
    return createCalendar(TimeZone.getDefault(), Locale.getDefault(Locale.Category.FORMAT));
}

// 获取指定时区和默认区域的日历实例
public static Calendar getInstance(TimeZone zone)
{
    return createCalendar(zone, Locale.getDefault(Locale.Category.FORMAT));
}

// 获取默认时区和指定区域的日历实例
public static Calendar getInstance(Locale aLocale)
{
    return createCalendar(TimeZone.getDefault(), aLocale);
}

// 获取指定时区和指定区域的日历实例
public static Calendar getInstance(TimeZone zone, Locale aLocale)
{
    return createCalendar(zone, aLocale);
}

// 真正获取日历实例的方法
private static Calendar createCalendar(TimeZone zone, Locale aLocale)
{
    // ......
    Calendar cal = null;

    if (aLocale.hasExtensions()) {
        String caltype = aLocale.getUnicodeLocaleType("ca");
        if (caltype != null) {
            switch (caltype) {
            case "buddhist":
            cal = new BuddhistCalendar(zone, aLocale);
                break;
            case "japanese":
                cal = new JapaneseImperialCalendar(zone, aLocale);
                break;
            case "gregory":
                cal = new GregorianCalendar(zone, aLocale);
                break;
            }
        }
    }
    if (cal == null) {
        if (aLocale.getLanguage() == "th" && aLocale.getCountry() == "TH") {
            cal = new BuddhistCalendar(zone, aLocale);
        } else if (aLocale.getVariant() == "JP" && aLocale.getLanguage() == "ja"
                   && aLocale.getCountry() == "JP") {
            cal = new JapaneseImperialCalendar(zone, aLocale);
        } else {
            cal = new GregorianCalendar(zone, aLocale);
        }
    }
    return cal;
}

完整代码

完整代码请访问我的Github,若对你有帮助,欢迎给个?,感谢~~🌹🌹🌹

https://github.com/gozhuyinglong/blog-demos/blob/main/design-patterns/src/main/java/io/github/gozhuyinglong/designpatterns/factory/FactorySimple.java

推荐阅读

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-02-16 12:56:41  更:2022-02-16 12:56:48 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 12:52:24-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码