工厂模式

喜你入骨 提交于 2020-02-26 02:18:43

一、定义
工厂模式是我们最常用的实例化对象模式了,是用工厂方法代替new操作的一种模式。因为工厂模式就相当于创建实例对象的new,我们经常要根据类Class生成实例对象,如A a=new A() 工厂模式也是用来创建实例对象的,所以以后new时就要多个心眼,是否可以考虑使用工厂模式,虽然这样做,可能多做一些工作,但会给你系统带来更大的可扩展性和尽量少的修改量。

二、静态工厂模式
1,首先建立一个产品的抽象类
需要生产什么产品(实例对象)就需要首先建立一个相应产品的抽象类

public abstract class INoodles {
    /**
     * 描述每种面条啥样的
     */
    public abstract void desc();
}

2.再建立几种具体的产品类如:
这里建立了三个产品类:兰州拉面,泡面,干扣面(没吃过)

public class LzNoodles extends INoodles {
    @Override
    public void desc() {
        System.out.println("兰州拉面");
    }
}
public class PaoNoodles extends INoodles {
    @Override
    public void desc() {
        System.out.println("泡面");
    }
}
public class GankouNoodles extends INoodles {
    @Override
    public void desc() {
        System.out.println("干扣面");
    }
}

3.在建立完这些产品后就可以建立(造面的)工厂了:
工厂里面包含了我们可以生产的产品(面)

public class SimpleNoodlesFactory {
    public static final int TYPE_LZ = 1;//兰州拉面
    public static final int TYPE_PM = 2;//泡面
    public static final int TYPE_GK = 3;//干扣面

    public static INoodles createNoodles(int type) {
        switch (type) {
            case TYPE_LZ:
                return new LzNoodles();
            case TYPE_PM:
                return new PaoNoodles();
            case TYPE_GK:
            default:
                return new GankouNoodles();
        }
    }
}

4.开始根据客人的要求生产产品
如下代码是生产干扣面(真心不知道这名字是怎么来的)的过程。

INoodles noodles = SimpleNoodlesFactory.createNoodles(SimpleNoodlesFactory.TYPE_GK);
 noodles.desc();

特点
1 它是一个具体的类,非接口 抽象类。有一个重要的create()方法,利用if或者 switch创建产品并返回。

2 create()方法通常是静态的,所以也称之为静态工厂。

缺点
1 扩展性差(我想增加一种面条,除了新增一个面条产品类,还需要修改工厂类方法)
2 不同的产品需要不同额外参数的时候 不支持。

三、另一种简单工厂(反射):
利用反射Class.forName(clz.getName()).newInstance()实现的简单工厂:

public class StaticNoodlesFactory {
    /**
     * 传入Class实例化面条产品类
     *
     * @param clz
     * @param <T>
     * @return
     */
    public static <T extends INoodles> T createNoodles(Class<T> clz) {
        T result = null;
        try {
            result = (T) Class.forName(clz.getName()).newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }
}

特点
1 它也是一个具体的类,非接口 抽象类。但它的create()方法,是利用反射机制生成对象返回,好处是增加一种产品时,不需要修改create()的代码。

缺点
这种写法粗看牛逼,细想之下,不谈reflection的效率还有以下问题:
1 个人觉得不好,因为Class.forName(clz.getName()).newInstance()调用的是无参构造函数生成对象,它和new Object()是一样的性质,而工厂方法应该用于复杂对象的初始化 ,当需要调用有参的构造函数时便无能为力了,这样像为了工厂而工厂。
2 不同的产品需要不同额外参数的时候 不支持

四、 多方法工厂(常用)
使用方法二 三实现的工厂,都有一个缺点:不同的产品需要不同额外参数的时候 不支持。

而且如果使用时传递的type、Class出错,将不能得到正确的对象,容错率不高。

而多方法的工厂模式为不同产品,提供不同的生产方法,使用时 需要哪种产品就调用该种产品的方法,使用方便、容错率高。

工厂如下:

public class MulWayNoodlesFactory {

    /**
     * 模仿Executors 类
     * 生产泡面
     *
     * @return
     */
    public static INoodles createPm() {
        return new PaoNoodles();
    }

    /**
     * 模仿Executors 类
     * 生产兰州拉面
     *
     * @return
     */
    public static INoodles createLz() {
        return new LzNoodles();
    }

    /**
     * 模仿Executors 类
     * 生产干扣面
     *
     * @return
     */
    public static INoodles createGk() {
        return new GankouNoodles();
    }
}

查看java源码:java.util.concurrent.Executors类便是一个生成Executor 的工厂 ,其采用的便是 多方法静态

https://www.cnblogs.com/xuxinstyle/p/9128865.html

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!