工厂模式的初衷就是为了简化实例化对象的过程,不需要每次都手写创建逻辑,任何需要生成复杂对象的地方,都可以使用工厂方法模式。
一、简单工厂模式
简单工厂模式不算是23种设计模式中的,思想比较简单,就是根据不同入参来决定到底实例化的是哪个类对象。如果使用的是public Shape getShape(String shapeType)
这个方法,明显不符合开闭原则,每次新增代码都要去修改原有代码,而public Shape getShape(Class clz)
这个方法一定程度上减少了修改代码的可能行。
下面是简单实现,根据传入参数的不同来实例化不同的对象。
public class ShapeFactory {
//根据传入的字符串来决定实例化的类对象
public Shape getShape(String shapeType) {
if ("".equals(shapeType) || null == shapeType)
return null;
switch (shapeType) {
case "CIRCLE":
return new Circle();
case "SQUARE":
return new Square();
case "RECTANGLE":
return new Rectangle();
default:
return null;
}
}
//根据传入的类来决定实例化的类对象
public Shape getShape(Class clz) {
if (clz == null)
return null;
try {
return (Shape) clz.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
return null;
} catch (IllegalAccessException e) {
e.printStackTrace();
return null;
}
}
}
public class ShapeFactoryTest {
public static void main(String[] args) {
ShapeFactory factory = new ShapeFactory();
Shape circle = factory.getShape("CIRCLE");
circle.draw();
Shape square = factory.getShape(Square.class);
square.draw();
}
}
可以看到成功创建了两个对象。
二、工厂模式
将调用的方法写在了接口中,不同的工厂类都实现了这个接口来实例化不同的类对象。所以工厂模式其实就是让其子类自己决定实例化哪一个类对象,工厂模式使对象的创建过程延迟到子类进行。符合开闭原则,如果要添加新的种类,只要新增对应的工厂类和产品类就可以了。
public interface InterfaceFactory {
Shape getShape();
}
创建圆形的工厂类:
public class CircleFactory implements InterfaceFactory {
@Override
public Shape getShape() {
return new Circle();
}
}
创建矩形的工厂类:
public class RectangleFactory implements InterfaceFactory {
@Override
public Shape getShape() {
return new Rectangle();
}
}
创建正方形的工厂类:
public class SquareFactory implements InterfaceFactory {
@Override
public Shape getShape() {
return new Square();
}
}
public class InterfaceFactoryTest {
public static void main(String[] args) {
InterfaceFactory circleFactory = new CircleFactory();
InterfaceFactory squareFactory = new SquareFactory();
Shape circle = circleFactory.getShape();
circle.draw();
Shape square = squareFactory.getShape();
square.draw();
}
}
成功创建了一个圆形和一个正方形。
三、抽象工厂模式
其实和工厂模式很像,只是多了维度,多了产品族这个维度。举个例子就是小米牌和华为牌,小米牌下面又可以细分很多产品,如:小米手机、小米耳机等等;华为牌也有对应的华为手机与华为耳机。华为手机和小米手机就是不同产品族下面同一产品等级的东西,而华为手机和华为耳机则是同一产品族下面不同产品等级的东西。
如果增加的是产品族,则符合开闭原则,只需要增加对应的工厂类和对应的产品类。如果增加的是产品等级,那裂开了,不符合开闭原则。
public interface AbstractFactory {
Shape getShape(String shapeType);
Color getColor(String colorType);
}
public class ColorFactory implements AbstractFactory {
@Override
public Shape getShape(String shapeType) {
return null;
}
@Override
public Color getColor(String colorType) {
if ("".equals(colorType) || null == colorType)
return null;
switch (colorType) {
case "RED":
return new Red();
case "BLUE":
return new Blue();
case "GREEN":
return new Green();
default:
return null;
}
}
}
public class ShapeFactory implements AbstractFactory {
@Override
public Shape getShape(String shapeType) {
if ("".equals(shapeType) || null == shapeType)
return null;
switch (shapeType) {
case "CIRCLE":
return new Circle();
case "SQUARE":
return new Square();
case "RECTANGLE":
return new Rectangle();
default:
return null;
}
}
@Override
public Color getColor(String colorType) {
return null;
}
}
传递不同的产品族的信息来决定到底使用那个工厂来生产。
public class FactoryProducer {
public static AbstractFactory getFactory(String choice) {
if (choice.equalsIgnoreCase("SHAPE"))
return new ShapeFactory();
else if (choice.equalsIgnoreCase("COLOR"))
return new ColorFactory();
return null;
}
}
public class AbstractFactoryTest {
public static void main(String[] args) {
AbstractFactory shapeFactory = FactoryProducer.getFactory("Shape");
AbstractFactory colorFactory = FactoryProducer.getFactory("Color");
Shape shape = shapeFactory.getShape("CIRCLE");
Color red = colorFactory.getColor("RED");
shape.draw();
red.fill();
}
}
成功生产了对象。