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


模式名

工厂方法(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

参考:

工厂方法模式


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值