2.0 - The Three Musketeers design patterns factory pattern - simple factory pattern

2.0 design patterns factory pattern

First recall design principles:

Design Principles Explanation
Open Closed Principle Open for extension, but closed for modification.
Dependency Inversion Principle By abstracting the respective class or module does not affect each other, loose coupling.
Single Responsibility Principle A class, interfaces, methods, only one thing
Interface Segregation Principle Try to ensure the purity of the interface, the client should not rely unwanted interfaces.
Demeter Also known as the principle of least know, know, the better a class depends on its class.
Richter substitution principle Subclass can extend the functionality of the parent class but can not change the parent class of the original function.
Synthesis of multiplexing principles To make use of object composition, polymerization, without using object inheritance relations to code reuse.

Factory mode Detailed

Historical origin of the factory pattern

In real life, we all know, the original social self-sufficiency (no factory), a small farming community workshop (simple plant, civil distillery), the Industrial Revolution line (factory method, homegrown), modern industrial chain foundries (abstract factories, Foxconn)

Simple factory pattern

Simple factory pattern (Simple Factory Pattern) refers to a decision by the object creates an instance of a factory which product category, but it does not belong GOF, 23 kinds of design patterns used in factories simple factory class is responsible for fewer objects to create a scene, and the client only need to pass parameters to the factory class, how to create objects of logic do not care. Next we look at the code

We can define a course ICar standard interfaces:

 

/**
 * 汽车接口
 */
public interface ICar {
    void run();
}
/**
 * 奥迪类
 */
public class AudiCar implements ICar {
    @Override
    public void run() {
        System.out.println("奥迪跑起来了");
    }
}
public static void main(String[] args) {
        ICar iCar=new AudiCar();
        iCar.run();
}

Look at the code above, the parent class reference refers to sub-class AudiCar (), the application layer of code needs to rely AudiCar, if business expansion, I CadillacCar continue to increase even more, then rely on our clients to become increasingly bloated. Therefore, we find a way to decrease this dependence, to create hidden details. Although the current code, we create an object of the process is not complicated, but the code design point of view is not easy to expand. Now, we use a simple factory pattern to optimize the code.

/**
 * 凯迪拉克类
 */
public class CadillacCar implements ICar {
    @Override
    public void run() {
        System.out.println("凯迪拉克跑起来了");
    }
}

Create a factory class SimpleFactory, we give the following three methods to create plant

 /**
     * 创建实例
     * @param type
     * @return
     */
    public ICar create(String type){
      if(StringUtils.isEmpty(type)){
         return null;
      }
      if("Audi".equals(type)){
          return new AudiCar();
      }else if("Cadillac".equals(type)){
         return new CadillacCar();
      }else {
          return null;
      }
    }
/**
     * 通过反射创建,不修改代码逻辑
     * @param className
     * @return
     */
    public ICar createByclazz(String className){
        try {
            if (!(null == className || "".equals(className))) {
                return (ICar) Class.forName(className).newInstance();
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }
/**
     * 通过类实例化,方法参数是字符串,可控性有待提升,而且还需要强制转型
     * @param clazz
     * @return
     */
    public ICar create(Class<? extends ICar> clazz){
        try {
            if (null != clazz) {
                return clazz.newInstance();
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

The client calling code

/**
 * 简单工厂模式测试类
 * 优点:把创建代码封装到工厂里,调用者感应不到,只需要传入响应的类型即可
 * 缺点:不符合开闭原则,没增加一个产品都要修改工厂代码,不易于扩展
 */
public class SimpleFactoryTest {

    public static void main(String[] args) {
        SimpleFactory simpleFactory=new SimpleFactory();
        ICar iCar= simpleFactory.create("Audi");
        iCar.run();

        //通过反射调用
        ICar iCar1=simpleFactory.createByclazz("com.design.pattern.common.AudiCar");
        iCar1.run();

        ICar iCar2=simpleFactory.create(AudiCar.class);
        iCar2.run();
    }
}

Let's look at the class diagram:

Simple factory pattern in JDK source is everywhere, we now give you an example, such as the Calendar class, see Calendar.getInstance () method, the following is an open concrete to create a class of 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;
}

There we often use a logback, we can see that there is more than LoggerFactory overloaded method getLogger ():

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

Simple factory also has its drawbacks: Responsibilities factory class is relatively heavy and difficult to expand overly complex product structures.

Guess you like

Origin blog.csdn.net/madongyu1259892936/article/details/93747664