Java设计模式——简单工厂模式原理与应用

1、 简单工厂模式定义

提供一个创建对象实例的功能,而无须关心其具体实现。被创建实例的类型可以是接口、抽象类,也可以是具体的类。

2、简单工厂包含以下角色

  • CarFactory:生产汽车的简单工厂
    生产汽车的简单工厂负责实现生产汽车的所有逻辑
  • Car:抽象汽车产品
    抽象汽车产品是所有汽车的父类,负责描述所有汽车的属性和行为
  • Porsche:保时捷汽车
    具体产品是生产的保时捷汽车。
  • Ferrari:法拉利汽车
    具体产品是生产的法拉利汽车。

3、简单工厂模式用UML类图表示

在这里插入图片描述

4、简单工厂模式用代码表示

  • 车辆接口
/**
 * 汽车接口
 */
public interface Car {

    void run();
}
  • 保时捷
/**
 * 保时捷
 */
public class Porsche implements Car {

    @Override
    public void run() {
        System.out.println("Porsche running ...");
    }
}
  • 法拉利
public class Ferrari implements Car {

    @Override
    public void run() {
        System.out.println("Ferrari running ...");
    }
}
  • 车辆工厂
/**
 * 车辆工厂
 *
 */
public class CarFactory {

    public static Car getCar(String carType) {

        switch (carType) {
            case "ferrari":
                return new Ferrari();
            case "porsche":
                return new Porsche();
            default:
                throw new RuntimeException("无此车辆");
        }
    }
}
  • 收到客户订单,开始生产
/**
 * 简单工厂模式
 *
 */
public class SimpleFactoryPattern {

    public static void main(String[] args) {

        // 第一天开法拉利
        String carType = "ferrari";
        CarFactory.getCar(carType).run();

        // 第二天开保时捷
        carType = "porsche";
        CarFactory.getCar(carType).run();

        System.out.println("Happiness is so simple");
    }
}
  • 执行结果:
    在这里插入图片描述

5、工厂模式优缺点

优点:

  • 封装
    简单工厂帮助我们实现组件的封装,让组件外部实现面向接口编程

  • 解耦
    通过简单工厂,客户端和具体的实现逻辑解耦

缺点:

  • 违反开闭原则

  • 增加扩展的复杂度
    添加新产品需要修改工厂逻辑,在产品类型较多时,造成工厂过于臃肿,增加复杂度。

6、何时选用简单工厂

  • 封装具体实现,让客户端通过接口操作具体实现。
  • 想把创建对象的具体职责集中管理和控制

7、简单工厂模式的应用

  • 简单工厂模式在Java中的应用
    在这里插入图片描述
    public static Calendar getInstance()
    {
        return createCalendar(TimeZone.getDefault(), Locale.getDefault(Locale.Category.FORMAT));
    }

    public static Calendar getInstance(TimeZone zone,
                                       Locale aLocale)
    {
        return createCalendar(zone, aLocale);
    }

    private static Calendar createCalendar(TimeZone zone,
                                           Locale aLocale)
    {
        CalendarProvider provider =
            LocaleProviderAdapter.getAdapter(CalendarProvider.class, aLocale)
                                 .getCalendarProvider();
        if (provider != null) {
            try {
                return provider.getInstance(zone, aLocale);
            } catch (IllegalArgumentException iae) {
                // fall back to the default instantiation
            }
        }

        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 no known calendar type is explicitly specified,
            // perform the traditional way to create a Calendar:
            // create a BuddhistCalendar for th_TH locale,
            // a JapaneseImperialCalendar for ja_JP_JP locale, or
            // a GregorianCalendar for any other locales.
            // NOTE: The language, country and variant strings are interned.
            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;
    }

mark,欢迎评论交流

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值