工厂模式(Factory Pattern)属于创建型模式,用于解决接口选择的问题(在不同条件下创建不同实例),提供了一种创建对象的最佳方式。
优势
1、工厂类根据调用者的选择条件动态实例化相关对象,去除了调用者与具体实现的耦合
2、 隐藏对象具体创建细节,调用者只针对接口编程,便于扩展
不足
1、如果需要添加新的实现,需要修改工厂类,违反了开-闭原则
2、简单对象的创建使用工厂模式会增加系统复杂度
实现
1、假定有绘画接口(Brush.java)及其若干个具体实现
Brush.java
public interface Brush {
/** 绘画方法 */
void draw();
}
Circle.java
public class Circle implements Brush {
@Override
public void draw() {
System.out.println("Circle");
}
}
Rectangle.java
public class Rectangle implements Brush {
@Override
public void draw() {
System.out.println("Rectangle");
}
}
Triangle.java
public class Triangle implements Brush {
@Override
public void draw() {
System.out.println("Triangle");
}
}
2、 创建一个工厂,生成基于给定信息的实体类的对象。
工厂类是整个模式的关键,包含了必要的逻辑判断,根据外界给定的信息来决定应该创建哪个具体的对象。
BrushFactory.java
public class BrushFactory {
public Brush createBrush( String name){
Brush brush = null;
switch ( name){
case "Circle":
brush = new Circle();
break;
case "Rectangle":
brush = new Rectangle();
break;
case "Triangle":
brush = new Triangle();
break;
}
return brush;
}
}
3、 使用该工厂,通过传递类型信息来获取实体类的对象。
调用者无需关心对象是如何创建及如何组织的,只需要告诉工厂需要的是什么对象即可。
Demo.java
public class Demo {
public static void main( String[] args){
BrushFactory factory = new BrushFactory();
Brush brush;
brush = factory.createBrush( "Circle");
brush.draw();
brush = factory.createBrush( "Rectangle");
brush.draw();
brush = factory.createBrush( "Triangle");
brush.draw();
}
}
优化
1、利用反射,消除工厂类中的switch判断,达到需要添加Brush接口新的实现时无需再修改工厂类的效果
BrushReflectFactory.java
public class BrushReflectFactory {
public Brush createBrush( String name) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
// 利用反射,根据参数获得具体实例
return ( Brush)Class.forName( name).newInstance();
}
}
使用新的工厂
Demo.java
public class Demo {
public static void main( String[] args) throws Exception {
BrushReflectFactory reflectFactory = new BrushReflectFactory();
Brush brush;
// 这里传入实现类的完整名称(包名 + 类名)
brush = reflectFactory.createBrush( "org.pattern.factory.Circle");
brush.draw();
brush = reflectFactory.createBrush( "org.pattern.factory.Rectangle");
brush.draw();
brush = reflectFactory.createBrush( "org.pattern.factory.Triangle");
brush.draw();
}
}
2、使用工厂方法模式,以满足开-闭原则对扩展开发、对修改关闭的要求,使得增加新实现时无需修改原有代码
关键点: 抽象工厂类,新增与具体实例相关联的子工厂
实现
抽象原有工厂类
BrushMethodFactory.java
public interface BrushMethodFactory {
Brush createBrush( );
}
定义与具体实现对应的工厂,并实现BrushMethodFactory,返回具体实现实例
CircleFactory.java
public class CircleFactory implements BrushMethodFactory {
// 注意这里返回对应具体实现的实例
@Override
public Brush createBrush() {
return new Cricle();
}
}
RectangleFactory.java
public class RectangleFactory implements BrushMethodFactory {
@Override
public Brush createBrush() {
return new Rectangle();
}
}
此时使用该工厂时直接调用对应工厂即可,需要添加实现时直接添加对应的工厂,而无需修改原有代码
Demo.java
public class Demo {
public static void main( String[] args) throws IllegalAccessException, InstantiationException, ClassNotFoundException {
// 依然由调用者决定生成什么对象,不同的是这里直接调用与具体对象相对应的工厂,而不是传入标识字符串
BrushMethodFactory methodFactory = new CircleFactory();
Brush brush = methodFactory.createBrush();
brush.draw();
}
}