目录
简单工厂模式
简单工厂中主要存在以下角色
- 工厂(Factory):提供了静态工厂方法,它负责创建所有具体产品的实例。
- 抽象产品(Abstract Product):负责描述所有具体产品的公共产品,可以用抽象类或接口实现。
- 具体产品(Concrete Product):是工厂创建的目标产品。
下面使用一个“颜料”工厂的实例来实现一个简单工厂
抽象产品 - 颜料(color)
public interface Color {
void draw();
}
具体产品 - 黄色、绿色、红色颜料
public class Green implements Color{
@Override
public void draw() {
System.out.println("绿色颜料");
}
}
public class Red implements Color{
@Override
public void draw() {
System.out.println("红色颜料");
}
}
public class Yellow implements Color{
@Override
public void draw() {
System.out.println("黄色颜料");
}
}
工厂 - 颜料工厂 - 根据传入参数”生产“相关颜料
public class ColorFactory {
public static String RED = "red";
public static String GREEN = "green";
public static String YELLOW = "yellow";
public static Color getColor(String c){
if (RED.equalsIgnoreCase(c)){
return new Red();
}else if (GREEN.equalsIgnoreCase(c)){
return new Green();
}else if (YELLOW.equalsIgnoreCase(c)){
return new Yellow();
}else {
return null;
}
}
}
public class ColorFactoryTest {
@Test
public void test(){
Color color = ColorFactory.getColor(ColorFactory.GREEN);
color.draw();
}
}
========结果========
绿色颜料
如果对象可以复用,那么就不需要每次创建一个新对象,可以先将其缓存起来,每次请求从缓存中给他拿相应的对象。如下:
public class ColorCacheFactory {
public static String RED = "red";
public static String GREEN = "green";
public static String YELLOW = "yellow";
private static final Map cacheMap = new HashMap<>();
static {
cacheMap.put(RED,new Red());
cacheMap.put(GREEN,new Green());
cacheMap.put(YELLOW,new Yellow());
}
public static Color getColor(String s){
return cacheMap.get(s);
}
}
工厂方法模式
在简单工厂模式中每增加一个具体实例都要对相应工厂进行相应代码的,这就违反了SOLID中的开闭原则。所以就出现了工厂方法模式解决了这个问题。
工厂方法模式中有以下角色
- 抽象工厂(Abstract Factory)
- 具体工厂(Concrete Factory)
- 抽象产品(Abstract Product)
- 具体产品(Concrete Product)
相比简单工厂这里将工厂变成了抽象工厂 + 具体工厂
下面我们还使用颜料的例子,抽象产品和具体产品和上面一样所以我们在下面不重复贴代码了
抽象工厂
public interface ColorFactory {
String RED = "red";
String GREEN = "green";
String YELLOW = "yellow";
Color getColor();
}
具体工厂
public class GreenColorFactory implements ColorFactory{
@Override
public Color getColor() {
return new Green();
}
}
public class RedColorFactory implements ColorFactory{
@Override
public Color getColor() {
return new Red();
}
}
public class YellowColorFactory implements ColorFactory{
@Override
public Color getColor() {
return new Yellow();
}
}
使用方式
ColorFactory factory = new GreenColorFactory();
factory.getColor().draw();
这样看起来,除了解决了不符合开闭原则的问题,没有其它任何优势,反而由于产生了很多新的工厂类会增加一定代码量。但是如果换个角度看,如果创建一个Color的实例不仅仅是new Red()
这么简单的一行代码,而是一个比较复杂的过程,那么把这些代码都糅杂在一个简单工厂之中显然不是一个好的选择。
public static Color getColor(String c){
if (RED.equalsIgnoreCase(c)){
Red color = new Red();
...
return color;
}else if (GREEN.equalsIgnoreCase(c)){
Green color = new Green();
...
return color;
}else if (YELLOW.equalsIgnoreCase(c)){
Yellow color = new Yellow();
...
return color;
}else {
return null;
}
}
抽象工厂模式
抽象工厂模式是对一组队友多种相同主题的工厂进行封装,抽象工厂是工厂方法的升级版本,工厂方法模式只生产同一类的产品,而抽象工厂模式可生产多个类的产品。
我们继续在”颜料“这个主题上进行升级,颜料经常用于服饰上色,所以我们创建一个生产颜料和服饰的抽象工厂。
public interface Color {
void draw();
}
public class Green implements Color {
@Override
public void draw() {
System.out.println("绿色颜料");
}
}
public class Red implements Color {
@Override
public void draw() {
System.out.println("红色颜料");
}
}
public interface Apparel {
void crop();
}
public class Pants implements Apparel{
@Override
public void crop() {
System.out.println("裁剪裤子");
}
}
public class Shirts implements Apparel{
@Override
public void crop() {
System.out.println("裁剪衬衫");
}
}
public interface AbstractFactory {
Color getColor();
Apparel getApparel();
}
public class GreenPantsFactory implements AbstractFactory {
@Override
public Color getColor() {
return new Green();
}
@Override
public Apparel getApparel() {
return new Pants();
}
}
public class RedShirtsFactory implements AbstractFactory {
@Override
public Color getColor() {
return new Red();
}
@Override
public Apparel getApparel() {
return new Shirts();
}
}
public class MethodFactoryTest {
@Test
public void test(){
AbstractFactory factory = new GreenPantsFactory();
factory.getColor().draw();
factory.getApparel().crop();
}
}
=====结果=====
绿色颜料
裁剪裤子
抽象共产和工厂方法的区别
- 工厂方法模式只有一个抽象产品类,而抽象工厂模式有多个。
- 工厂方法模式的具体工厂类只能创建一个具体产品类的实例,而抽象工厂模式可以创建多个