工厂设计模式

工厂模式:主要用来实例化有共同接口的类,工厂模式可以动态决定应该实例化那一个类。

工厂模式的几种形态:

1、简单工厂(Simple Factory)

2、工厂方法(Factory method)

3、抽象工厂(Abstract Factory)


简单工厂(Simple Factory)

简单工厂又称为静态工厂,主要有一个静态方法,用来接受参数,并根据参数来决定返回实现同一接口的不同类的实例。

情景:一家工厂生产洗衣机、空调、冰箱三种产品。


首先为所有的产品定义一个共同的产品接口:

public interface Product {}

<span style="font-family:KaiTi_GB2312;font-size:14px;">让所有产品都实现该接口:</span>

/**
 * 洗衣机
 */
public class Washer implements Product{

	public Washer() {
		System.out.println("洗衣机被制造了");
	}
}

/**
 * 冰箱
 */
public class Icebox implements Product{

	public Icebox() {
		System.out.println("冰箱被制造了");
	}
}

/**
 * 空调
 */
public class AirCondition implements Product{

	public AirCondition() {
		System.out.println("空调被制造了");
	}
}


接下来定义一个工厂类负责生产这些产品:

public class SimpleFactory {
	
	public static Product create(String productName) throws Exception{
		
		Product product = null;
		if("washer".equals(productName)){
			product = new Washer();
		}else if("airCondition".equals(productName)){
			product = new AirCondition();
		}else if("icebox".equals(productName)){
			product = new Icebox();
		}else{
			throw new Exception("没有该产品");
		}
		
		return product;
	}
}


最后测试类,根据传入的参数来决定生产什么类型的产品:

/**
 * 简单工厂又称静态工厂(Simple Factory)测试类
 */
public class Test {
	
	public static void main(String[] args) {
		
		try {
			//生产冰箱
			SimpleFactory.create("icebox");
			
			//生产空调
			SimpleFactory.create("airCondition");
			
			//生产洗衣机
			SimpleFactory.create("washer");
			
			//生产没有的产品,抛出异常
			SimpleFactory.create("cellPhone");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}


由上可以看出简单工厂的核心是SimpleFactory类,该类必须具有逻辑判断能力和所有产品的生产权利,我们只需要将订单给他,我们就能获得相对应的产品,这看似十分方便,但却很多的局限性,比如当我们每次想要生产一个新产品时都必须修改SimpleFactory的原代码。其次,当我们拥有很多很多产品的时候,而且产品之间又存在复杂的层次关系的时候,这个类必须拥有复杂的逻辑判断能力,其代码量也将不断地激增,这对以后的维护简直就是恐怖两个字...
还有就是,整个系统都严重依赖SimpleFactory类,只要SimpleFactory类一出问题,系统就进入不能工作的状态,这也是最为致命的一点....
以上的不足将在工厂模式的另外两种状态中得到解决。


工厂方法(Factory Method)

上面的代码告诉我们,简单工厂并不简单,它是整个模式的核心,一旦他出了问题,整个模式都将受影响而不能工作,为了降低风险和为日后的维护、扩展做准备,我们需要对它进行重构,引入工厂方法
工厂方法为工厂类定义了接口,用多态来削弱了工厂类的职能,以下是工厂接口的定义:

/**
 * 工厂接口
 */
public interface Factory {
	/**
	 * 创建产品
	 * @return 产品
	 */
	public Product create();
}

/**
 * 产品接口
 */
public interface Product {}
</pre><pre code_snippet_id="1660692" snippet_file_name="blog_20160425_6_3900036" name="code" class="java"><span style="font-family:KaiTi_GB2312;font-size:14px;">以下是实现了产品接口的产品类:</span>
</pre><pre code_snippet_id="1660692" snippet_file_name="blog_20160425_8_9690321" name="code" class="java">/**
 * 空调
 */
public class AirCondition implements Product{
	
	public AirCondition(){
		System.out.println("空调被制造了");
	}
}

/**
 * 冰箱
 */
public class Icebox implements Product{
	public Icebox(){
		System.out.println("冰箱被制造了");
	}
}

/**
 * 洗衣机
 */
public class Washer implements Product{
	
	public Washer(){
		System.out.println("洗衣机被制造了");
	}
}



接下来就产品的核心类,也就创建产品的工厂类:

/**
 * 空调生产工厂
 */
public class AirConditionFactory implements Factory{

	@Override
	public Product create() {
		return new AirCondition();
	}
}

/**
 * 冰箱生产工厂
 */
public class IceboxFactory implements Factory{

	@Override
	public Product create() {
		return new Icebox();
	}
}

/**
 * 洗衣机生产工厂
 */
public class WasherFactory implements Factory{

	@Override
	public Product create() {
		return new Washer();
	}
}

测试类:

/**
 * 工厂方法(Factory Method)测试类
 */
public class Test {
	public static void main(String[] args) {
		//调用洗衣机生产工厂,生产洗衣机
		Factory washerFactory = new WasherFactory();
		Washer washer = (Washer) washerFactory.create();
		
		//调用空调生产工厂,生产空调
		Factory airConditionFactory = new AirConditionFactory();
		AirCondition airCondition = (AirCondition) airConditionFactory.create();
		
		//调用冰箱生产工厂,生产冰箱
		Factory iceboxFactory = new IceboxFactory();
		Icebox icebox = (Icebox) iceboxFactory.create();
		
	}
}

从上面创建产品对象的代码可以看出,工厂方法简单工厂的主要区别是,简单工厂是把创建产品的职能都放在一个类里面,而工厂方法则把不同的产品放在实现了工厂接口的不同工厂类里面,这样就算其中一个工厂类出了问题,其他工厂类也能正常工作,互相不受影响,以后增加新产品,也只需要新增一个实现工厂接口工厂类,就能达到,不用修改已有的代码。但工厂方法也有他局限的地方,那就是当面对的产品有复杂的等级结构的时候,例如,工厂除了生产家电外产品,还生产手机产品,这样一来家电是手机就是两大产品家族了,这两大家族下面包含了数量众多的产品,每个产品又有多个型号,这样就形成了一个复杂的产品树了。如果用工厂方法来设计这个产品家族系统,就必须为每个型号的产品创建一个对应的工厂类,当有数百种甚至上千种产品的时候,也必须要有对应的上百成千个工厂类,这就出现了传说的类爆炸,对于以后的维护来说,简直就是一场灾难.....


抽象工厂(Abstract Factory)

抽象工厂是在生产产品的同时对产品进行分类处理,比如说“冰箱A、冰箱B、洗衣机A、洗衣机B”这四种产品,可以将“冰箱A、洗衣机A”两种A类产品归为一类,“冰箱B、洗衣机B”两种B类产品又归为一类:

首先为冰箱和洗衣机两种产品分别定义一个产品接口:

/**
 * 冰箱接口
 */
public interface Icebox {}

/**
 * 洗衣机接口
 */
public interface Washer {}


接着分别创建这两个接口的具体产品:

/**
 * 冰箱A
 */
public class IceboxA implements Icebox{

	public IceboxA() {
		System.out.println("冰箱A被制造了");
	}
}

/**
 * 冰箱B
 */
public class IceboxB implements Icebox{

	public IceboxB() {
		System.out.println("冰箱B被制造了");
	}
}

/**
 * 洗衣机A
 */
public class WasherA implements Washer{

	public WasherA() {
		System.out.println("洗衣机A被制造了");
	}
}

/**
 * 洗衣机B
 */
public class WasherB implements Washer{

	public WasherB() {
		System.out.println("冰箱B被制造了");
	}
}

到此,产品部分准备完毕,接下来我们来定义一个产品工厂接口:

/**
 * 工厂接口
 */
public interface Factory {
	public Washer createWasher();
	public Icebox createIcebox();
}

然后创建工厂类实现工厂:

/**
 * 生产A类产品的工厂
 */
public class FactoryA implements Factory{

	@Override
	public Washer createWasher() {
		return new WasherA();
	}

	@Override
	public Icebox createIcebox() {
		return new IceboxA();
	}
}

/**
 * 生产B类产品的工厂
 */
public class FactoryB implements Factory{

	@Override
	public Washer createWasher() {
		return new WasherB();
	}

	@Override
	public Icebox createIcebox() {
		return new IceboxB();
	}
}


测试类:
/**
 * 抽象工厂(Abstract Factory)测试类
 */
public class Test {
	
	public static void main(String[] args) {
		
		//调用A类工厂,生产A类冰箱和A类洗衣机
		Factory factoryA = new FactoryA();
		IceboxA iceboxA = (IceboxA) factoryA.createIcebox();
		WasherA washerA = (WasherA) factoryA.createWasher();
		
		//调用B类工厂,生产B类冰箱和B类洗衣机
		Factory factoryB = new FactoryB();
		IceboxB iceboxB = (IceboxB) factoryB.createIcebox();
		WasherB washerB = (WasherB) factoryB.createWasher();
		
	}
}












评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值