设计模式之——工厂模式

###转载请注明出处:http://blog.csdn.net/binbinqq86/article/details/71775093

工厂模式(Factory Pattern),听到这个词,可能首先想到的就是批量生产,没错,这个模式就是用来制造对象的。工厂模式是一个大的概念,细分可以包含三种:

  1. 简单工厂模式(静态工厂模式)
  2. 工厂方法模式
  3. 抽象工厂模式

首先来说一下简单工厂模式,看结构图:

这里写图片描述

整个结构非常简单,既然是工厂,肯定需要产品,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对象,可以说工厂模式无处不在。使用工厂模式能够使客户与产品解耦,但同时也导致类结构的复杂化,所以,具体在使用的时候还是需要去权衡利弊。。。

好了,今天的讲解到此结束,有不明白的童鞋可以在下方留言~

###源码下载

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值