• JAVA 设计模式之 工厂模式详解


    一、简单工厂模式

      简单工厂模式(Simple Factory Pattern)是指由一个工厂对象决定创建出哪一种产品类 的实例。属于创建型模式,但它不属于 GOF,23 种设计模式

    (参考资料: http://en.wikipedia.org/wiki/Design_Patterns#Patterns_by_Type)。

      简单工厂模式适用于的场景:

        1、适用 于工厂类负责创建的对象较少的场景,

          2、且客户端只需要传入工厂类的参数,对于如何创 建对象的逻辑不需要关心。

      简单工厂模式缺点:

        1、工厂类的职业相对过重,增加新的产品时需要修改工厂类的判断逻辑,违背开闭原则

        2、不易于扩展过于复杂的产品结构

    下面手写一个简单的工厂模式

    /**
     * @Description 需要实现的接口
     * @Author Bert
     * @Date 2019521
     */
    public interface ICoure {
        public void record();
    }
    
    /**
     * @Description 实现ICoure
     * @Author Bert
     * @Date 2019521 0021
     */
    public class JavaCoure implements ICoure {
    
        @Override
        public void record() {
            System.out.println("录制Java课程!");
        }
    }
    
    /**
     * @Description 工厂类  将类的创建过程封装到工厂里面
     * @Author Bert
     * @Date 2019521 0021
     */
    public class CourseFactory {
        /**
         * @Description 通过name判断,创建对应的对象
         * @Date 2019521 0021 23:05
         * @Param [name]
         * @return com.bert.simple.factory.ICoure
         */
        public ICoure create(String name){
            if("Java".equals(name))
                return new JavaCoure();
            if("Python".equals(name))
                return new PythonCoure();
            else
                return null;
        }
        /**
         * @Description //通过类的全路径
         * @Date 2019521 0021
         * @Param [className]
         * @return com.bert.simple.factory.ICoure
         */
        public ICoure create1(String className){
            try {
                if( null != className && !"".equals(className)){
                    return (ICoure)Class.forName(className).newInstance();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
            return null;
        }
    
        /**
         * @Description 传入一个Class,可以避免输入错误的内容
         * @Date 2019521 0021
         * @Param [clazz]
         * @return com.bert.simple.factory.ICoure
         */
        public ICoure create2(Class clazz){
            if (null != clazz) {
                try {
                    return (ICoure) clazz.newInstance();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            return null;
        }
    }
    
    /**
     * @Description 测试类
     * @Author Bert
     * @Date 2019521 0021
     */
    public class SimpleFactoryTest {
    
        public static void main(String[] args) {
            CourseFactory factory = new CourseFactory();
            /**
             * 通过简单的工厂创建
             */
            ICoure iCoure = factory.create("Java");//方式1
            iCoure.record();
    
            ICoure factory1 = factory.create1("com.bert.simple.factory.JavaCoure");//方式2
            factory1.record();
    
            ICoure factory2 = factory.create2(JavaCoure.class);//方式3
            factory2.record();
    
        }
    }
    

      简单工厂模式在 JDK 源码也是无处不在 现在我们来举个例子:

    /* 里面通过createCalendar(TimeZone zone, Locale aLocale)传入时区、语言  创建不同时区的时间 */
            Calendar calendar = Calendar.getInstance();/* getInstance()是一个工厂模式,也是一个单例模式 */
    
    //Calendar 源码
    public static Calendar getInstance()
        {
            return createCalendar(TimeZone.getDefault(), Locale.getDefault(Locale.Category.FORMAT));
        }
    
            /* getLogger(Class<?> clazz) 典型的工厂模式 */
            Logger logger = LoggerFactory.getLogger(SimpleFactoryTest.class);/*也是一个单例*/
    
    //LoggerFactory源码
    
    public static Logger getLogger(Class<?> clazz) {
            Logger logger = getLogger(clazz.getName());
            if (DETECT_LOGGER_NAME_MISMATCH) {
                Class<?> autoComputedCallingClass = Util.getCallingClass();
                if (autoComputedCallingClass != null && nonMatchingClasses(clazz, autoComputedCallingClass)) {
                    Util.report(String.format("Detected logger name mismatch. Given name: "%s"; computed name: "%s".", logger.getName(), autoComputedCallingClass.getName()));
                    Util.report("See http://www.slf4j.org/codes.html#loggerNameMismatch for an explanation");
                }
            }
    
            return logger;
        }
    

    二、工厂方法模式

      工厂方法模式(Fatory Method Pattern)是指定义一个创建对象的接口,但让实现这个 接口的类来决定实例化哪个类,工厂方法让类的实例化推迟到子类中进行。属于创建型模式,23中设计模式之一,在工厂方法 模式中用户只需要关心所需产品对应的工厂,无须关心创建细节,而且加入新的产品符 合开闭原则。

    /**
     * @Description 需要实现的接口
     * @Author Bert
     * @Date 2019521
     */
    public interface ICoure {
        public void record();
    }
    
    /**
     * @Description 实现ICoure
     * @Author Bert
     * @Date 2019521 0021
     */
    public class JavaCoure implements ICoure {
    
        @Override
        public void record() {
            System.out.println("录制Java课程!");
        }
    }
    
    /**
     * @Description TODO
     * @Author Bert
     * @Date 2019521 0021
     */
    public class PythonCoure implements ICoure {
    
        @Override
        public void record() {
            System.out.println("录制Python课程!");
        }
    }
    
    /**
     * @Description 工厂接口
     * @Author Bert
     * @Date 2019522 0022
     */
    public interface ICoureFactory {
        ICoure create();
    }
    
    /**
     * @Description Java方法工厂
     * @Author Bert
     * @Date 2019522 0022
     */
    public class JavaICoureFactory implements ICoureFactory{
        @Override
        public ICoure create() {
            return new JavaCoure();
        }
    }
    
    /**
     * @Description Python方法工厂
     * @Author Bert
     * @Date 2019522 0022
     */
    public class PythonICoureFactory implements ICoureFactory{
        @Override
        public ICoure create() {
            return new PythonCoure();
        }
    }
    
    /**
     * @Description 工厂方法模式测试类
     * @Author Bert
     * @Date 2019522 0022
     */
    public class FactoryMethodTest {
    
        public static void main(String[] args) {
    
            ICoureFactory iCoureFactory = new JavaICoureFactory();
            ICoure iCoure = iCoureFactory.create();
            iCoure.record();
    
            PythonICoureFactory iCoureFactory1 = new PythonICoureFactory();
            ICoure iCoure1 = iCoureFactory1.create();
            iCoure1.record();
        }
    }
    

      类图如下:

      工厂方法模式的适用场景:

        1、创建对象需要大量重复的代码

        2、客户端(应用层)不依赖于产品类实例如何被创建、实现等细节,一个类通过其子类来指定创建哪个对象。

      工厂方法模式的优点:

        1、用户只关系所需产品对应的工厂,无须关心创建细节。

        2、加入新产品符合开闭原则,提高了系统的可扩展性。

      工厂方法模式的缺点:

        1、类的个数容易过多,增加了代码结构的复杂度。

        2、增加了系统的抽象性和理解难度。

    三、抽象工厂模式

      抽象工厂模式(Abstract Factory Pattern)是指提供一个创建一系列相关或者相互依赖对象的接口,无须指定他们具体的类。

      属于创建型设计模式。

      

    /**
     * @Description 需要实现的接口
     * @Author Bert
     * @Date 2019521
     */
    public interface ICoure {
        public void record();
    }
    
    /**
     * @Description 实现ICoure
     * @Author Bert
     * @Date 2019521 0021
     */
    public class JavaCoure implements ICoure {
    
        @Override
        public void record() {
            System.out.println("录制Java课程!");
        }
    }
    
    /**
     * @Description TODO
     * @Author Bert
     * @Date 2019521 0021
     */
    public class PythonCoure implements ICoure {
    
        @Override
        public void record() {
            System.out.println("录制Python课程!");
        }
    }
    
    /**
     * @Description 要求所有的工厂都实现这个工厂
     *      一个品牌的抽象
     *      1、 抽象工厂不符合开闭原则 (在顶层接口中添加的抽象方法,在继承他的类都需要继承)
     *      2、扩展性强
     * @Author Bert
     * @Date 2019522 0022
     */
    public interface ICouseeFactory {
    
        ICoure createCourse();
    
        Inote createNote();
    
        Ivideo createVideo();
    
    }
    
    /**
     * @Description TODO
     * @Author Bert
     * @Date 2019522 0022
     */
    public interface Inote {
    
    }
    
    /**
     * @Description TODO
     * @Author Bert
     * @Date 2019522 0022
     */
    public interface Ivideo {
    
    }
    
    /**
     * @Description TODO
     * @Author Bert
     * @Date 2019522 0022
     */
    public class JavaNote implements Inote{
    }
    
    /**
     * @Description TODO
     * @Author Bert
     * @Date 2019522 0022
     */
    public class JavaVideo implements Ivideo {
    }
    
    /**
     * @Description TODO
     * @Author Bert
     * @Date 2019522 0022
     */
    public class PythonNote implements Inote {
    }
    
    /**
     * @Description TODO
     * @Author Bert
     * @Date 2019522 0022
     */
    public class PythonVideo implements Ivideo {
    }
    
    /**
     * @Description JAVA 课程实现
     * @Author Bert
     * @Date 2019522 0022
     */
    public class JavaCourseFactory implements ICouseeFactory {
    
        @Override
        public ICoure createCourse() {
            return new JavaCoure();
        }
    
        @Override
        public Inote createNote() {
            return new JavaNote();
        }
    
        @Override
        public Ivideo createVideo() {
            return new JavaVideo();
        }
    }
    
    /**
     * @Description Python课程实现
     * @Author Bert
     * @Date 2019522 0022
     */
    public class PythonCourseFactory implements ICouseeFactory {
    
        @Override
        public ICoure createCourse() {
            return new PythonCoure();
        }
    
        @Override
        public Inote createNote() {
            return new PythonNote();
        }
    
        @Override
        public Ivideo createVideo() {
            return new PythonVideo();
        }
    }
    
    /**
     * @Description 抽象工厂 测试类
     * @Author Bert
     * @Date 2019522 0022
     */
    public class AbstactFactoryTest {
        public static void main(String[] args) {
    
            ICouseeFactory factory = new JavaCourseFactory();
            factory.createCourse().record();
            factory.createNote();
            factory.createVideo();
    
        }
    }
    

      

     

      抽象工厂模式使用场景:

        1、客户端(应用层)不依赖于产品类实例如何被创建,实现等细节。

        2、强调一系列相关的产品对象(属于同一产品族)一起使用创建对象需要大量重复的代码。

        3、提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于具体的实现。

      抽象工厂模式优点:

        1、具体产品在应用层代码隔离,无须关系创建细节。

        2、将一个系列的产品族统一到一起创建。

      抽象工厂模式缺点:

        1、规定了所有可能被创建的产品集合,产品族中扩展新的产品困难,需要修改抽象工厂的接口。

        2、增加了系统的抽象性和理解难度。

     Spring 中用到的抽象工厂模式例如:DefaultListableBeanFactory

  • 相关阅读:
    安装和强行卸载fuse
    Elasticsearch snapshot 备份的使用方法 【备忘】
    MYSQL数据仓库infobright【备忘】
    Tomcat8 启动慢 Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [53,161] milliseconds
    python爬虫实例
    JDK1.8 JVM参数配置
    QQ登录用到的URL
    CAS5.3.X 配置备忘
    Nexus3忘记admin密码时的解决办法
    CentOS7利用systemctl添加自定义系统服务
  • 原文地址:https://www.cnblogs.com/bert227/p/10903357.html
Copyright © 2020-2023  润新知