Android设计模式(五岁以下儿童)--简单工厂模式
1、面试的时候问这个问题:
在ListView 的item小程序。很多不同的显示风格。或者是,为了更好地维护,不同的样式,应该怎么做?
我一下就想到的是工厂的模式,利用project,编写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; } }