导语
前一篇文章,简单的讲述了关于简单工厂模式,本篇将继续 讲述工厂方法的定义,以及它的相关实现。且看看在JDK源码或框架源码中,有哪些地方有使用。
一、工厂方法的定义和类型
定义:定义一个对象的接口,但让实现这个接口的类来决定实例化哪个类,工厂方法让类的实例化推迟到子类中进行
类型:创建类型
二、工厂方法的适用场景和优缺点
适用场景:
- 创建对象需要重复大量代码
- 客户端(应用层)不依赖于产品类实例如何被创建、实现等细节
- 一个类通过其子类来指定创建哪个对象
优点:
- 用户只需要关心所需产品对应的工厂,无须关心创建细节
- 加入新产品符合开闭原则,提高可扩展性
缺点:
- 类的个数容易过多,增加复杂度
- 增加了系统的抽象性和理解难度
三、工厂方法UML类图和具体代码实现
从上面的UML图中,可以比较清晰的看出每个类之间的关系,工厂方法和简单工厂方法的区别,在于工厂方法中将一个对象的创建交由其子类来实现。但是还是使用代码体现出来比较好。接下来进行代码的展示:
1.首先创建冰箱的抽象类
public abstract class Fridge {
public abstract void produce();
}
2.再定义冰箱的具体品类实现类
public class PanasonicFridge extends Fridge {
@Override
public void produce() {
System.out.println("-----生产松下冰箱-----");
}
}
public class GeLiFridge extends Fridge {
@Override
public void produce() {
System.out.println("-----生产格力空调-----");
}
}
3.创建冰箱的工厂类
这个类和简单工厂方法的区别在于,这个类中的方法是抽象的,且不再传入任何参数。因为这里的具体实现是交由子类工厂去实现的。这里还需要理解一个概念,相同类型的产品,称之为产品等级。这里的产品等级都是在冰箱这个等级上,格力冰箱和松下冰箱都属于同一个产品等级。产品等级和产品族是对比工厂方法和抽象方法的一个重要的概念。
public abstract class FridgeFactory {
public abstract Fridge getFridge();
}
4.创建子类工厂实现
public class GeLiFridgeFactory extends FridgeFactory {
@Override
public Fridge getFridge() {
return new GeLiFridge();
}
}
public class PanasonicFridgeFactory extends FridgeFactory {
@Override
public Fridge getFridge() {
return new PanasonicFridge();
}
}
5.测试类
public class MainTest {
public static void main(String[] args) {
FridgeFactory fridgeFactory =new GeLiFridgeFactory();
Fridge fridge = fridgeFactory.getFridge();
fridge.produce();
}
}
测试结果:
四、简单工厂方法在JDK源码中的体现
相信在日常开发中,大多数人都接触过Collection这个接口类,在这类中有这样一个方法:
Iterator<E> iterator();
在这里这个Collection可以视为一个具体的抽象工厂,而 iterator()便是工厂方法。工厂方法也可以指作为工厂的一个方法,iterator()这个方法就正是作为工厂的一个方法。iterator()是以个接口,它有很多是实现类:
从上图中可以看到有很多的实现类,其中一个很熟悉的 ArrayList,点进去看会看到具体实现如下:
public Iterator<E> iterator() {
return new Itr();
}
private class Itr implements Iterator<E> {
int cursor; // index of next element to return
int lastRet = -1; // index of last element returned; -1 if no such
int expectedModCount = modCount;
Itr() {}
public boolean hasNext() {
return cursor != size;
}
@SuppressWarnings("unchecked")
public E next() {
checkForComodification();
int i = cursor;
if (i >= size)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i + 1;
return (E) elementData[lastRet = i];
}
public void remove() {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();
try {
ArrayList.this.remove(lastRet);
cursor = lastRet;
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
@Override
@SuppressWarnings("unchecked")
public void forEachRemaining(Consumer<? super E> consumer) {
Objects.requireNonNull(consumer);
final int size = ArrayList.this.size;
int i = cursor;
if (i >= size) {
return;
}
final Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length) {
throw new ConcurrentModificationException();
}
while (i != size && modCount == expectedModCount) {
consumer.accept((E) elementData[i++]);
}
// update once at end of iteration to reduce heap write traffic
cursor = i;
lastRet = i - 1;
checkForComodification();
}
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
}
在这里上面的iterator()方法的具体实现就交由子类去实现了,不同子类中实现能得到不同产品的实例。在这里可以理解ArrayList就是一个具体的实现工厂。这里具体的抽象产品就是 Itr 所实现的 Iterator这么一个接口。而 Itr 就是具体的产品。
版权声明:尊重博主原创文章,转载请注明出处:https://blog.csdn.net/zfy163520