###转载请注明出处:http://blog.youkuaiyun.com/binbinqq86/article/details/71775093
工厂模式(Factory Pattern),听到这个词,可能首先想到的就是批量生产,没错,这个模式就是用来制造对象的。工厂模式是一个大的概念,细分可以包含三种:
- 简单工厂模式(静态工厂模式)
- 工厂方法模式
- 抽象工厂模式
首先来说一下简单工厂模式,看结构图:
整个结构非常简单,既然是工厂,肯定需要产品,Phone就是我们的抽象产品,所有的手机都继承于它,而SimpleFactory有一个createPhone方法用来创建手机的实例对象,并返回给消费者,这就是一个工厂的职责,通常把createPhone设置为静态方法,这样就不用创建工厂对象,也被称为静态工厂模式,这是最简单的工厂模式,下面是代码:
package com.example.tb.designpatten.factory.simplefactory;
import android.util.Log;
/**
* Created by tb on 2017/5/13.
* 以手机为我们的产品
*/
public class Phone {
private static final String TAG = "Phone";
/**
* @param type 手机型号
*/
public Phone(String type){
printPhoneType(type);
}
public void printPhoneType(String type){
Log.d(TAG, "printPhoneType: "+type);
}
}
package com.example.tb.designpatten.factory.simplefactory;
/**
* Created by tb on 2017/5/13.
* 以小米2为例
*/
public class MI2 extends Phone{
/**
* @param type 手机型号
*/
public MI2(String type) {
super(type);
}
}
package com.example.tb.designpatten.factory.simplefactory;
/**
* Created by tb on 2017/5/13.
* 以小米3为例
*/
public class MI3 extends Phone{
/**
* @param type 手机型号
*/
public MI3(String type) {
super(type);
}
}
package com.example.tb.designpatten.factory.simplefactory;
/**
* Created by tb on 2017/5/13.
* 简单工厂模式(将createPhone方法改为静态就是静态工厂)
*/
public class SimpleFactory {
public Phone createPhone(String type){
Phone phone=null;
if(type.equals("mi2")){
phone=new MI2("mi2");
}else if(type.equals("mi3")){
phone=new MI3("mi3");
}else{
phone=new Phone("unknown");
}
return phone;
}
}
public void test(){
SimpleFactory simpleFactory=new SimpleFactory();
simpleFactory.createPhone("mi2");
}
简单工厂模式就这么多,很容易理解了。下面我们看一下工厂方法模式,老规矩上图:
可以看出,工厂方法模式跟简单工厂模式不同的就是把工厂也给抽象化了,这样就可以通过创建不同的工厂来实现不同的目的,比如中国的工厂,印度的工厂等等,代码就不贴出来了,跟上面几本类似,工厂方法模式定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法把类的实例化推迟到子类。
最后再来看下抽象工厂模式。这个模式可以创建产品的家族,看看它的定义:提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。抽象工厂和工厂方法的区别就是产品的纬度增加了,由一个产品变成了多个产品,工厂和产品是多对多的关系,工厂方法中则是多对一的关系。
抽象工厂允许客户使用抽象接口来创建一组相关的产品,而不需要知道或者关心实际产出的具体产品是什么,这样一来,客户就从具体产品中被解耦。下面还是通过我们生产手机的例子来说明问题,看图:
可以看出抽象工厂模式的类繁多,但是,主要还是分为4类:
- AbstractFactory:抽象工厂角色,它声明了一组用于创建一种产品的方法,每一个方法对应一种产品,如上图中的就定义了两个方法,分别创建cpu和内存。
- ConcreteFactory:具体工厂角色,它实现了在抽象工厂中定义的创建产品的方法,生成一组具体产品,这些产品构成了一个产品种类,每一个产品都位于某个产品等级结构中,如上图的Factory1和Factory2.
- AbstractProduct:抽象产品角色,它为每种产品声明接口,比如上面的cpu和内存
- ConcreteProduct:具体产品角色,它定义具体工厂生产的具体产品对象,实现抽象产品接口中声明的业务方法,如上图中的CpuHelio、CpuSnapDragon、MemorySamsung、MemoryToshiba
下面我们来看看具体的代码:
package com.example.tb.designpatten.factory.abstractfactory.cpu;
/**
* Created by tb on 2017/5/13.
* cpu基类
*/
public abstract class Cpu {
public abstract void printInfo();
}
package com.example.tb.designpatten.factory.abstractfactory.cpu;
import android.util.Log;
/**
* Created by tb on 2017/5/13.
* 华为的cpu
*/
public class CpuHelio extends Cpu{
@Override
public void printInfo() {
Log.d("CPU:","CpuHelio");
}
}
package com.example.tb.designpatten.factory.abstractfactory.cpu;
import android.util.Log;
/**
* Created by tb on 2017/5/13.
* 高通的cpu
*/
public class CpuSnapDragon extends Cpu{
@Override
public void printInfo() {
Log.d("CPU:","CpuSnapDragon");
}
}
package com.example.tb.designpatten.factory.abstractfactory.memory;
/**
* Created by tb on 2017/5/13.
* 内存基类
*/
public abstract class Memory {
public abstract void printInfo();
}
package com.example.tb.designpatten.factory.abstractfactory.memory;
import android.util.Log;
/**
* Created by tb on 2017/5/13.
* 三星的内存
*/
public class MemorySamsung extends Memory{
@Override
public void printInfo() {
Log.d("Memory:","MemorySamsung");
}
}
package com.example.tb.designpatten.factory.abstractfactory.memory;
import android.util.Log;
/**
* Created by tb on 2017/5/13.
* 东芝的内存
*/
public class MemoryToshiba extends Memory{
@Override
public void printInfo() {
Log.d("Memory:","MemoryToshiba");
}
}
package com.example.tb.designpatten.factory.abstractfactory;
import com.example.tb.designpatten.factory.abstractfactory.cpu.Cpu;
import com.example.tb.designpatten.factory.abstractfactory.memory.Memory;
/**
* Created by tb on 2017/5/13.
* 抽象工厂
*/
public abstract class AbstractFactory {
/**
* 手机cpu
* @return
*/
public abstract Cpu getCpu();
/**
* 手机内存
* @return
*/
public abstract Memory getMemory();
}
package com.example.tb.designpatten.factory.abstractfactory;
import com.example.tb.designpatten.factory.abstractfactory.cpu.Cpu;
import com.example.tb.designpatten.factory.abstractfactory.cpu.CpuHelio;
import com.example.tb.designpatten.factory.abstractfactory.memory.Memory;
import com.example.tb.designpatten.factory.abstractfactory.memory.MemorySamsung;
/**
* Created by tb on 2017/5/13.
* 具体工厂类1
*/
public class Factory1 extends AbstractFactory{
@Override
public Cpu getCpu() {
return new CpuHelio();
}
@Override
public Memory getMemory() {
return new MemorySamsung();
}
}
package com.example.tb.designpatten.factory.abstractfactory;
import com.example.tb.designpatten.factory.abstractfactory.cpu.Cpu;
import com.example.tb.designpatten.factory.abstractfactory.cpu.CpuHelio;
import com.example.tb.designpatten.factory.abstractfactory.cpu.CpuSnapDragon;
import com.example.tb.designpatten.factory.abstractfactory.memory.Memory;
import com.example.tb.designpatten.factory.abstractfactory.memory.MemorySamsung;
import com.example.tb.designpatten.factory.abstractfactory.memory.MemoryToshiba;
/**
* Created by tb on 2017/5/13.
* 具体工厂类2
*/
public class Factory2 extends AbstractFactory{
@Override
public Cpu getCpu() {
return new CpuSnapDragon();
}
@Override
public Memory getMemory() {
return new MemoryToshiba();
}
}
public void test(){
Factory1 factory1=new Factory1();
factory1.getCpu().printInfo();
factory1.getMemory().printInfo();
Factory2 factory2=new Factory2();
factory2.getCpu().printInfo();
factory2.getMemory().printInfo();
}
代码也很简单,以上就是所有相关工厂模式的介绍了,关于它的应用,在Java源码中也可以找到,我们常用的List和Set都继承于Collection接口,而Collection继承于Iterable接口,Iterable接口很简单,其中的iterator方法就是一个工厂方法,为什么呢?在ArrayList和HashSet中,我们可以去查看下源码,它们都实现了Iterable接口的iterator方法,并返回一个对象,这与我们的定义不谋而合:
public interface Iterable<T> {
/**
* Returns an iterator over elements of type {@code T}.
*
* @return an Iterator.
*/
Iterator<T> iterator();
}
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
/**
* Returns an iterator over the elements in this list in proper sequence.
*
* <p>The returned iterator is <a href="#fail-fast"><i>fail-fast</i></a>.
*
* @return an iterator over the elements in this list in proper sequence
*/
public Iterator<E> iterator() {
return new Itr();
}
/**
* An optimized version of AbstractList.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;
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();
}
}
}
public class HashSet<E>
extends AbstractSet<E>
implements Set<E>, Cloneable, java.io.Serializable
{
/**
* Returns an iterator over the elements in this set. The elements
* are returned in no particular order.
*
* @return an Iterator over the elements in this set
* @see ConcurrentModificationException
*/
public Iterator<E> iterator() {
return map.keySet().iterator();
}
}
HashSet的iterator方法中返回的是成员变量map中对应的HashSet对象元素的迭代器对象,而最终返回的是KeySet中的一个迭代器对象,看代码:
public class HashMap<K,V> extends AbstractMap<K,V>
implements Map<K,V>, Cloneable, Serializable {
public Set<K> keySet() {
Set<K> ks;
return (ks = keySet) == null ? (keySet = new KeySet()) : ks;
}
final class KeySet extends AbstractSet<K> {
public final Iterator<K> iterator() { return new KeyIterator(); }
}
}
通过上面可以看出,iterator方法相当于一个工厂方法,专门为new对象而生。而在Android中工厂模式的应用也很多,比如我们第一次就接触Android就看到的Activity的onCreate方法,它里面的setContentView就是工厂方法,用来制造新的view对象,每个Activity都相当于一个工厂,制造不同的view对象,可以说工厂模式无处不在。使用工厂模式能够使客户与产品解耦,但同时也导致类结构的复杂化,所以,具体在使用的时候还是需要去权衡利弊。。。
好了,今天的讲解到此结束,有不明白的童鞋可以在下方留言~
###源码下载