Android设计模式(五)--简单工厂模式

1、面试的时候问到这样的问题:

在一个ListView 的item子视图中,很多种不同的显示样式,或者说是,为了更好的维护,或者以后需要添加不同的样式,应该怎么做?

我一下就想到的是工厂的模式,利用工程,编写ViewFactory,方法中有getView()的方法,以后需要时,添加相应的参数,并编写不同的实现类,也就是不同样式的视图;


但是这样的答案,似乎没有让面试官满意;


他的意思是,书写不同的Adapter ,通过适配器中的getView()获取不同的View,即:一个样式的视图,对应一个Adapter,即在listView中一个Adapter,这个Adapter中拥有很多不同样式的Adapter,这样初始化,编写的时候,listView的Adapter就不需要修改了,这样只需要,添加以后需要的那个视图样式的adapter 就可以了。


回顾设计模式的时候,突然想到这样的问题,便写了下来,

想到的是,其实面试的时候,我这样的回答是可以解决问题的,只是以前学的时候,没有考虑到简单工厂模式的缺点。

现在需要学习的就是这个了;


言归正传

Android设计模式--简单工厂模式

1、 定义:
属于创建型模式,又叫做静态工厂方法(Static Factory Method)模式,但不属于23种GOF设计模式之一。


2、实质:
实质是由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类;


3、 工厂角色:
这是简单工厂模式的核心,由它负责创建所有的类的内部逻辑。


4、优点:
不必管这些对象究竟如何创建及如何组织的.明确了各自的职责和权利,有利于整个软件体系结构的优化。


5、缺点:
5.1、工厂类所能创建的类只能是事先考虑到的,如果需要添加新的类,则就需要改变工厂类了;
5.2、工厂类集中了所有实例的创建逻,当对象越来越多时,工厂类对系统的维护和扩展非常不利;
5.3、简单工厂模式违背了“开放封闭原则”,就是违背了“系统对扩展开放,对修改关闭”的原则,违反了高内聚责任分配原则;
5.4、当需要添加产品类时,工厂类内部的逻辑需要改动很多很多;

6、尽管面试也是失败了,但是学习还是不能停啊,

写了一个简单的demo:


接口类:

package com.example.demo.SimpleFactory;
/**
 * 统一的彩票接口
 * @author qubian
 * @data 2015年6月4日
 * @email naibbian@163.com
 *
 */
public interface Lottery {

	public String getLotteryName();
}

具体的实现:

package com.example.demo.SimpleFactory;
/**
 * 双色球 处理
 * 
 * @author qubian
 * @data 2015年6月4日
 * @email naibbian@163.com
 *
 */
public class SSQLottery implements Lottery{

	@Override
	public  String getLotteryName() {

		return "双色球";
	}

}


package com.example.demo.SimpleFactory;

/**
 *  大乐透处理
 * @author qubian
 * @data 2015年6月4日
 * @email naibbian@163.com
 *
 */
public class DLTLottery implements Lottery{

	@Override
	public String getLotteryName() {

		return "大乐透";
	}

}

核心工厂类:

package com.example.demo.SimpleFactory;

/**
 * 彩票彩种工厂处理
 * @author qubian
 * @data 2015年6月4日
 * @email naibbian@163.com
 *
 */
public class LotteryFactory {
	
	public enum LotteryEnum {
        SSQ, DLT, QLC,FC3D,FJ115;
	}
	private static Lottery lottery =null;
	
	public static Lottery getLottery(LotteryEnum e)
	{
		if (e ==LotteryEnum.SSQ) {
			 lottery= new SSQLottery();
		}else if (e ==LotteryEnum.SSQ) {
			 lottery= new DLTLottery();
		}
		return lottery;
	}
	
	public static String getLotteryName(LotteryEnum e)
	{

		return getLottery(e).getLotteryName();
	}
	
	
}

使用:

package com.example.demo.SimpleFactory;

import com.example.demo.SimpleFactory.LotteryFactory.LotteryEnum;
import android.util.Log;
/**
 * 使用
 * @author qubian
 * @data 2015年6月4日
 * @email naibbian@163.com
 *
 */
public class UseSimpleFactory {
	private static final String TAG="UseSimpleFactory";
	public void use()
	{
		Log.i(TAG, LotteryFactory.getLotteryName(LotteryEnum.SSQ));
	}
}


当然,简单工厂在Android 源码中有典型的运用: BitmapFactory

public class BitmapFactory {
    private static final int DECODE_BUFFER_SIZE = 16 * 1024;

    public static class Options {
        /**
         * Create a default Options object, which if left unchanged will give
         * the same result from the decoder as if null were passed.
         */
        public Options() {
            inDither = false;
            inScaled = true;
            inPremultiplied = true;
        }
    /**
     * Decode a file path into a bitmap. If the specified file name is null,
     * or cannot be decoded into a bitmap, the function returns null.
     *
     * @param pathName complete path name for the file to be decoded.
     * @param opts null-ok; Options that control downsampling and whether the
     *             image should be completely decoded, or just is size returned.
     * @return The decoded bitmap, or null if the image data could not be
     *         decoded, or, if opts is non-null, if opts requested only the
     *         size be returned (in opts.outWidth and opts.outHeight)
     */
    public static Bitmap decodeFile(String pathName, Options 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;
    }
    /**
     * Decode a file path into a bitmap. If the specified file name is null,
     * or cannot be decoded into a bitmap, the function returns null.
     *
     * @param pathName complete path name for the file to be decoded.
     * @return the resulting decoded bitmap, or null if it could not be decoded.
     */
    public static Bitmap decodeFile(String pathName) {
        return decodeFile(pathName, null);
    }

    /**
     * Decode a new Bitmap from an InputStream. This InputStream was obtained from
     * resources, which we pass to be able to scale the bitmap accordingly.
     */
    public static Bitmap decodeResourceStream(Resources res, TypedValue value,
            InputStream is, Rect pad, Options opts) {

        if (opts == null) {
            opts = new Options();
        }

        if (opts.inDensity == 0 && value != null) {
            final int density = value.density;
            if (density == TypedValue.DENSITY_DEFAULT) {
                opts.inDensity = DisplayMetrics.DENSITY_DEFAULT;
            } else if (density != TypedValue.DENSITY_NONE) {
                opts.inDensity = density;
            }
        }
        
        if (opts.inTargetDensity == 0 && res != null) {
            opts.inTargetDensity = res.getDisplayMetrics().densityDpi;
        }
        
        return decodeStream(is, pad, opts);
    }
    /**
     * Synonym for {@link #decodeResource(Resources, int, android.graphics.BitmapFactory.Options)}
     * will null Options.
     *
     * @param res The resources object containing the image data
     * @param id The resource id of the image data
     * @return The decoded bitmap, or null if the image could not be decode.
     */
    public static Bitmap decodeResource(Resources res, int id) {
        return decodeResource(res, id, null);
    }

    /**
     * Decode an immutable bitmap from the specified byte array.
     *
     * @param data byte array of compressed image data
     * @param offset offset into imageData for where the decoder should begin
     *               parsing.
     * @param length the number of bytes, beginning at offset, to parse
     * @param opts null-ok; Options that control downsampling and whether the
     *             image should be completely decoded, or just is size returned.
     * @return The decoded bitmap, or null if the image data could not be
     *         decoded, or, if opts is non-null, if opts requested only the
     *         size be returned (in opts.outWidth and opts.outHeight)
     */
    public static Bitmap decodeByteArray(byte[] data, int offset, int length, Options opts) {
        if ((offset | length) < 0 || data.length < offset + length) {
            throw new ArrayIndexOutOfBoundsException();
        }

        Bitmap bm;

        Trace.traceBegin(Trace.TRACE_TAG_GRAPHICS, "decodeBitmap");
        try {
            bm = nativeDecodeByteArray(data, offset, length, 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;
    }
}







  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值