最简单的案例:
/**
* 简单工厂模式
* 1.就是指不需要使用new对象来创建实例,屏蔽了内部实现的细节
* */
class FactoryA{
private FactoryA(){}
public static FactoryA create(){
return new FactoryA();
}
public void showMethod(){
System.out.println("showMethod");
}
}
public class SampleFactory {
public static void main(String[] args){
FactoryA factoryA = FactoryA.create();
factoryA.showMethod();
}
}
/**
* 简单工厂模式
* 2. 实现的细节由子类去完成
* 以下案例是我们在 活动基类去抽取枝干,然后由子类去实现特色的地方
* */
abstract class BaseActivity{
abstract int getLayoutId();
void invokeLayout(){
invoke(getLayoutId());
}
final void invoke(int resID){
System.out.println("加载布局:"+resID);
}
}
class MyActivity extends BaseActivity{
@Override
int getLayoutId() {
return 0x123;
}
}
public class SampleFactory {
public static void main(String[] args){
MyActivity myActivity = new MyActivity();
myActivity.invokeLayout();
}
}
// output:加载布局:291
/**
* 简单工厂模式
* 3. 使用反射返回工厂对象
* */
class Api{
void method(){
System.out.println("APi");
}
}
class ImplApi extends Api{
@Override
void method() {
System.out.println("ImplApi");
}
}
class MyFactory{
public static <T extends Api> Api create(Class<T> cls){
Api api = null;
try {
api = (Api) Class.forName(cls.getName()).newInstance();
} catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
e.printStackTrace();
}
return api;
}
}
public class SampleFactory {
public static void main(String[] args){
Api api = MyFactory.create(ImplApi.class);
api.method();
}
}
// output:ImplApi
Android中有解析图片的方法亦是使用了工厂方法:
Bitmap bitmap = BitmapFactory.decodeFile("path"); // 传入路径返回Bitmap对象
如下代码所示调用了 decodeStream()方法返回Bitmap对象
public static Bitmap decodeFile(String pathName, Options opts) {
validate(opts);
Bitmap bm = null;
InputStream stream = null;
try {
stream = new FileInputStream(pathName);
bm = decodeStream(stream, null, opts);
} 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 decodeStream(InputStream is, Rect outPadding, Options opts) {
// we don't throw in this case, thus allowing the caller to only check
// the cache, and not force the image to be decoded.
if (is == null) {
return null;
}
validate(opts);
Bitmap bm = null;
Trace.traceBegin(Trace.TRACE_TAG_GRAPHICS, "decodeBitmap");
try {
if (is instanceof AssetManager.AssetInputStream) {
final long asset = ((AssetManager.AssetInputStream) is).getNativeAsset();
bm = nativeDecodeAsset(asset, outPadding, opts);
} else {
bm = decodeStreamInternal(is, outPadding, opts);
}
if (bm == null && opts != null && opts.inBitmap != null) {
throw new IllegalArgumentException("Problem decoding into existing bitmap");
}
setDensityFromOptions(bm, opts);
} finally {
Trace.traceEnd(Trace.TRACE_TAG_GRAPHICS);
}
return bm;
}
然后具体的Native方法如下代码所示:
private static native Bitmap nativeDecodeStream(InputStream is, byte[] storage,
Rect padding, Options opts);
private static native Bitmap nativeDecodeFileDescriptor(FileDescriptor fd,
Rect padding, Options opts);
private static native Bitmap nativeDecodeAsset(long nativeAsset, Rect padding, Options opts);
private static native Bitmap nativeDecodeByteArray(byte[] data, int offset,
int length, Options opts);
private static native boolean nativeIsSeekable(FileDescriptor fd);
可以发现简单工厂在Android中还是很常用的,就是只需要传入特征的参数就可以生成特定的对象。
关于父类引用指向子类对象的疑惑案例:
/**
* 父类引用指向子类对象
* 对象的存在:表面和实际类型
* 表面类型决定能调用哪些方法
* 实际类型决定的是调用的时实际的执行方法
* */
class ABC{
void doSomething(){
System.out.println("ABC");
}
}
class ABCD extends ABC{
@Override
void doSomething() {
System.out.println("BCD");
}
void doMethod(){
}
}
public class TestB {
public static void main(String[] args){
ABC a = new ABCD();
a.doSomething();
// 不能调用子类的非继承重写方法!
}
}
/*output:BCD*/