您的位置:首页 > 编程语言 > Java开发

Java:设计模式之工厂方法(Factory Method)

2013-01-13 21:40 766 查看
模式名

工厂方法(Factory Method)
定义
工厂通常是一个用来创建其他对象的对象。工厂是构造方法抽象,用来实现不用的分配方案。定义一个接口用于创建对象,但是让子类决定初始化哪个类。工厂方法把一个类的初始化下放到子类。

工厂对象通常包含一个或多个方法,用来创建这个工厂所能创建的各种类型的对象。这些方法可能接收参数,用来指定对象创建的方式,最后返回创建的对象。

有时,特定类型对象的控制过程比简单地创建一个对象更复杂。在这种情况下,工厂对象就派上用场了。工厂对象可能会动态地创建产品对象的类,或者从对象池中返回一个对象,或者对所创建的对象进行复杂的配置,或者应用其他的操作。

实例
如要生产大中小三种球体,可以采用工厂方法生产,不需要关注球体本身的具体实现。代替各种球体的new对象方法。允许子类选择创建对象的具体类型.
适用场景
创建对象需要大量重复的代码,通过工厂方法可以避免大量修改代码来实现重构。
子类能明确何种对象需要创建。
父类可以代理子类的创建过程。
一个类不知道何时需要创建其子类(lazy-initialization);
创建对象的生命周期必须集中管理,以保证在整个程序中具有一致的行为。
工厂方法模式常见于工具包和框架中,在这些库中可能需要创建客户端代码实现的具体类型的对象。
结构层次


优点
代码灵活、松耦合,可重用。将对象的创建推迟到其子类和工厂中。便于集中管理一系列对象的创建。
客户端代码只需要关注产品接口,因此可以增加具体产品类而不用修改客户端代码。
可以多次返回同一个实例,或者返回一个子类而不需要指定具体类型(多态)。
使用工厂可以强制客户端使用统一的创建对象方式,避免不同的客户端使用不同的构造函数。
局限性

第一个局限是,重构已经存在的类会破坏客户端代码。
第二个局限是,因为工厂方法所实例化的类具有私有的构造方法,所以这些类就不能扩展了。因为任何子类都必须调用父类的构造方法,但父类的私有构造方法是不能被子类调用的。
第三个局限是,如果确实扩展了工厂方法所实例化的类(例如将构造方法设为保护的,虽然有风险但也是可行的),子类必须具有所有工厂方法的一套实现。
讲述由工厂方法生产各种尺寸的球体的例子:

一、Ball的实现

package com.freestudio.designpattern;

abstract class Ball
{
public final static int BIG_BALL = 1;
public final static int MEDIUM_BALL = 2;
public final static int SMALL_BALL = 3;

protected void playBall()
{
System.out.println("playBall:" + this.getClass().getSimpleName());
}
}

class BigBall extends Ball
{
private BigBall()
{
// 禁止直接构造对象
}

public static Ball getInstance()
{
return new BigBall();
}

protected void playBall()
{
System.out.println("playBall:" + this.getClass().getSimpleName());
}
}

class MediumBall extends Ball
{
private MediumBall()
{
// 禁止直接构造对象
}

public static Ball getInstance()
{
return new MediumBall();
}

protected void playBall()
{
System.out.println("playBall:" + this.getClass().getSimpleName());
}
}

class SmallBall extends Ball
{
private SmallBall()
{
// 禁止直接构造对象
}

public static Ball getInstance()
{
return new SmallBall();
}

protected void playBall()
{
System.out.println("playBall:" + this.getClass().getSimpleName());
}
}


二、工厂方法的实现

package com.freestudio.designpattern;

public class BallFactory
{
public static Ball creator(int type)
{
switch (type)
{
case Ball.BIG_BALL:
return BigBall.getInstance();
case Ball.MEDIUM_BALL:
return MediumBall.getInstance();
case Ball.SMALL_BALL:
return SmallBall.getInstance();
}
return null;
}

}


三、测试代码

package com.freestudio.designpattern;

public class Main
{
public static void main(String[] args)
{
// TODO Auto-generated method stub
TestFactory();
}

static void TestFactory()
{
Ball bigBall = BallFactory.creator(Ball.BIG_BALL);
bigBall.playBall();
Ball mediumBall = BallFactory.creator(Ball.MEDIUM_BALL);
mediumBall.playBall();
Ball smallBall = BallFactory.creator(Ball.SMALL_BALL);
smallBall.playBall();
}
}


输出:

playBall:BigBall
playBall:MediumBall
playBall:SmallBall


参考:

工厂方法模式
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: