Java design patterns (three) simple factory pattern

Definition and Types

  • Definition: determined by a factory object to create an instance of the class of product which
  • Type: create type, but does not belong GOF23 design patterns

Applicable scene

  • Object factory class is responsible for creating relatively small
  • The client (application layer) only know the parameters passed factory class, how to create objects (logic) do not care

advantage

Only need to pass the right parameters, you can get the object you need, without having to know the details of creating

Shortcoming

Factory class of functions relative overweight , adding new products, need to modify the factory class determination logic, contrary to the principle of opening and closing

Coding

Create an abstract class product

public abstract class Video {
    public abstract void produce();
}

Product implementation class

public class JavaVideo extends Video {
    @Override
    public void produce() {
        System.out.println("录制Java课程");
    }
}
public class PythonVideo extends Video {
    @Override
    public void produce() {
        System.out.println("录制Python视频");
    }
}

Create a corresponding product simple factory to create a product by product type, the application side without knowing the details of the product creation

public class VideoFactory {

    public Video getVideo(String type) {
        if ("java".equalsIgnoreCase(type)) {
            return new JavaVideo();
        } else if ("python".equalsIgnoreCase(type)) {
            return new PythonVideo();
        } else {
            return null;
        }
    }
}

Test category

public class Test {
    public static void main(String[] args) {
        VideoFactory videoFactory = new VideoFactory();
        Video video = videoFactory.getVideo("Java");
        video.produce();
    }
}

Console output

录制Java课程

If you increase the product, we not only need to modify the product corresponding product category, also we need to modify the factory class, in violation of the principle of opening and closing.

We can optimize our factory class through reflection

public class VideoFactory {

    public Video getVideo(Class<? extends Video> clazz) {
        try {
            return clazz.newInstance();
        } catch (InstantiationException | IllegalAccessException e) {
            e.printStackTrace();
        }
        return null;
    }
}

As a result, the product is added when we do not have to modify the factory class, but can be added directly to the product.

The final UML class diagram

Source resolve

JDKSource

In the JDK, simple examples such as a factory mode java.util.Calendar, a set of getInstanceoverloaded methods is provided to create Calendara simple method of plant products.

public static Calendar getInstance()
public static Calendar getInstance(TimeZone zone)
public static Calendar getInstance(Locale aLocale)
public static Calendar getInstance(TimeZone zone,Locale aLocale)

The core method

private static Calendar createCalendar(TimeZone zone,Locale aLocale)

Source code is longer, not posted, are interested can go to the next source.

CalendarUML class diagram as follows

LogbackSource

logbackSimple class factory pattern is mainly reflected inch.qos.logback.classic.LoggerContext#getLogger(String)

@Override
public final Logger getLogger(final String name) {

    if (name == null) {
        throw new IllegalArgumentException("name argument cannot be null");
    }

    // 判断log类型返回root节点的logger
    if (Logger.ROOT_LOGGER_NAME.equalsIgnoreCase(name)) {
        return root;
    }

    int i = 0;
    Logger logger = root;

    // 如果缓存中已经存在的指定的logger,直接返回childLogger
    Logger childLogger = (Logger) loggerCache.get(name);
    // if we have the child, then let us return it without wasting time
    if (childLogger != null) {
        return childLogger;
    }

    // 以下是创建logger的逻辑
    String childName;
    while (true) {
        int h = LoggerNameUtil.getSeparatorIndexOf(name, i);
        if (h == -1) {
            childName = name;
        } else {
            childName = name.substring(0, h);
        }
        // move i left of the last point
        i = h + 1;
        synchronized (logger) {
            childLogger = logger.getChildByName(childName);
            if (childLogger == null) {
                childLogger = logger.createChildByName(childName);
                loggerCache.put(childName, childLogger);
                incSize();
            }
        }
        logger = childLogger;
        if (h == -1) {
            return childLogger;
        }
    }
}

It is a typical simple factory method

Guess you like

Origin www.cnblogs.com/gcdd/p/12292126.html