设计模式之——工厂模式
来源:互联网 发布:java模式 编辑:程序博客网 时间:2024/06/06 02:35
转载请注明出处:http://blog.csdn.net/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对象,可以说工厂模式无处不在。使用工厂模式能够使客户与产品解耦,但同时也导致类结构的复杂化,所以,具体在使用的时候还是需要去权衡利弊。。。
好了,今天的讲解到此结束,有不明白的童鞋可以在下方留言~
源码下载
- 设计模式之——工厂模式
- 设计模式之——工厂模式
- 设计模式之——工厂模式
- 设计模式之——工厂模式
- Java设计模式之工厂模式——简单工厂
- 设计模式——工厂模式之简单工厂
- 设计模式——工厂模式之工厂方法
- 设计模式——创建型模式之工厂模式
- 设计模式—工厂模式
- 设计模式—工厂模式
- 设计模式—工厂模式
- 设计模式—工厂模式
- 设计模式—工厂模式
- 设计模式—工厂模式
- 设计模式—工厂模式
- 设计模式—工厂模式
- 设计模式—工厂模式
- 设计模式—工厂模式
- SQL分类
- spring学习笔记(二)
- 检查网络是否连接
- 机器人操作系统ROS笔记--Gazebo的使用
- 稀疏矩阵的表示和运算
- 设计模式之——工厂模式
- 解决WiFi固件编译错误:STATION_INFO_ASSOC_REQ_IES
- kafka数据可靠性深度解读
- 比较PHP和JSP这两个Web开发
- UVA
- golang中实现每次产生的随机数都不同
- 170511 逆向-OD的其他功能
- spring学习笔记(三)
- tomcat中文乱码问题