设计模式之简单工厂模式

什么是简单工厂模式

    工厂模式是最常用的一类创建型设计模式。它不属于GoF 23种设计模式。它的设计思想很简单,基本流程:         首先将需要创建的不同对象封装到不同的具体产品类中,将公共部分进行抽取后封装到一个抽象产品类中,每一个具体产品类都是抽象产品类的子类。然后提供一个工厂类用于创建各种产品,在工厂类中提供一个创建产品类的方法,该方法可以根据所传入的参数不同创建不同的具体产品对象,客户端只需要调用工厂类的工厂方法。     简单工厂模式是说定义一个工厂类,它可以根据参数的不同返回不同类的实例,被创建的实例通常都具有共同的父类。因为在简单工厂模式中用于创建实例的方法是静态方法,因此简单工厂模式又称为静态工厂方法模式。     简单工厂模式包含以下几个角色:         Factory(工厂角色):即工厂类,是简单工厂模式的核心,负责实现创建所有产品实例的内部逻辑。工厂类可以被客户单直接调用创建所需要的产品对象,在工厂类中提供了静态的工厂方法返回抽象的产品类型。         Product(抽象产品角色):工厂类所创建的的所有对象的父类,封装了各种产品对象的公共方法。         ConcreteProduct(具体产品角色):是简单工厂模式的创建目标,所有被创建的对象都充当这个角色的某个具体类的实例。每一个具体产品角色都继承了抽象产品角色,并实现了抽象产品中声明的抽象方法。

简单工厂模式的优缺点

优点
  1. 工厂类包含必要的判断逻辑,可以决定在声明时候创建哪一个产品实例,客户端可以免除直接创建产品对象的职责,简单工厂模式实现了对象的创建和使用的分离。
  2. 客户端无需知道所创建的具体产品类的类名,只需要知道具体产品类所对应的参数即可。
缺点
  1. 由于工厂类集中了所有产品的创建逻辑,职责过重,一旦不能正常工作,整个系统都要受到影响。
  2. 使用简单工厂模式必然会增加系统中类的个数,增加了系统的复杂性。
  3. 系统扩展难,一旦添加新产品就不得不修改工厂逻辑,在产品类型较多时,有可能造成工厂逻辑过于复杂。
  4. 简单工厂模式由于使用了静态工厂方法,造成工厂角色无法形成无法形成基于继承的等级结构。

简单工厂模式的应用场景

  1. 工厂类负责创建的对象比较少,由于创建的对象比较少,不会造成工厂方法中的业务逻辑太复杂。
  2. 客户端只知道传入工厂类的参数,对于如何创建对象不关心。

简单工厂模式案例

/**
 * 抽象产品
 */
public interface SweepingRobot {

    void orderRobot();

}

/**
 * 具体产品
 */
public class XiaoMiRobot implements SweepingRobot {
    @Override
    public void orderRobot() {
        System.out.println("购买小米扫地机器人。");
    }
}

/**
 * 具体产品
 */
public class EcovacsRobot implements SweepingRobot {
    @Override
    public void orderRobot() {
        System.out.println("购买科沃斯扫地机器人.");
    }
}

/**
 * 工厂类
 */
public class RobotSimpleFactory {

    public static SweepingRobot orderRobot(Integer brand) {
        switch (brand) {
            case 1:
                return new XiaoMiRobot();
            case 2:
                return new EcovacsRobot();
            default:
                return null;
        }
    }

}

public class Client {
    public static void main(String[] args) {
        SweepingRobot sweepingRobot = RobotSimpleFactory.orderRobot(1);
        sweepingRobot.orderRobot();
    }
}

![在这里插入图片描述](https://img-blog.csdnimg.cn/6ad3c031200948efb86e0985346f9a47.png#pic_center)

简单工厂模式在源码中的应用

Calendar

/**
 * Calendar 是抽象产品,也充当了工厂类
 **/
public abstract class Calendar implements Serializable, Cloneable, Comparable<Calendar> {
    /**
     * Converts the current calendar field values in {@link #fields fields[]}
     * to the millisecond time value
     * {@link #time}.
     *
     * @see #complete()
     * @see #computeFields()
     */
    protected abstract void computeTime();

    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;
    }
    ......
}

/**
 * 具体产品
 **/
class JapaneseImperialCalendar extends Calendar {
    protected void computeTime() {
        // In non-lenient mode, perform brief checking of calendar
        // fields which have been set externally. Through this
        // checking, the field values are stored in originalFields[]
        // to see if any of them are normalized later.
        if (!isLenient()) {
            if (originalFields == null) {
                originalFields = new int[FIELD_COUNT];
            }
            for (int field = 0; field < FIELD_COUNT; field++) {
                int value = internalGet(field);
                if (isExternallySet(field)) {
                    // Quick validation for any out of range values
                    if (value < getMinimum(field) || value > getMaximum(field)) {
                        throw new IllegalArgumentException(getFieldName(field));
                    }
                }
                originalFields[field] = value;
            }
        }
        ......
    }
    
}

/**
 * 具体产品
 **/
public class GregorianCalendar extends Calendar {
    protected void computeTime() {
        // In non-lenient mode, perform brief checking of calendar
        // fields which have been set externally. Through this
        // checking, the field values are stored in originalFields[]
        // to see if any of them are normalized later.
        if (!isLenient()) {
            if (originalFields == null) {
                originalFields = new int[FIELD_COUNT];
            }
            for (int field = 0; field < FIELD_COUNT; field++) {
                int value = internalGet(field);
                if (isExternallySet(field)) {
                    // Quick validation for any out of range values
                    if (value < getMinimum(field) || value > getMaximum(field)) {
                        throw new IllegalArgumentException(getFieldName(field));
                    }
                }
                originalFields[field] = value;
            }
        }
    }
    ......
}
 
![在这里插入图片描述](https://img-blog.csdnimg.cn/69d8ab1f27e34987b1af42b0f08ae103.png#pic_center)
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值