0 序言
工厂模式的目的是解耦创建对象和使用对象这两个操作。
工厂模式可以分为简单工厂、工厂方法和抽象工厂。
1 简单工厂
简单工厂使用if-else
分支直接返回对象。违反开闭原则。
public class Color {}
public class Red extends Color {}
public class Orange extends Color {}
public class SimpleFactory {
public static final Map<String, Color> cachedColor = new HashMap<>();
static {
cachedColor.put("red", new Red());
cachedColor.put("orange", new Orange());
}
public static Color createHuman(String type) {
if (type == null || type.isEmpty()) {
return null;
}
return cachedColor.get(type.toLowerCase());
}
}
2 工厂方法
public interface IFactory {
Human createColor();
}
public class RedFactory implements IFactory {
public Color createColor() {
return new Red();
}
}
public class OrangeFactory implements IFactory {
public Color createColor() {
return new Orange();
}
}
public class FactoryMap {
public static final Map<String, IFactory> cachedFactory = new HashMap<>();
static {
cachedFactory.put("red", new RedFactory());
cachedFactory.put("orange", new OrangeFactory());
}
public static Color getColorFactory(String type) {
if (type == null || type.isEmpty()) {
return null;
}
return cachedFactory.get(type.toLowerCase());
}
}
// 使用时
factoryMap.getHumanFactory("red");
从上述代码看出,工厂方法比简单工厂更复杂。如果创建对象很简单,比如Factory
类的createHuman
方法只有1行,那么更适合简单工厂。如果创建对象很复杂
,createHuman
方法依赖多个参数,方法达到几十行,那么适合工厂方法。
此外,工厂方法更不违反开闭原则。但是会造成类爆炸。如果新增一个类Green extends Color
,那么要同时新增一个类GreenFactory implements IFactory
,并且修改FactoryMap
类的cachedFactory
变量。
3 抽象工厂
上面的例子Color
类只有1种分类方法。而遇到多分类,并且一组对象有相同约束时,为了减少工厂类数量,可以使用抽象工厂。
public interface IFactory {
WindowsProduct generateWindowsProduct();
LinuxProduct generateLinuxProduct();
}
public class TextFactory extends IFactory {
public WindowsProduct generateWindowsProduct() {
return new WindowsTextProgram();
}
public LinuxProduct generateLinuxProduct() {
return new LinuxTextProgram();
};
}
public class PictureFactory extends IFactory {
public WindowsProduct generateWindowsProduct() {
return new WindowsPictureProgram();
}
public LinuxProduct generateLinuxProduct() {
return new LinuxPictureProgram();
};
}
有4个类,WindowsTextProgram, WindowsPictureProgram, LinuxTextProgram, LinuxPictureProgram
。将它们按照操作系统windows
和linux
分类,每个工厂要同时实现generateWindowsProduct
方法和generateLinuxProduct
方法。
符合开闭原则。如果新增VideoProgram
类,可以新增工厂类VideoFactory extends IFactory
。