This article is excerpted from This is How Design Patterns should Be Learned

Use the simple factory pattern to encapsulate product creation details

Now look at the code, again, creating an online course. Suppose there are courses on Java architecture, big data, artificial intelligence, etc., and an ecosystem has formed. We can define a course standard ICourse interface.


public interface ICourse {
    /** Record video */
    public void record(a);
}

Copy the code

Create a Java course implementation class, JavaCourse.


public class JavaCourse implements ICourse {
    public void record(a) {
        System.out.println("Recording a Java Lesson"); }}Copy the code

The client call code is as follows.


public static void main(String[] args) {
    ICourse course = new JavaCourse();
    course.record();
}

Copy the code

The parent class ICourse refers to a reference to the subclass JavaCourse, which your application-layer code depends on. If the business expands and PythonCourse continues to be added, or even more, the client dependencies become more and more bloated. Therefore, we need to find a way to reduce this dependency and hide the creation details. While the process of creating objects is not complicated in the current code, it is not easily extensible from a code design perspective. Therefore, the code is optimized with the simple factory pattern. First add the PythonCourse class.


public class PythonCourse implements ICourse {
    public void record(a) {
        System.out.println("Recording Python lessons"); }}Copy the code

Then create the CourseFactory factory class.


public class CourseFactory {
    public ICourse create(String name){
        if("java".equals(name)){
            return new JavaCourse();
        }else if("python".equals(name)){
            return new PythonCourse();
        }else {
            return null; }}}Copy the code

Finally, modify the client calling code.


public class SimpleFactoryTest {
    public static void main(String[] args) {
        CourseFactory factory = new CourseFactory();
        factory.create("java"); }}Copy the code

Of course, you can change the Create () method of CourseFactory to a static method for ease of invocation, as shown in the class diagram below.

The client calls are simple, but if the business continues to scale and to add front-end lessons, the create() method in the factory will have to modify the code logic each time as the product chain grows, which does not comply with the open-close principle. Therefore, we can continue to optimize the simple factory pattern using reflection techniques, as shown below.


public class CourseFactory {
    public ICourse create(String className){
        try {
            if(! (null == className || "".equals(className))) {
                return(ICourse) Class.forName(className).newInstance(); }}catch (Exception e){
            e.printStackTrace();
        }
        return null; }}Copy the code

The client call code is modified as follows.


public static void main(String[] args) {
        CourseFactory factory = new CourseFactory();
        ICourse course = factory.create("com.gupaoedu.vip.pattern.factory.simplefactory.JavaCourse");
        course.record();
}

Copy the code

After optimization, the product was enriched without the need to modify the code in CourseFactory. The problem is, method parameters are strings, controllability needs to be improved, and transformation needs to be enforced. Continue to modify the code.


public ICourse create(Class<? extends ICourse> clazz){
    try {
        if (null! = clazz) {returnclazz.newInstance(); }}catch (Exception e){
        e.printStackTrace();
    }
    return null;
}

Copy the code

Optimize the client test code.


public static void main(String[] args) {
    CourseFactory factory = new CourseFactory();
    ICourse course = factory.create(JavaCourse.class);
    course.record();
}

Copy the code

Finally, look at the class diagram shown below.

Application of simple factory pattern in JDK source code

Simple factory patterns are ubiquitous in JDK source code, such as the Calendar class, see the Calendar.getInstance() method. The concrete creation class for Calendar opens below.


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) {
        }
    }

    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 (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 = newGregorianCalendar(zone, aLocale); }}return cal;
}

Copy the code

Application of simple factory pattern in Logback source code

In the popular Logback, you can see multiple overloaded methods getLogger() in LoggerFactory.


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

public static Logger getLogger(Class clazz) {
    return getLogger(clazz.getName());
}

Copy the code

Pay attention to “Tom play architecture” reply to “design pattern” can obtain the complete source code.

Tom play architecture: 30 real cases of design patterns (attached source code), the challenge of annual salary 60W is not a dream

This article is “Tom play structure” original, reproduced please indicate the source. Technology is to share, I share my happiness! If this article is helpful to you, welcome to follow and like; If you have any suggestions can also leave a comment or private letter, your support is my motivation to adhere to the creation. Pay attention to “Tom bomb architecture” for more technical dry goods!