其他分享
首页 > 其他分享> > [01][01][03] 工厂模式详解

[01][01][03] 工厂模式详解

作者:互联网

工厂模式分为三种类型

1. 简单工厂模式

指由一个工厂对象决定创建出哪一种产品类的实例

1.1 代码实现

1.1.1 产品抽象类

public interface ICourse {
    /**
     * 录制课程
     */
    void record();
}

1.1.2 具体产品类

public class JavaCourse implements ICourse {
    /**
     * 录制 java 课程
     */
    @Override
    public void record() {
        System.out.println("正在录制 java 课程");
    }
}

1.1.3 简单工厂类

public class CourseFactory {

    /**
     * 通过名称创建对象
     * @param name
     * @return
     */
    public ICourse createByName(String name) {
         if ("java".equals(name)) {
             return new JavaCourse();
         } else {
             return null;
         }
    }

    /**
     * 通过类路径创建对象
     * @param classPath
     * @return
     */
    public ICourse createByClassPath(String classPath) {
        try {
            if (StringUtils.isNotBlank(classPath)) {
                return (ICourse) Class.forName(classPath).newInstance();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 通过类创建对象
     * @param className
     * @return
     */
    public ICourse createByClass(Class className) {
        try {
            if (null != className) {
                return (ICourse) className.newInstance();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

1.1.4 测试类

public class SimelpFactoryTest {

    public static void main(String[] args) {
        CourseFactory courseFactory = new CourseFactory();

        // 通过类名创建对象
        ICourse nameCourse = courseFactory.createByName("java");
        nameCourse.record();

        // 通过类路径创建对象
        ICourse classNameCourse = courseFactory.createByClassPath("com.zhunongyun.toalibaba.designpatterns.factory.common.JavaCourse");
        classNameCourse.record();

        // 通过类创建对象
        ICourse classCourse = courseFactory.createByClass(JavaCourse.class);
        classCourse.record();

        ICourse pythonCourse = courseFactory.createByName("python");
        pythonCourse.record();
    }
}

1.2 适用场景

1.3 优点/缺点

1.3.1 优点

1.3.2 缺点

1.4 源码分析

1.4.1java.util 下的 Calendar

Calendar 是一个日历工具,使用简单工厂模式创建实体类Calendarcalendar=Calendar.getInstance();

Calendar 的 getInstance()的代码就是通过简单工厂的方式去创建 Calendar 对象

public abstract class Calendar implements Serializable, Cloneable, Comparable<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;
    }
}

1.4.2org.slf4j 下的 LoggerFactory

LoggerFactory 是日志工厂类,通过简单工厂创建对象Loggerlogger=LoggerFactory.getLogger("xx");

LoggerFactory 的 getLogger()的代码就是通过简单工厂的方式去创建 Logger 对象

public final class LoggerFactory {
    public static Logger getLogger(String name) {
        ILoggerFactory iLoggerFactory = getILoggerFactory();
        return iLoggerFactory.getLogger(name);
    }

    public static Logger getLogger(Class<?> clazz) {
        Logger logger = getLogger(clazz.getName());
        if (DETECT_LOGGER_NAME_MISMATCH) {
            Class<?> autoComputedCallingClass = Util.getCallingClass();
            if (autoComputedCallingClass != null && nonMatchingClasses(clazz, autoComputedCallingClass)) {
                Util.report(String.format("Detected logger name mismatch. Given name: \"%s\"; computed name: \"%s\".", logger.getName(), autoComputedCallingClass.getName()));
                Util.report("See http://www.slf4j.org/codes.html#loggerNameMismatch for an explanation");
            }
        }
        return logger;
    }
}

2. 工厂方法模式

指定义一个创建对象的接口,但让实现这个接口的类来决定实例化哪个类,工厂方法让类的实例化推迟到子类中进行

2.1 代码实现

2.2 适用场景

2.3 优/缺点

2.3.1 优点

2.3.2 缺点

2.4 源码分析

2.4.1org.slf4j 下的 LoggerFactory

LoggerFactory 的 getLogger()的代码中ILoggerFactory iLoggerFactory = getILoggerFactory();,通过工厂方法模式创建出具体 Logger 的工厂类

public final class LoggerFactory {
    public static Logger getLogger(String name) {
        ILoggerFactory iLoggerFactory = getILoggerFactory();
        return iLoggerFactory.getLogger(name);
    }

    public static ILoggerFactory getILoggerFactory() {
        if (INITIALIZATION_STATE == 0) {
            Class var0 = LoggerFactory.class;
            synchronized(LoggerFactory.class) {
                if (INITIALIZATION_STATE == 0) {
                    INITIALIZATION_STATE = 1;
                    performInitialization();
                }
            }
        }

        switch(INITIALIZATION_STATE) {
        case 1:
            return SUBST_FACTORY;
        case 2:
            throw new IllegalStateException("org.slf4j.LoggerFactory in failed state. Original exception was thrown EARLIER. See also http://www.slf4j.org/codes.html#unsuccessfulInit");
        case 3:
            return StaticLoggerBinder.getSingleton().getLoggerFactory();
        case 4:
            return NOP_FALLBACK_FACTORY;
        default:
            throw new IllegalStateException("Unreachable code");
        }
    }
}

3. 抽象工厂模式

指提供一个创建一系列相关或相互依赖对象的接口,无需指定他们具体的类

3.1 产品等级与产品族

3.2 代码实现

public interface INote {
    /**
     * 编写课程笔记
     */
    void write();
}
public interface IVideo {
    /**
     * 处理课程视频
     */
    void handle();
}
public class JavaNote implements INote {
    @Override
    public void write() {
        System.out.println("正在编写 java 课程笔记");
    }
}
public class JavaVideo implements IVideo {
    @Override
    public void handle() {
        System.out.println("正在处理 java 课程视频");
    }
}

3.3 适用场景

3.4 优/缺点

3.4.1 优点

3.42 缺点

3.5 源码分析

Spring 中的 AbstractBeanFactory 类

public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory {

    ......

    protected abstract boolean containsBeanDefinition(String var1);

    protected abstract BeanDefinition getBeanDefinition(String var1) throws BeansException;

    protected abstract Object createBean(String var1, RootBeanDefinition var2, @Nullable Object[] var3) throws BeanCreationException;
}

AbstactBeanFactory 的三个实现类:

标签:03,01,return,ICourse,class,详解,new,工厂,public
来源: https://blog.51cto.com/14962454/2542173