工厂模式有以下几种形态:
· 简单工厂模式(Simple Factory):又称为静态工厂方法模式;
· 工厂方法模式(Factory Method):又称为多态性工厂(Polymorphic Factory)或虚拟构造子模式(VirtualConstructor);
· 抽象工厂模式(Abstract Factory):有称为工具箱模式(Kit或Toolkit);
简单工厂的目的:定义一个用于创建对象的接口。
类图如下:
先来看看它的组成:
1) 工厂类角色(Creator):这是本模式的核心,含有一定的商业逻辑和判断逻辑。在java中它往往由一个具体类实现。
2) 抽象产品角色(ConcreteProduct):它一般是具体产品继承的父类或者实现的接口。在java中由接口或者抽象类来实现。
3) 具体产品角色(Product):工厂类所创建的对象就是此角色的实例。在java中由一个具体类实现。
例子:
话说十年前,有一个暴发户,他家有三辆汽车——Benz奔驰、Bmw宝马、Audi奥迪,还雇了司机为他开车。不过,暴发户坐车时总是怪怪的:上Benz车后跟司机说“开奔驰车!”,坐上Bmw 后他说“开宝马车!”,坐上Audi 说“开奥迪车!”。你一定说:这人有病!直接说开车不就行了?!
那么简单工厂模式怎么来使用呢?我们就以简单工厂模式来改造暴发户坐车的方式
——现在暴发户只需要坐在车里对司机说句:“开车”就可以了。
//抽象产品角色
public interface Car{
public void drive();
}
//具体产品角色
public class Benz implements Car{
public void drive() {
System.out.println("DrivingBenz ");
}
}
public class Bmw implements Car{
public void drive() {
System.out.println("DrivingBmw ");
}
}
。。。(奥迪我就不写了:P)
//工厂类角色
public class Driver{
//工厂方法.注意返回类型为抽象产品角色
public static Car driverCar(Strings)throws Exception {
//判断逻辑,返回具体的产品角色给Client
if(s.equalsIgnoreCase("Benz"))
return newBenz();
elseif(s.equalsIgnoreCase("Bmw"))
return new Bmw();
......
else throw newException();
}
}
//欢迎暴发户出场......
public class Magnate{
public static void main(String[]args){
try{
//告诉司机我今天坐奔驰
Car car =Driver.driverCar("benz");
//下命令:开车
car.drive();
}
}
优点:
1. 解耦
模式的核心是工厂类,这个类含有必要的判断逻辑,可以决定在什么时候创建哪一个产品类的实例。而客户端则可以免除直接创建产品对象的责任,而仅仅负责“消费”产品。简单工厂模式实现了对责任的分割。
缺点:
建议在如下情况中,选用简单工厂:
1. 如果想要完全封装隔离具体实现,让外部只能通过接口来操作封装体,那么可以选用简单工厂,让客户端通过工厂来获取相应的接口,而无需关心具体实现
2. 如果想要把对外创建对象的职责集中管理和控制,可以选用简单工厂,一个简单工厂可以创建很多的、不相关的对象,可以把对外创建对象的职责集中到一个简单工厂来,从而实现集中管理和控制
问题和简答
1. 工厂模式就是在不使用new操作符的情况下,将类实例化的吗?为什么在具体实现是仍然使用了new操作符呢?
答:对于整个系统而言,工厂模式吧具体使用了new操作符的细节包装和隐藏起来。当然只要程序是java语言写的,Java语言的特征就在细节里一定会出现。
2. 练习题:
请使用简单工厂模式设计一个创建不同形状,如圆形/方形和三角形实例的描图员(ArtTracer)系统。每个几何图形都有draw()和erase()方法。当描图员接到指令,要求创建不支持的集合图形时,要提出BadShapeException异常。