简单的工厂模式-Java设计模式(一)

159 阅读2分钟

** 2019-11-28 15:41:44 **

简单的工厂模式-Java设计模式(一)

简单工厂模式

简单工厂模式不是 23 种里的一种,简而言之,就是有一个专门生产某个产品的类。 更像是一种编码的风格和习惯。

适用范围

1.工厂类负责创建的对象比较少。 2.客户端(应用层)只知道传入工厂类的参数,对于如何创建对象(逻辑)不关心。

优缺点

优点:只需要传入一个正确的参数,就可以获取你所需要的对象,无需知道其创建细节。 缺点:工厂类的职责相对过重,增加新的产品需要修改工厂类的判断逻辑,无法满足开闭原则,对多个产品的扩展不利。



代码 & 结构图

动物例子

/**
 * 动物接口
 */
public interface Animal {
    void run();
}
public class Bird implements Animal {
    @Override
    public void run() {
        System.out.println("鸟在天上飞");
    }
}
public class Fish implements Animal {
    @Override
    public void run() {
        System.out.println("鱼在水中游泳");
    }
}
public class People implements Animal {
    @Override
    public void run() {
        System.out.println("人在地上走");
    }
}

工厂类

/**
 * 工厂类
 */
public class AnimalFactory {
    public static Animal createAnimal(String animal) {
        switch (animal) {
            case "fish":
                return new Fish();
            case "bird":
                return new Bird();
            case "people":
                return new People();
            default:
                return null;
        }
    }
}

测试

public class Test {
    public static void main(String[] args) {
        Animal fish = AnimalFactory.createAnimal("fish");
        // 调用方法
        fish.run(); //输出结果: 鱼在水中游泳
    }
}

UML结构图

源码 - simpleFactory分支

不同分支对应不同设计模式源码 github.com/nullaman/Ja…



JDK中的例子

Calendar类

Calendar.getInstance();
    /**
     * Gets a calendar using the default time zone and locale. The
     * <code>Calendar</code> returned is based on the current time
     * in the default time zone with the default
     * {@link Locale.Category#FORMAT FORMAT} locale.
     *
     * @return a Calendar.
     */
    public static Calendar getInstance()
    {
        return createCalendar(TimeZone.getDefault(), Locale.getDefault(Locale.Category.FORMAT));
    }
    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;
    }