工厂方法模式(Factory Pattern)属于创建型模式,它提供了一种创建对象的最佳方式,在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。
场景
明确地计划不同条件下创建不同实例
实现
创建一个接口。
Shape.java
public interface Shape {
void draw();
}
创建实现接口的实体类。
Rectangle.java
public class Rectangle implements Shape {
@Override
public void draw() {
System.out.println("Inside Rectangle::draw() method.");
}
}
Square.java
public class Square implements Shape {
@Override
public void draw() {
System.out.println("Inside Square::draw() method.");
}
}
Circle.java
public class Circle implements Shape {
@Override
public void draw() {
System.out.println("Inside Circle::draw() method.");
}
}
抽象工厂类
Factory.Java
public interface Factory {
void getShape(String shapeType);
}
创建一个工厂,生成基于给定信息的实体类的对象。
ShapeFactory.java
public class ShapeFactory implements Factory {
@Override
public Shape getShape(String shapeType){
if(shapeType == null){
return null;
}
if(shapeType.equalsIgnoreCase("CIRCLE")){
return new Circle();
} else if(shapeType.equalsIgnoreCase("RECTANGLE")){
return new Rectangle();
} else if(shapeType.equalsIgnoreCase("SQUARE")){
return new Square();
}
return null;
}
}
此处的工厂实现会带来一个问题:如果我们去增加Shape,那就需要在工厂类中在添加一个If else或者Case分支条件,这违背了开放封闭原则,我们对修改也开放了,所以工厂实现还有另外一种实现方式
扩展:工厂实现的另外一种方式(反射)
public class ShapeFactory {
public <T extends Shape> T getShape(Class<T> shapeClass) {
Shape shape = null;
String shapeName = shapeClass.getName();
try {
shape = (Shape) Class.forName(shapeName).newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return (T) shape;
}
}
使用这种工厂的实现方式,当需要增加Shape时,并不需要修改工厂类,直接创建Shape即可。
扩展:工厂扩展为多个工厂
为每一个Shape,创建一个单独的工厂,各司其职,比如
public class SquareFactory implements Factory{
@Override
public Shape getShape(String shapeType){
return new Square();
}
}
优点
- 良好的封装性,代码结构清晰
- 扩展性高,如果想增加一个产品,只要扩展或者修改一个工厂类就可以
- 屏蔽产品的具体实现,调用者只关心产品的接口
缺点
- 每次增加一个产品时,都需要增加一个具体类和对象,使得系统中类的个数成倍增加
Android 中的应用
Java中的类集合框架
List和Set继承自Collection接口,Collection接口继承于Iterable接口
public interface Iterable<T> {
Iterator<T> iterator();
}
List 的间接实现类ArrayList中:
public Iterator<E> iterator() {
return new Itr();
}
分析:
Iterator -> Shape(产品抽象)
Itr -> 具体的Shape(具体产品实现)
List/Collection/Iterable -> Factory(工厂抽象)
ArrayList -> SquareFactory (具体的工厂实现)
参考
书籍:《设计模式之禅》、《Android源码设计模式》
技术文章:菜鸟教程-设计模式