和工厂相关的设计模式主要有三种,工厂方法模式,抽象工厂模式;
在前面的博客中介绍了简单工厂模式,本篇博客主要介绍的是工厂方法模式
什么是工厂方法模式工厂方法模式是简单工厂的进一步的深化,在工厂方法模式中,不再提供统一的工厂类来创建不同的对象,针对不同的类,选择使用了不同的工厂;可以这样理解:每一个类都是有自己的工厂来创建自己的对象(实例)的;
工厂方法模式的定义:定义一个用于创建对象的接口(ReaderFactory),让子类(***Factory)决定哪儿个类进行实例化,工厂方法模式让一个类的实例化延迟到其子类;
工厂方法是一种创建设计模式,即与对象创建有关。在工厂方法模式中,创建对象而不将创建逻辑暴露给调用者,调用者使用相同的通用接口来创建新类型的对象;
工厂模式是创建对象的核心设计原则之一,它允许客户端以不与库的类层次结构紧密耦合的方式创建库的对象(如下所述)
工厂方法模式的实现 应用场景的假设以及代码实现设计一种图片加载器的功能,这个图片加载功能抽象到接口中,不同的图片加载器类实现这个接口中的加载图片的接口即可,这样一来,所有的图片加载实现类都拥有了加载相关图片的功能。这个时候想要创建出来不同的图片加载器实例,一般使用 new 进行创建,但是这样一来,程序之间的耦合度就变高了,所以可以考虑工厂模式,简单工厂模式下面,在新添加功能的时候,会违反开闭原则,所以选择使用工厂方法的模式,给每个类都创建一个工厂类,一个工厂类实现一种实例,得到了解耦合的作用,同时保证了开闭原则;
首先完成加载器接口的设计,在这个接口中存在一个 Read() 方法,这个方法用来加载各种图片:
public interface Reader {
void read();
}
接口只是定义了图片加载的功能,具体的实现类如下面所示:
实现 Reader 接口,实现了加载 gif 图片的功能:
public class GifReader implements Reader{
@Override
public void read() {
System.out.println("加载 Gif 图片");
}
}
实现 Reader 接口,实现了加载 jpg 图片的功能:
public class JpgReader implements Reader{
@Override
public void read() {
System.out.println("加载 jpg 图片");
}
}
实现 Reader 接口,实现了加载 png 图片的功能:
public class PngReader implements Reader{
@Override
public void read() {
System.out.println("加载 png 图片");
}
}
至此,需要实现的功能接口以及实现功能接口的相关类已经创建出来的,但是此时使用不同的图片加载器类创建对象使得,程序之间的耦合度是比较高的,此时使用工厂模式的工厂方法模式,给每一个类创建一个工厂,也就是一个工厂只是创建特定的类的实例;
首先创建工厂接口,所有类对应的自己的工厂(工厂就是各个工厂类)都实现这个 getReader() 方法;
public interface ReaderFactory {
Reader getReader();
}
给每一个图片加载类都创建出来一个对应的工厂,这个工厂用来生产图片加载器类的实例:
GifReaderFactory 的实现:
public class GifReaderFactory implements ReaderFactory{
@Override
public Reader getReader() {
return new GifReader();
}
}
JpgReaderFactory 的实现:
public class JpgReaderFactory implements ReaderFactory{
@Override
public Reader getReader() {
return new JpgReader();
}
}
PngReaderFactory 的实现:
public class PngReaderFactory implements ReaderFactory{
@Override
public Reader getReader() {
return new PngReader();
}
}
用于生产各个图片加载器的工厂都创建好之后,可以不使用 new 关键就可以创建出来相关的图片加载器对象了,具体的使用方法如下所示,也就是测试代码:
public class TestFactoryMethodModel {
public static void main(String[] args) {
/**
* 代码的执行逻辑:
* 1、使用工厂方法模式下不同的工厂创建出来一个工厂对象
* 2、使用工厂对象生产出来一个用来加载特定图片的加载图片类的实例
* 3、加载图片类的实例创建创建出来了,调用 read() 方法,加载图片
*
* 想要获得图片加载器对象,前提是得到工厂类对象,用工厂类对象调用方法得到图片加载器对象;
* 工厂方法模式重点是,创建不同图片加载器对象,加载图片的对象创建出来之后,调用相关的方法执行加载图片即可;
*/
ReaderFactory jpgReaderFactory = new JpgReaderFactory();
Reader jpgReader = jpgReaderFactory.getReader();
jpgReader.read();
ReaderFactory pngReaderFactory = new PngReaderFactory();
Reader pngReader = pngReaderFactory.getReader();
pngReader.read();
ReaderFactory factory = new GifReaderFactory();
Reader reader = factory.getReader();
reader.read();
}
}
执行结果:
加载 jpg 图片
加载 png 图片
加载 Gif 图片
上面测试代码可能看不出来工厂方法的强大之处:请看下面的测试代码:
// 使用到多态,ReaderFactory factory = new GifReaderFactory(); 这一句diamante 中的 new 关键词后面的 GifReaderFactory 修改成为 JpgReaderFactory 或者 PngReaderFactory 的时候,创建出来的就是jpg 或者 png 的图片加载器
// 想要得到其他的图片加载器,相关的图片加载器实现 Reader 接口,对应的图片加载器类工厂实现 ReaderFactory 接口 ,在测试中,只是需要修改 new 关键字后面的这个类即可,其他的代码都是不需要改动的,符合开闭原则,是一种比较好的设计
public class TestFactoryMethodModel {
public static void main(String[] args) {
ReaderFactory factory = new GifReaderFactory();
Reader reader = factory.getReader();
reader.read();
}
}
简单工厂模式与工厂方法模式对比
简单工厂模式是所有的实现类共同使用一个工厂类,但是如果想要增加新的功能的时候,需要修改工厂类的代码,是不符合开闭原则的,也就是不符合开放扩展,关闭修改的;每次添加新功能的时候,就修改一次工厂类的代码的的设计是十分糟糕的;
工厂方法模式相对来说,写的代码多了一些,也就是所谓的每一个实现类都拥有自己的工厂,虽然代码量增加了,但是在增加了新的功能的时候,不需要修改原来的代码,可以扩展使用,较好的符合开闭原则;
小结本文重点介绍了工厂方法模式,介绍了工厂方法模式的额使用背景,以及具体的代码实现,比较了简单工厂模式以及工厂方法模式之间的区别;需要注意的是,无论是简单工厂模式还是工厂方法模式,都是为了程序之间解耦合使用的,使得程序的维护成本降低;
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)