在为Android开发时,我遇到了 Bitmap 类。我觉得奇怪的是,这个类没有公共构造函数,而是提供静态createBitmap
函数,其目的完全相同。
从句法上讲,没有任何优势:
Bitmap bm = new Bitmap(10, 10);
Bitmap bm = Bitmap.createBitmap(10, 10);
我已经看到其他类也这样做,其中等效的静态函数通常被命名为newInstance
。这是什么原因?
答案 0 :(得分:6)
您所描述的内容称为工厂方法。它之所以存在是因为它提供了获取符合特定接口但可能具有不同底层实现的对象的能力。
对于(一个完全任意且无关紧要的)示例,Factory方法可以选择向您提供LinkedList对象而不是ArrayList对象,因为您指定的初始大小在LinkedList中可能具有性能优势。
但是两个列表实现都符合IList接口,因此生成的对象将作为IList返回。
答案 1 :(得分:1)
在第一种情况下,您需要实例化特定类型。在第二步中,您将其留给实施者来决定返回哪种类型。
我不熟悉Bitmap,但另一个例子是EnumSet。当你打电话:
EnumSet<SomeEnum> set = EnumSet.noneOf(SomeEnum.class);
静态工厂方法根据枚举中的项目数使用不同的实现,以便在所有情况下尽可能高效。
底层代码为小枚举返回RegularEnumSet
或为大枚举返回JumboEnumSet
。使用构造函数不可能进行这种上下文优化。
public static <E extends Enum<E>> EnumSet<E> noneOf(Class<E> elementType) {
Enum[] universe = getUniverse(elementType);
if (universe == null)
throw new ClassCastException(elementType + " not an enum");
if (universe.length <= 64)
return new RegularEnumSet<>(elementType, universe);
else
return new JumboEnumSet<>(elementType, universe);
}
答案 2 :(得分:1)
这是工厂方法模式。
这有两个主要原因:
它允许将来不一定每次都返回一个新实例。例如,Integer.valueOf(int)
将重新使用它已创建的相同Integer对象,如果值介于-127和128之间。这是代码中使用的最常见的Integer值,因此我们没有JVM制作数千份副本相同的实例(每个实例占用内存)并且只能重用相同的实例。
它允许静态方法在调用者不知道的情况下返回子类。如果将工厂方法与其他设计模式(如代理或适配器)组合以返回类的修改版本,这将非常有用。
答案 3 :(得分:0)
编辑:这个问题包括:
Factory, Abstract Factory and Factory Method
Design Patterns: Factory vs Factory method vs Abstract Factory
这是工厂模式。重点是从静态类创建类,因此您可以隐藏类的编程细节(安全措施)。
来源:
http://www.oodesign.com/factory-pattern.html
<强>意图:强>
创建对象而不将实例化逻辑暴露给 客户。通过公共接口
引用新创建的对象
示例:
public class ProductFactory{
public Product createProduct(String ProductID){
if (id==ID1)
return new OneProduct();
if (id==ID2) return
return new AnotherProduct();
... // so on for the other Ids
return null; //if the id doesn't have any of the expected values
}
...
}
另一个坚实的来源: