设计模式之——工厂模式

来源:互联网 发布:java模式 编辑:程序博客网 时间:2024/06/06 02:35

转载请注明出处: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
原创粉丝点击