Viewing Design Patterns with JDK Source Code: Simple Factory, Factory Method, Abstract Factory

Keywords: Java JDK MySQL JDBC Database

Detailed description of three factory models:

Simple factory model:
Scenario: The factory class is responsible for creating fewer objects, the client only cares about the parameters that are passed into the factory class, and does not care about how to create the logic of the object.

Disadvantage: If you want to add new products, you need to modify the judgment logic of the factory class, violate the open and close principle of software design, and have many kinds of products, which will make the simple factory class more complex.

Specific examples in jdk source code (note the Chinese annotations in the code)
    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;
            /*Creating different calendar objects according to different regions is like calendar factory, which produces calendars in different regions of the world. I need calendars in this region. I just need to pass parameters to the factory, and I don't need to know the process of calendar production and the process of example.*/
                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;
            }
In addition to the calendar class and JDBC, when we need the driver of MySQL database, we pass MySQL parameters and Oracle parameters.
 
Factory Method Model:
 
Scenario: Creating objects requires a lot of repetitive code, clients do not rely on details such as how product class instances are created and implemented, and a class specifies which object to create through its subclasses
The core of the factory approach is to place the instantiation process in subclasses (which is quite different from simple factories).
To explain the factory method pattern, we need the following concepts: a general abstract factory and its subclasses, as well as an abstract product class and a subclass of abstract product class. Look at the following jdk source code concretely:

Take the iterator() method implemented by ArrayList as an example

public Iterator<E> iterator() {
        return new Itr();
    }
 
    /**
     * An optimized version of AbstractList.Itr
     */
    private class Itr implements Iterator<E> {
        int cursor;       // index of next element to return
        int lastRet = -1; // index of last element returned; -1 if no such
        int expectedModCount = modCount;
 
        public boolean hasNext() {
            return cursor != size;
        }
 
        @SuppressWarnings("unchecked")
        public E next() {
            checkForComodification();
            int i = cursor;
            if (i >= size)
                throw new NoSuchElementException();
            Object[] elementData = ArrayList.this.elementData;
            if (i >= elementData.length)
                throw new ConcurrentModificationException();
            cursor = i + 1;
            return (E) elementData[lastRet = i];
        }

It can be understood that there are many methods defined in the Collection interface, such as size(),isEmpty(),iterator(), etc. These methods can be considered as products in the factory, and Collection can be regarded as a general abstract factory. Some of its classes that implement this interface, such as ArrayList, LinkedHashSet, etc., can be seen as factories of different brands, while the overall product Iterator interface defines the details of the functions required by the product and then gives them to factories of different brands to implement.

The abstract factory pattern:

After understanding the above, we can understand the abstract factory very well. The biggest difference between the abstract factory model and the factory method model is that the factory method model aims at a product hierarchy; (for example, different implementations of the Iterator() method) and the abstract factory model needs to face multiple product hierarchy structures (different methods under the Collection interface). To make it clear, Collection is an abstract factory, which provides a library of product classes. All products appear with the same interface, so that the client does not depend on the specific implementation. The factory method is one of the product classes in the abstract factory, and the instantiation of the method is put into the concrete implementation class.

Posted by mars16 on Fri, 10 May 2019 12:07:41 -0700