小白自学设计模式之工厂模式

最简单的案例:

/**
 * 简单工厂模式
 *       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*/

猜你喜欢

转载自blog.csdn.net/crazyzhangxl/article/details/80604603