Detailed description of three factory models:
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.
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; }
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.