美文网首页
java 设计模式:简单工厂

java 设计模式:简单工厂

作者: 王二蛋和他的狗 | 来源:发表于2021-04-20 11:52 被阅读0次

工厂模式的定义

定义一个创建产品对象的工厂接口,将产品对象的实际创建工作推迟到具体子工厂类当中。这满足创建型模式中所要求的“创建与使用相分离”的特点。

简单工厂

如果要创建的产品不多,只要一个工厂类就可以完成,这种模式叫“简单工厂模式”。

简单工厂通常为静态方法,因此又叫静态工厂方法模式

优点:

  • 工厂类包含必要的逻辑判断,可以决定在什么时候创建哪一个产品的实例。客户端可以免除直接创建产品对象的职责,很方便的创建出相应的产品。工厂和产品的职责区分明确。
  • 客户端无需知道所创建具体产品的类名,只需知道参数即可。
    也可以引入配置文件,在不修改客户端代码的情况下更换和添加新的具体产品类。

缺点:

  • 简单工厂模式的工厂类单一,负责所有产品的创建,职责过重,一旦异常,整个系统将受影响。且工厂类代码会非常臃肿,违背高聚合原则。
  • 使用简单工厂模式会增加系统中类的个数(引入新的工厂类),增加系统的复杂度和理解难度
  • 系统扩展困难,一旦增加新产品不得不修改工厂逻辑,在产品类型较多时,可能造成逻辑过于复杂
  • 简单工厂模式使用了 static 工厂方法,造成工厂角色无法形成基于继承的等级结构。

应用场景

对于产品种类相对较少的情况,考虑使用简单工厂模式。使用简单工厂模式的客户端只需要传入工厂类的参数,不需要关心如何创建对象的逻辑,可以很方便地创建所需产品。

代码实现

简单工厂模式的主要角色如下:

  • 简单工厂:是简单工厂模式的核心,负责实现创建所有实例的内部逻辑。工厂类的创建产品类的方法可以被外界直接调用,创建所需的产品对象。
  • 抽象产品:是简单工厂创建的所有对象的父类,负责描述所有实例共有的公共接口。
  • 具体产品:是简单工厂模式的创建目标。

其结构图如下图所示。


在这里插入图片描述

kotlin代码实现

interface IProduct{
    fun showName() :String
}

class Dog : IProduct{
    override fun showName() = "dog"

}

class Cat : IProduct{
    override fun showName() = "cat"
}

object AnimalFactory{
    fun createAnimal(type:Int):IProduct{
        return when(type){
            1-> Dog()
            2-> Cat()
            else -> throw NullPointerException()
        }
    }
}

简单工厂模式在Android中的实际应用

fragment 的构建

有时候,为了简化简单工厂模式,我们可以将抽象产品类和工厂类合并,将静态工厂方法移至抽象产品类中。Fragment的创建使用简单工厂方法没有抽象产品类,所以工厂类放到了实现产品类中。

class ListWorkFragment : BMvpFragment<ListWorkView ,ListWorkPresenter>(),ListWorkView,ISubjectView{
        companion object {
        @JvmStatic
        fun newInstance(recommendTypeId: Int,
                        termCode: String = "") =
            ListWorkFragment().apply {
                arguments = Bundle().apply {
                    putInt("type", recommendTypeId)
                    putString("code", termCode)
                }
            }
    }

优点

  1. 在创建Fragment的时候,可以不需要管内部参数,而从外部输入
  2. Fragment推荐使用setArguments来传递参数,避免在横竖屏切换的时候Fragment自动调用自己的无参构造函数,导致数据丢失。

Bitmap源码分析

@UnsupportedAppUsage(maxTargetSdk = 28)
    Bitmap(long nativeBitmap, int width, int height, int density,
            boolean requestPremultiplied, byte[] ninePatchChunk,
            NinePatch.InsetStruct ninePatchInsets) {
        this(nativeBitmap, width, height, density, requestPremultiplied, ninePatchChunk,
                ninePatchInsets, true);
    }

    // called from JNI and Bitmap_Delegate.
    Bitmap(long nativeBitmap, int width, int height, int density,
            boolean requestPremultiplied, byte[] ninePatchChunk,
            NinePatch.InsetStruct ninePatchInsets, boolean fromMalloc) {
        ...
    }

看构造函数可知,无法new出bitmap,那么怎么创建bitmap对象呢?

 BitmapFactory.decodeFile("")

内部源码

public static Bitmap decodeFile(String pathName) {
    return decodeFile(pathName, null);
}

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;
}

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;
    }

    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;
}

private static native Bitmap nativeDecodeStream(InputStream is, byte[] storage,
        Rect padding, Options opts);

/**
 * Set the newly decoded bitmap's density based on the Options.
 */
private static void setDensityFromOptions(Bitmap outputBitmap, Options opts) {
    if (outputBitmap == null || opts == null) return;

    final int density = opts.inDensity;
    if (density != 0) {
        outputBitmap.setDensity(density);
        final int targetDensity = opts.inTargetDensity;
        if (targetDensity == 0 || density == targetDensity || density == opts.inScreenDensity) {
            return;
        }

        byte[] np = outputBitmap.getNinePatchChunk();
        final boolean isNinePatch = np != null && NinePatch.isNinePatchChunk(np);
        if (opts.inScaled || isNinePatch) {
            outputBitmap.setDensity(targetDensity);
        }
    } else if (opts.inBitmap != null) {
        // bitmap was reused, ensure density is reset
        outputBitmap.setDensity(Bitmap.getDefaultDensity());
    }
}

看下BitmapFactory的注释我们可以看到,这个工厂支持从不同的资源创建Bitmap对象,包括files, streams, 和byte-arrays,但是调用关系都大同小异。

相关文章

  • 简单工厂模式

    Java23种设计模式--简单工厂模式 一、什么是简单工厂模式 简单工厂模式属于类的创建型模式,又叫做静态工厂方法...

  • 设计模式系列-简单工厂模式

    JAVA设计模式系列: 单例模式 观察者模式 模板方法模式 简单工厂模式 定义 简单工厂模式又叫做静态工厂方法模式...

  • 工厂模式

    java设计模式-工厂模式 工厂模式: 工厂模式是java设计模式里最常用的设计模式之一。 工厂模式属于创建型模式...

  • JAVA基础23种设计模式----简单工厂模式--MonkeyK

    JAVA基础23种设计模式----简单工厂模式--MonkeyKing 简单工厂模式属于类的创建模型模式,又叫静态...

  • Java设计模式教程

    Java设计模式教程 Java工厂设计模式 Java抽象工厂模式 Java单例模式 Java建造者(Builder...

  • Java 设计模式1-简单工厂模式

    简单工厂模式不属于标准的Java 23设计模式之内。根据分类,简单工厂模式又分类为:1.普通简单工厂模式。2.多方...

  • 设计模式系列-抽象工厂模式

    JAVA设计模式系列: 单例模式 观察者模式 模板方法模式 简单工厂模式 抽象工厂模式 抽象工厂模式 定义 抽象工...

  • Java设计模式-工厂方法模式

    上一篇:Java设计模式-简单工厂模式 与简单工厂模式的对比 在简单工厂模式中,每当我们添加了新的功能(例如例子中...

  • 设计模式-工厂模式

    设计模式1 设计模式2 工厂模式 工厂模式可简单的分为三类:简单工厂,工厂方法,抽象工厂 简单工厂模式 定义 简单...

  • 设计模式 - 工厂模式

    概述 我们都知道Java中共有 23 种设计模式,其中工厂模式分为三种,即:简单工厂模式(不在 23 种设计模式之...

网友评论

      本文标题:java 设计模式:简单工厂

      本文链接:https://www.haomeiwen.com/subject/notnlltx.html