Define an interface for creating an object,but let subclassed decide which class to instantiate.Factory Method lets a class defer instantiation to subclasses.
定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类
Product:定义产品的共性,实现对事物最抽象的定义
ConcreteProduct: 具体产品类
Creator:抽象创建类,也就是抽象工厂类
ConcreteCreator: 具体的工厂类
定义一个抽象的英雄类,分别可以获取血量和魔法值:
/**
* 抽象英雄类
*/
public abstract class Hero {
/**
* 英雄的血量
*/
public abstract void getBlood();
/**
* 英雄的魔法值
*/
public abstract void getMagicPoint();
}
定义二个具体的英雄类,一个英雄火枪–Sniper类,一个英雄白牛–SpiritBreaker类:
/**
* 英雄火枪--Sniper类
*/
public class Sniper extends Hero {
@Override
public void getBlood() {
// TODO Auto-generated method stub
System.out.println("火枪--Sniper blood is 2000");
}
@Override
public void getMagicPoint() {
// TODO Auto-generated method stub
System.out.println("火枪--Sniper magic point is 500");
}
}
/**
* 英雄白牛--SpiritBreaker类
*/
public class SpiritBreaker extends Hero{
@Override
public void getBlood() {
// TODO Auto-generated method stub
System.out.println("白牛--SpiritBreaker blood is 5000");
}
@Override
public void getMagicPoint() {
// TODO Auto-generated method stub
System.out.println("白牛--SpiritBreaker magic point is 1000");
}
}
定义一个抽象工厂类–AFactoryCreator:
public abstract class AFactoryCreator {
public abstract T creator(Class c);
}
定义具体的工厂类–FactoryCreator
public class FactoryCreator extends AFactoryCreator{
@Override
public T creator(Class c) {
// TODO Auto-generated method stub
Hero hero = null;
try {
hero = (Hero) Class.forName(c.getName()).newInstance();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return (T) hero;
}
}
客户端的工厂方法模式应用:FactoryMethod
public class FactoryMethod {
public static void main(String[] args) {
// TODO Auto-generated method stub
AFactoryCreator creator = new FactoryCreator();
Hero sniper = creator.creator(Sniper.class);
sniper.getBlood();
sniper.getMagicPoint();
Hero spiritBreaker = creator.creator(SpiritBreaker.class);
spiritBreaker.getBlood();
spiritBreaker.getMagicPoint();
}
}
程序运行输出:
火枪--Sniper blood is 2000
火枪--Sniper magic point is 500
白牛--SpiritBreaker blood is 5000
白牛--SpiritBreaker magic point is 1000
简单工厂模式:
我们再看这个例子,可以发现AFactoryCreator类是不是用处不大,但是增加了一个类,会导致系统的复杂度和清晰度。对于一些简单的例子,我们可以直接把AFactoryCreator类去掉,将FactoryCreator类的creator改为static方法,使用会更加方便,简洁。
修改如下:
public class StaticFactory {
public static T creator(Class c){
Hero hero = null;
try {
hero = (Hero)Class.forName(c.getName()).newInstance();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return (T)hero;
}
}
Client调用如下:
public class FactoryMethod {
public static void main(String[] args) {
// TODO Auto-generated method stub
Hero sniper = StaticFactory.creator(Sniper.class);
sniper.getBlood();
sniper.getMagicPoint();
Hero spiritBreaker = StaticFactory.creator(SpiritBreaker.class);
spiritBreaker.getBlood();
spiritBreaker.getMagicPoint();
}
}
上面就是简单工厂模式—Simple Factory Pattern ,也叫静态工厂模式,该方法应用广泛,非常的实用,缺点是工厂类扩展比较困难。
其UML类图如下:
静态工厂模式在android源码中是随处可见的,这主要是体现了其使用的简单和实用。
(1)BitmapFactory类
/frameworks/base/graphics/java/android/graphics/BitmapFactory.java
一个这个类名,就知道是创建Bitmap的工厂类,当然用的是工厂模式了。
public class BitmapFactory {
..................................
public static Bitmap decodeFile(String pathName, Options opts) {
return decodeFile(pathName, opts, true);
}
public static Bitmap decodeFile(String pathName, Options opts, boolean consumeRights) {
Bitmap bm = null;
InputStream stream = null;
try {
stream = new FileInputStream(pathName);
bm = decodeStream(stream, null, opts, consumeRights);
} catch (Exception e) {
/* do nothing.
If the exception happened on open, bm will be null.
*/
Log.e("BitmapFactory", "Unable to decode stream: " + e);
} finally {
if (stream != null) {
try {
stream.close();
} catch (IOException e) {
// do nothing here
}
}
}
return bm;
}
public static Bitmap decodeFile(String pathName) {
return decodeFile(pathName, null);
}
public static Bitmap decodeResourceStream(Resources res, TypedValue value,
InputStream is, Rect pad, Options opts) {
return decodeResourceStream(res, value, is, pad, opts, true);
}
public static Bitmap decodeResource(Resources res, int id, Options opts) {
return decodeResource(res, id, opts, true);
}
public static Bitmap decodeResource(Resources res, int id) {
return decodeResource(res, id, null, true);
}
public static Bitmap decodeResource(Resources res, int id, boolean consumeRights) {
return decodeResource(res, id, null, consumeRights);
}
public static Bitmap decodeByteArray(byte[] data, int offset, int length, Options opts) {
return decodeByteArray(data, offset, length, opts, true);
}
public static Bitmap decodeByteArray(byte[] data, int offset, int length) {
return decodeByteArray(data, offset, length, null, true);
}
public static Bitmap decodeByteArray(byte[] data, int offset, int length,
boolean consumeRights) {
return decodeByteArray(data, offset, length, null, consumeRights);
}
public static Bitmap decodeStream(InputStream is, Rect outPadding, Options opts) {
return decodeStream(is, outPadding, opts, true);
}
private static Bitmap decodeStreamInternal(InputStream is, Rect outPadding, Options opts, boolean consumeRights) {
// ASSERT(is != null);
byte [] tempStorage = null;
if (opts != null) tempStorage = opts.inTempStorage;
if (tempStorage == null) tempStorage = new byte[DECODE_BUFFER_SIZE];
return nativeDecodeStream(is, tempStorage, outPadding, opts, consumeRights);
}
public static Bitmap decodeStream(InputStream is) {
return decodeStream(is, null, null);
}
public static Bitmap decodeFileDescriptor(FileDescriptor fd, Rect outPadding, Options opts) {
return decodeFileDescriptor(fd, outPadding, opts, true);
}
public static Bitmap decodeFileDescriptor(FileDescriptor fd) {
return decodeFileDescriptor(fd, null, null);
}
private static native Bitmap nativeDecodeStream(InputStream is, byte[] storage,
Rect padding, Options opts, boolean consumeRights);
...............
}
这个样例,我们可以看到Bitmap工厂类非常方便的得到各自Bitmap对象,这才是静态工厂模式的精髓所以。
下面这个android样例中,我们可以看到静态工厂模式与单例模式组合使用,可以方便的得到唯一的对象:
源码是Camera应用:
packages/apps/SnapdragonCamera/src/com/android/camera/CameraManagerFactory.java
/**
* A factory class for {@link CameraManager}.
*/
public class CameraManagerFactory {
private static AndroidCameraManagerImpl sAndroidCameraManager;
/**
* Returns the android camera implementation of {@link CameraManager}.
*
* @return The {@link CameraManager} to control the camera device.
*/
public static synchronized CameraManager getAndroidCameraManager() {
if (sAndroidCameraManager == null) {
sAndroidCameraManager = new AndroidCameraManagerImpl();
}
return sAndroidCameraManager;
}
}
(1). Android设计模式源码解析之工厂方法模式
https://github.com/hfreeman2008/android_design_patterns_analysis/tree/master/factory-method/AigeStudio
(2).设计模式之禅—第8章 工厂方法模式