工厂模式 java实例_Java设计模式百例 - 工厂方法模式

工厂方法模式同简单工厂模式一样,也是创建类模式,又叫做虚拟构造(Virtual Constructor)模式或多态工厂(Polymorphic Factory)模式。其用意是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类中。

上篇说到,简单工厂模式并未做到完全的“开闭原则”。回顾一下,“开”即对扩展开放,这点是没错的,简单工厂模式的初衷之一就是方便增加“产品类型”的时候;“闭”即对修改关闭,这点其实并未做到,当需要增删改“产品类型”的时候,工厂类必须要修改,因为工厂类“知道”如何创建所有的产品类型的对象。

那么工厂方法模式就是为了完全满足“开闭原则”,即在简单工厂模式的基础上,做到当增加产品类型的时候,无需改动现有的代码。继续用上篇的例子:

例子

仍然是做一个画图软件,可以画矩形、三角形和圆形等,每一种图形都用一个类来管理:

* Rectangle

* Circle

* Triangle

每个类都有各自的draw()方法,共同实现Shape接口。

Shape.javapublic interface Shape {

void draw();

}

Rectangle.javapublic class Rectangle implements Shape {

@Override

public void draw() {

System.out.println("Draw a rectangle.");

}

}

Triangle.javapublic class Triangle implements Shape {

@Override

public void draw() {

System.out.println("Draw a triangle.");

}

}

Circle.javapublic class Circle implements Shape {

@Override

public void draw() {

System.out.println("Draw a circle.");

}

}

以上几个类都没有变化,有变化的是工厂类,工厂类也采用基于接口的设计,由不同的具体工厂类负责相应对象的创建:

ShapeFactory.javapublic interface ShapeFactory {

Shape getShape();

}

RectangleFactory.javapublic class RectangleFactory implements ShapeFactory {

public Shape getShape() {

return new Rectangle();

}

}

CircleFactory.javapublic class CircleFactory implements ShapeFactory{

public Shape getShape() {

return new Circle();

}

}

Triangle.Factory.javapublic class CircleFactory implements ShapeFactory{

public Shape getShape() {

return new Circle();

}

}

那么在需要某个形状的时候,就通过相应的具体工厂类创建即可:

Client.javapublic class Client {

public static void main(String[] args) {

ShapeFactory factory = new CircleFactory();

Shape c = factory.getShape();

c.draw();

}

}

再来看一下类图:

6164e2344a2afe9854731ec63d835019.png

与简单工厂模式对比以下:

a0fcf1906861eb10b32e02d4d81396d4.png

区别就在于简单工厂模式下的一个具体的工厂类转换成了基于接口ShapeFactory的三个具体工厂类。

好处也是明显的:当增加一个新的形状类型的时候,不需要对现有代码做任何更改,增加一个相应的实现了ShapeFactory的具体工厂类即可。可见,工厂方法模式能够完全做到“开闭原则”。

这个例子仍然是不恰当的,因为无论如何这一套模式设计比原始的实现方式有更加复杂了。所以再次赘述一遍注意事项,以上例子是为了说明工厂方法模式,但并不是一个合理的应用。复杂对象适合使用工厂模式,而简单对象,特别是只需要通过 new 就可以完成创建的对象,无需使用工厂模式。如果使用工厂模式,就需要引入一个工厂类,会增加系统的复杂度。

Java中的应用

下边看一下合理的应用场景是如何的,在Java中的实际应用的例子(来自《Java与模式》):

* 1. Java聚集中的应用 *

Java聚集是一套设计精良的数据结构实现,主要的Java聚集都实现自java.util.Collection接口,这个接口的父接口Iterable规定所有的Java聚集都必须提供一个iterator()方法,返还一个Iterator类型的对象:

java.lang.Iterable.javapublic interface Iterable {

... ...

Iterator iterator();

... ...

}

ArrayLis是我们常用的一个Collection实现类,其iterator()方法实现如下:

java.util.ArrayList.javapublic class ArrayList extends AbstractList

implements List, RandomAccess, Cloneable, java.io.Serializable {

... ...

// 实现iterato接口,返回一个Iterator对象

public Iterator iterator() {

return new Itr();

}

private class Itr implements Iterator {

... ...

}

... ...

}

可见,ArrayList类的iterator()方法就是一个具体工厂类的工厂方法,而Collection就是一个抽象工厂。除了ArrayList还有LinkedList等等具体实现类。

总结

从上边的例子可以看到,工厂方法模式其实是将“面向接口”编程的思路应用在了工厂类上,这样有几个方便的地方:做到了完全的“开闭原则”,因为增加新的“产品”和相应的“工厂”均不需修改现有代码;

工厂设计模式通常应用在复杂的对象创建场景中,因此面临多层的继承关系,比如ArrayList实现了List接口,而后者继承自Collect接口,Collect又继承自Iterator接口。有时候具体工厂方法与具体产品是有层次对应关系的,比如:

677b8b0a2e01f96c7cab7d49c47c92da.png

这种情况也是只有一个工厂类的简单工厂模式所无法满足的。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值