Java简单工厂

/ 2评 / 0

简单工厂是由一个工厂对象来决定创建出哪一种产品类的实例。属于创建型,但不属于GOF23种设计模式,更像是一种编码的风格和习惯。

学习简单工厂后,对于学习工厂方法、抽象工厂更有帮助。

适用范围

优缺点

优点:只需要传入一个正确的参数,就可以获取你所需要的对象,无需知道其创建细节。

缺点:工厂类的职责相对过重,增加新的产品需要修改工厂类的判断逻辑,违背开闭原则。

示例

Video.java 视频抽象类,提供生产视频的抽象方法。

package com.zaiae.design.pattern.creational.simplefactory;

public abstract class Video {
    public abstract void produce();
}

JavaVideo.java Java视频类,继承视频抽象类,并实现自己的生产视频逻辑。

package com.zaiae.design.pattern.creational.simplefactory;

public class JavaVideo extends Video {

    @Override
    public void produce() {
        System.out.println("录制一套Java课程视频");
    }
}

PythonVideo.java Python视频类,继承视频抽象类,并实现自己的生产视频逻辑。

package com.zaiae.design.pattern.creational.simplefactory;

public class PythonVideo extends Video {

    @Override
    public void produce() {
        System.out.println("录制一套Python课程视频");
    }
}

VideoFactory.java 生产视频的简单工厂类,通过传入参数,生产不同的视频对象。

package com.zaiae.design.pattern.creational.simplefactory;

public class VideoFactory {
    public Video getVideo(String type) {
        switch (type.toLowerCase()) {
            case "java":
                return new JavaVideo();
            case "python":
                return new PythonVideo();
            default:
                return null;
        }
    }
}

Test.java 客户端(应用层)调用简单工厂,创建需要的对象。

package com.zaiae.design.pattern.creational.simplefactory;

public class Test {

    public static void main(String[] args) {
        VideoFactory videoFactory = new VideoFactory();
        Video video = videoFactory.getVideo("python");
        if (video != null) {
            video.produce();
        }
    }
}

UML结构图:

JDK中的使用例子

在jdk源码中,也大量使用了简单工厂,比如 java.util.Calendar 类中,创建 Calendar 实例对象,调用了如下方法:

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

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注