美文网首页
设计模式《工厂方法模式》

设计模式《工厂方法模式》

作者: 天道__ | 来源:发表于2018-07-06 16:30 被阅读0次

    引言

      上一节我们说了单例模式,这一节我们来说说工厂方法模式。

    示例地址

      Demo

    先看类图

    image

    工厂方法模式定义

      定义一个用于创建对象的接口,让子类决定实例化哪一个类。

    使用场景

      在任何需要生成复制对象的地方,都可以使用工厂方法模式。

    工厂方法模式示例

      举个例子,我们吃饭的时候都会点主食,主食的种类分为 米饭、面,南方人喜欢吃米饭,但是北方人喜欢吃面。

    简单工厂模式

    1. 我们先来设计产品
    /**
     * 主食
     * @author 512573717@qq.com
     * @created 2018/7/6  下午2:36.
     *
     */
    public interface IZhuShi {
        // 主食吃什么
        void eat();
    }
    
    2. 产品一:南方人爱吃米饭
    /**
     *  主食米饭
     *
     * @author 512573717@qq.com
     * @created 2018/7/6  下午2:37.
     *
     */
    public class Rice implements IZhuShi {
        @Override
        public void eat() {
          System.out.println("主食米饭上来了。");
        }
    }
    
    3. 产品二:北方人爱吃面食
    /**
     * 主食面
     *
     * @author 512573717@qq.com
     * @created 2018/7/6  下午2:43.
     */
    public class Flour implements IZhuShi {
        @Override
        public void eat() {
            System.out.println("主食 面上来了。");
        }
    }
    

    简单(静态)工厂

      接下来是我们怎么创建产品了,就是我们在点餐的时候要选择吃什么。

    1. 主食工厂
    /**
     * 主食工厂
     *
     * @author 512573717@qq.com
     * @created 2018/7/6  下午2:48.
     */
    public class FactoryZhuShi {
        //南方人
        public static final int SOUTH = 1;
        //北方人
        public static final int NORTH = 2;
    
        public  static IZhuShi createZhuShi(int type) {
            switch (type) {
                case SOUTH:
                    return new Rice();
                case NORTH:
                    return new Flour();
                default:
                    return new Rice();
            }
        }
    }
    
    2. 调用工厂创建产品
      IZhuShi south = FactoryZhuShi.createZhuShi(FactoryZhuShi.SOUTH);
      south.eat();
    
      IZhuShi north = FactoryZhuShi.createZhuShi(FactoryZhuShi.NORTH);
      north.eat();
    
    3. 如果我们增加了产品三(水饺),这个时候就需要修改工程类了,违背了设计模式的六大原则(开闭原则)。

    简单(反射)工厂

      Java中反射是无所不能的。那我们就反一种思路,我们通过反射实现。

    1. 反射实现工厂
    /**
     * 通过反射获取主食
     *
     * @author 512573717@qq.com
     * @created 2018/7/6  下午3:11.
     */
    public class ReflectFactoryZhuShi {
    
        public static <T extends IZhuShi> T createZhuShi(Class<T> cls) {
            T object = null;
            try {
                object = (T) (Class.forName(cls.getName())).newInstance();
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
            return object;
        }
    }
    
    2. 调用工厂创建产品
     IZhuShi south = ReflectFactoryZhuShi.createZhuShi(Rice.class);
     south.eat();
    
     IZhuShi north = ReflectFactoryZhuShi.createZhuShi(Flour.class);
     north.eat();
    
    3. 在增加新产品的时候,我们无需修改工厂类,解决设计模式的开闭原则。但是反射影响性能,我们在来看看方法工厂模式

    简单工厂

      反射有效率问题,我们看看最常用的一种写法

    1. 日常写法
    /**
     * 简单工厂
     *
     * @author 512573717@qq.com
     * @created 2018/7/6  下午3:37.
     */
    public class MethodFactoryZhuShi {
    
        public static Rice getRice() {
            return new Rice();
        }
    
        public static Flour getFlour() {
            return new Flour();
        }
    }
    
    2. 简单调用
       IZhuShi south = MethodFactoryZhuShi.getRice();
       south.eat();
    
       IZhuShi north = MethodFactoryZhuShi.getFlour();
       north.eat();
    

    工厂方法模式

    1. 工厂接口
    /**
     * 主食创建工厂
     *
     * @author 512573717@qq.com
     * @created 2018/7/6  下午4:08.
     */
    public interface IFactory<T extends IZhuShi> {
        T create();
    }
    
    2. 米饭工厂
    /**
     *  米饭工厂
     * 
     * @author 512573717@qq.com
     * @created 2018/7/8  下午11:11.
     * 
     */
    public class RiceFactory implements IFactory<Rice> {
        @Override
        public Rice create() {
            return new Rice();
        }
    }
    
    3. 面食工厂
    /**
     *  面食工厂
     *
     * @author 512573717@qq.com
     * @created 2018/7/8  下午11:11.
     *
     */
    public class FlourFactory implements IFactory<Flour> {
        @Override
        public Flour create() {
            return new Flour();
        }
    }
    
    4. 简单调用
     IFactory northFactory = new FlourFactory();
     IZhuShi north = northFactory.create();
     north.eat();
    
     IFactory southFactory = new RiceFactory();
     IZhuShi south = southFactory.create();
     south.eat();
    

    总结

       当有新的产品产生时,只要按照抽象产品角色、抽象工厂角色提供的合同来生成,那么就可以被客户使用,而不必去修改任何已有的代码。(即当有新产品时,只要创建并基础抽象产品;新建具体工厂继承抽象工厂;而不用修改任何一个类)工厂方法模式是完全符合开闭原则的!

    相关文章

      网友评论

          本文标题:设计模式《工厂方法模式》

          本文链接:https://www.haomeiwen.com/subject/sysmyftx.html