工厂模式
工厂模式是创建对象的一种最佳实现形式。在工厂模式中我们创建对象不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。
一、何时使用
我们明确的计划不同的情况下创建不同的实例。
二、实现举例
创建一个Shape接口和实现Shape接口的实体类,最后创建一个工厂类
步骤一:创建一个接口
- Shape.java
// 形状类接口
public interface Shape {
void draw();
}
步骤二:创建实现接口的实体类
- Square.java
// 正方形
public class Square implements Shape{
public void draw() {
System.out.println("调用了Square.draw()方法");
}
}
- Rectangle.java
// 长方形
public class Rectangle implements Shape{
public void draw() {
System.out.println("调用了Rectangle.draw()方法");
}
}
- Circle.java
// 圆
public class Circle implements Shape{
public void draw() {
System.out.println("调用了Circle.draw()方法");
}
}
步骤三:创建一个工厂生成基于给定信息的实体对象
ShapeFactory.java
// 形状工厂
public class ShapeFactory {
public Shape getShare(String shapeType){
if(shapeType == null){
return null;
}
if(shapeType.equalsIgnoreCase("CIRCLE")){
return new Circle();
}else if(shapeType.equalsIgnoreCase("SQUARE")){
return new Square();
} else if (shapeType.equalsIgnoreCase("RECTANGLE")){
return new Rectangle();
}
return null;
}
}
步骤四:使用工厂模式,通过传递类型信息来获取实体类对象
@org.junit.Test
public void TestFactoryPattern(){
ShapeFactory shapeFactory = new ShapeFactory();
//获取 Square 的对象,并调用它的 draw 方法
Shape square = shapeFactory.getShare("SQUARE");
square.draw();
//获取 Rectangle 的对象,并调用它的 draw 方法
Shape rectangle = shapeFactory.getShare("RECTANGLE");
rectangle.draw();
//获取 Circle 的对象,并调用它的 draw 方法
Shape circle = shapeFactory.getShare("CIRCLE");
circle.draw();
}
步骤五:运行结果
调用了Square.draw()方法
调用了Rectangle.draw()方法
调用了Circle.draw()方法
三、优点
- 一个调用者想要创建一个对象,只需要知道其名称即可
- 扩展性好,如果想要增加一个对象,只需扩展一个工厂类即可。
- 保密性好。屏蔽了一个对象的具体实现过程。调用者只需要关心对象接口即可。
四、缺点
每增加一个产品时,都需要增加一个具体类和扩展工厂类,使得系统的类成倍的增加,增加了系统的复杂度,同时也增加了具体类之间的依赖。
五、使用场景
- 日志记录器:记录可能记录到本地硬盘、系统事件、远程服务器等,用户可以选择记录日志到什么地方。
- 数据库访问:当不知道使用何种数据库时,已经数据库肯能有变化时。
- 设计连接一个服务器的框架,需要三个协议,"POP3","IMAP","HTTP",可以把这三个作为产品类,共同实现一个接口。
六、注意事项
作为创建类模式,在任何需要生成复杂类对象的地方,都可以使用工厂模式,而简单对象,特别是只需要通过new就可以创建的对象,无需使用工厂模式,如果使用工厂模式,需引入一个工厂类,无疑增加了系统的复杂度。