工厂方法模式

简单工厂的不足

上一节讲的简单工厂能够满足少量类的创建,但是严重破坏了开闭原则,每次添加一个新的类都得到大的工厂中去注册,然后用户才能从工厂里取出产品,更主要的是,用户必须要记住产品的名称,或者产品的类类型,这对使用者来说是不友好的。我们希望用户知道他想要的产品是在哪个工厂里,通过这个工厂就能获取他想要的,而不关心具体的创建细节,以及产品究竟放在哪。这个时候就有必要使用简单工厂的升级版—工厂方法模式

工厂方法定义

工厂方法模式通过让子类决定该创建的对象是什么,来达到将对象创建的过程封装的目的。工厂方法模式定义了一个创建对象的接口,但由子类决定实例化的类是哪一个。工厂方法让类把实例化推迟到子类。

定义中提到几个重要的地方:

  • 子类决定创建的对象
  • 实例化推迟到子类

子类决定创建的对象也就是说:之前的简单工厂是一个大的工厂,各种创建对象的活动都在这一个工厂里完成,需要用户传入类型,然后根据类型进行创建。而现在,我将这个搞那个厂定义为抽象的,里面有个创建产品的方法,继承我这个工厂的方法必须实现创建产品的方法,将创建的任务分给自己下属的各个工厂

// 原来的工厂
public class VideoFactory {

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

// 现在的工厂
public abstract class VideoFactory {
    public abstract Video getVideo();
}

你只要继承自我这个工厂,就得实现我这个创建的方法。

实例化推迟到子类:这个也很好理解,原来的调用方法是这样 VideoFactory.getVideo("java");,也就是说,这个时候类就已经实例化好了,但是,如果是工厂方法,那么调用方法就是如下

VideoFactory videoFactory = new JavaVideoFactory();
Video javaVideo = videoFactory.getVideo();

JavaVideoFactory.java方法如下

public class JavaVideoFactory extends VideoFactory {
    public Video getVideo() {
        return new JavaVideo();
    }
}

在创建具体的工厂时不必创建子类,只有我真正去取的时候才会进行创建,也就是将实例化推迟到子类

抽象类还是接口

在创建 VideoFactory 类的时候,是将它定义为抽象类还是定义为接口呢?我认为应该具体抉择:如果你的目的很单纯,就是一个产品一个工厂,且职责就是创建产品,没有其他的功能,那么抽象类和接口都是 OK 的,不管用接口还是抽象类引用都是无所谓的。但是如果你还想有一些默认方法或者一些默认动作,比如子类工厂都有的公共部分,可以抽取出来,这个时候就可以使用抽象类提供的默认方法等,只把不同的地方即创建产品进行抽象即可。所以还得看具体的问题分析

工厂方法模式的优缺点

由于每次增加新的产品都得创建对应的工厂,这就很容易导致类的数量过多,增加系统的复杂度,同时可能需要使用 DOM、反射等技术实现,这就增加了理解的难度。

但是工厂方法也是有不错的有点的,首先,用户不需要知道产品名称是什么,只需要产品在哪个工厂,通过工厂创建即可,其次,简单工厂符合开闭原则,增加新的产品时,只要增加一个产品类和一个具体的工厂类即可,不需要修改已有的代码,可扩展性非常的强,最后由子类决定创建何种对象,将任务分配到各个子类中去,维护起来更家的容易。

所以说,工厂方法应用的地方就是他的优点适用的地方

工厂方法在 JDK 中的应用
  • Collection接口中的iterator()方法就是一个工厂方法,只要实现了这个接口的类都得实现这个方法
  • JDBC 中的数据库连接,切换数据库只要更改连接驱动即可

等等,工厂方法模式的应用还是挺广的,下一节将会对抽象工厂方法具体的分析

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值