工厂模式在《java设计模式》中分为三种:
1.简单工厂模式:不利于生成系列产品。
2.工厂方法模式:又称为多形性工厂。
3.抽象工厂模式:又称为工具箱,产生产品族,但不利于生产新的产品。
一.简单工厂模式
从名字来看就很简单,存在的目的就是定义一个用于创建对象的接口。
来看一个简单的例子:
产品类-BWM.java
abstract class BMW{
public BMW(){};
}
产品类-BMW320.java
public class BMW320 extends BMW{
public BMW320{
System.out.println("create BMW320");
}
}
产品类-BMW523.java
public class BMW523 extends BMW{
public BMW523{
System.out.println("create BMW523");
}
}
工厂类-BMWFactory.java
public class BMWFactory{
public static BMW createBMW(int type){
switch(type){
case 320:
return new BMW320();
break;
case 523:
return new BMW523();
break;
defualt:
return null;
}
}
}
要使用的话就用BWMFactory.createBMW(type)来创建对象就可以了,这个就是简单工厂模式了。
客户要什么车就创建什么对象了。
public class Customer {
public static void main(String[] args) {
BMW bmw320 = BMWFactory.createBMW(320);
BMW bmw523 = BMWFactory.createBMW(523);
}
}
我们从开闭原则(对扩展开放,对修改关闭)来简单分析下简单工厂模式。当客户满足现有的型号320或者523的时候,只要通知下现有的工厂创建相应的对象就好了,从这个角度上来说是满足开闭原则的。
但是当客户不满足于现有的车型时,每新加一种车型,我们都需要在工厂类BMWFactory中createBMW方法中重新添加新的的逻辑即新的case,才能满足我们的需要。这对于工厂类BMWFactory明显是比较被动的。对于这样的工厂类我们称之为全能类或者上帝类。
我们对上述代码稍微改造下,来了解下什么是工厂方法模式。
二,工厂方法模式
产品类-BWM.java
abstract class BMW{
public BMW(){};
}
产品类-BMW320.java
public class BMW320 extends BMW{
public BMW320{
System.out.println("create BMW320");
}
}
产品类-BMW523.java
public class BMW523 extends BMW{
public BMW523{
System.out.println("create BMW523");
}
}
工厂类-BWMFactory.java
interface BWMFactory{
BMW createBWM;
}
工厂类-BMW320Factory .java
public class BMW320Factory implements BWMFactory{
@Overide
public BMW320 createBMW(){
return new BMW320()
}
}
工厂类-BMW523Factory .java
public class BMW523Factory implements BWMFactory{
@Overide
public BMW523createBMW(){
return new BMW523()
}
}
public class Customer {
public static void main(String[] args) {
BMW320Factory bmw320Factory = new BMW320Factory();
BMW320 bmw320 = bmw320Factory.createBWM();
BMW523Factory bmw523Factory = new BMW523Factory();
BMW523 bmw523 = bmw523Factory.createBWM();
}
}
这就是工厂方法模式,这似乎很完美的对对象创建进行了封装,但是当新产品大量出现的时候,会大量出现与之对应的工厂类,这不是我们所愿意看到的 。
三,抽象工厂模式
抽象工厂模式是工厂方法模式的设计版本,它用来创建一组相关或者相互依赖的对象。随着客户的需求越来越高,宝马车需要不同配置的空调和发动机等配件。于是这个工厂开始生产空调和发动机,用来组装汽车。这时候工厂有两个系列的产品:空调和发动机。
我们需要做到如果宝马320系列使用空调型号A和发动机型号A,而宝马523系列使用空调型号B和发动机型号B,那么使用抽象工厂模式,在为320系列生产相关配件时,就无需制定配件的型号,它会自动根据车型生产对应的配件型号A。
发动机类-Engine.java
public interface Engine{
}
A发动机类-EngineA.java
public class EngineA extends Engine{
public EngineA(){
System.out.printn("created EngineA");
}
}
B发动机类-EngineB.java
public class EngineB extends Engine{
public EngineB(){
System.out.printn("created EngineB");
}
}
空调类-Aircorn.java
public interface Aircorn{
}
A空调类-AircornA.java
public class AircornA extends Aircorn{
public AircornA(){
System.out.printn("created AircornA");
}
}
B空调类-AircornB.java
public class AircornB extends Aircorn{
public AircornB(){
System.out.printn("created AircornB");
}
}
抽象工厂类-AbstarctFactory.java
public interface AbstarctFactory{
public Engine createEngine();
public Aircorn createAircorn();
}
320工厂类-BWM320Factory.java
public class BWM320Factory implements AbstractFactory{
@Override
public Engine createEngine(){
return new EngineA();
}
@Override
public Engine createAircorn(){
return new AircornA();
}
}
523工厂类-BWM523Factory .java
public class BWM523Factory implements AbstractFactory{
@Override
public Engine createEngine(){
return new EngineB();
}
@Override
public Engine createAircorn(){
return new AircornB();
}
}
客户类-Customer.java
public class Customer {
public static void main(String[] args) {
BMW320Factory bmw320Factory = new BMW320Factory();
bmw320Factory.createEngine();
bmw320Factory.createAircorn();
BMW523Factory bmw523Factory = new BMW523Factory();
bmw523Factory.createEngine();
bmw523Factory.createAircorn();
}
}
无论是简单工厂模式,工厂方法模式,还是抽象工厂模式,他们都属于工厂模式,在形式和特点上也是极为相似的,他们的最终目的都是为了解耦。在使用时,我们不必去在意这个模式到底工厂方法模式还是抽象工厂模式,因为他们之间的演变常常是令人琢磨不透的。经常你会发现,明明使用的工厂方法模式,当新需求来临,稍加修改,加入了一个新方法后,由于类中的产品构成了不同等级结构中的产品族,它就变成抽象工厂模式了;而对于抽象工厂模式,当减少一个方法使的提供的产品不再构成产品族之后,它就演变成了工厂方法模式。
所以,在使用工厂模式时,只需要关心降低耦合度的目的是否达到了。