面试题答案
一键面试优势
- 提高灵活性:
- 单独的工厂模式在创建对象时,通常是基于已知的类名进行硬编码创建。而结合反射机制,工厂可以根据配置文件、运行时参数等动态获取类名,并通过反射创建对象。这使得系统在不修改代码的情况下,能够轻松切换创建的具体对象类型。例如,在一个电商系统中,支付方式可能有多种,如支付宝、微信支付等。如果使用单独的工厂模式,每种支付方式的创建代码可能是固定的。但结合反射机制,可根据用户的配置或系统环境,动态选择创建具体的支付方式对象,大大提高了系统的灵活性。
- 增强可维护性:
- 当有新的对象类型需要添加到系统中时,在单独的工厂模式下,可能需要修改工厂类的代码来添加新的创建逻辑。而反射与工厂模式结合,只需要在配置文件中添加新的类名等信息,工厂类通过反射动态创建对象,无需修改工厂类的核心代码。比如在一个游戏开发项目中,新增加一种怪物类型,结合反射的工厂模式,开发人员只需要配置新怪物的类名等信息,工厂就能创建出新的怪物对象,降低了维护成本。
- 实现解耦:
- 反射机制与工厂模式结合,使得对象的创建和使用进一步解耦。使用者不需要知道具体的对象创建细节,只需要向工厂请求对象。同时,由于反射可以根据配置等动态创建对象,对象的具体实现类可以在不影响使用者的情况下进行替换或修改。例如在一个大型企业级应用中,数据访问层可能有多种实现(如基于 JDBC、Hibernate 等),通过结合反射的工厂模式,业务层只需要从工厂获取数据访问对象,而无需关心具体是如何创建的,也不用担心数据访问层实现的变化。
实际项目场景举例
假设我们正在开发一个插件化的图形绘制系统。系统支持多种图形的绘制,如圆形、矩形等。每种图形都有自己的绘制逻辑(在各自的类中实现)。
- 定义图形接口:
public interface Shape {
void draw();
}
- 具体图形类:
public class Circle implements Shape {
@Override
public void draw() {
System.out.println("Drawing a circle.");
}
}
public class Rectangle implements Shape {
@Override
public void draw() {
System.out.println("Drawing a rectangle.");
}
}
- 结合反射的工厂类:
import java.util.HashMap;
import java.util.Map;
public class ShapeFactory {
private static final Map<String, Class<? extends Shape>> shapeMap = new HashMap<>();
static {
shapeMap.put("circle", Circle.class);
shapeMap.put("rectangle", Rectangle.class);
}
public static Shape createShape(String shapeType) {
Class<? extends Shape> shapeClass = shapeMap.get(shapeType);
if (shapeClass == null) {
throw new IllegalArgumentException("Invalid shape type: " + shapeType);
}
try {
return shapeClass.newInstance();
} catch (InstantiationException | IllegalAccessException e) {
throw new RuntimeException("Failed to create shape", e);
}
}
}
- 使用示例:
public class Main {
public static void main(String[] args) {
Shape circle = ShapeFactory.createShape("circle");
circle.draw();
Shape rectangle = ShapeFactory.createShape("rectangle");
rectangle.draw();
}
}
在这个例子中,如果未来要添加新的图形类型(如三角形),只需要创建三角形的实现类,并在 shapeMap
中添加对应的映射关系,而无需修改 createShape
方法的核心逻辑。这充分体现了结合反射机制的工厂模式在灵活性、可维护性和解耦方面的优势。