设计模式-抽象工厂模式

抽象工厂模式针对的是对一系列产品进行扩展的问题。

工厂方法模式针对的是对一类产品进行替换的问题。这两种要区分开。

比如房屋装修,你找装修公司,每个装修公司都有自己的一套装修方案,用的瓷砖,木板,桌子,椅子每个公司都不一样,你选用不同的装修公司,这一套产品都要跟着换,这就是抽象工厂模式的使用环境。

而工厂方法模式就好像是一个司机开车,开的是什么车,只对车这个产品进行替换,是同类产品间的替换。容易引起工厂泛滥。

下面来看一个例子,模拟一个场景

一个人开着XXX交通工具,拿着XXX武器,吃着XXX食物,去东北。。。。。

对于这个场景,我有几套方案,如果换的话要把整套的都替换掉。

比如我又两套方案

(1)交通工具是Car,武器是Ak47,食物是Apple

(2)交通工具是Broom(哈利波特的扫帚),武器是MagicStrick,食物是Mushroom

首先我们要对交通工具,武器,食物,分别提供一个接口或者抽象类,代码如下:

package com.feng.factory.abstractfactory;

public abstract class Vehicle {
	public abstract void run();

}
package com.feng.factory.abstractfactory;

public abstract class Weapon {

	public abstract void shoot();
}
package com.feng.factory.abstractfactory;

public abstract class Food {

	public abstract void printName();
}
然后,我们把具体的交通工具,武器,食物都构造出来,分别继承相应的抽象类,或者是实现相应的接口

先看交通工具类,实现两个类,Car和Broom

package com.feng.factory.abstractfactory;


public class Car extends Vehicle{

	public void run()
	{
		System.out.println("开着车,车跑了。。。。。");
	}
}
package com.feng.factory.abstractfactory;

public class Broom extends Vehicle{
	
	public void run()
	{
		System.out.println("起着扫帚去东北。。。");
	}

}
再看武器类,实现两个类,AK47和MagicStrick

package com.feng.factory.abstractfactory;

public class Ak47 extends Weapon{

	public void shoot()
	{
		System.out.println("使用AK47射击。。。。。");
	}
}
package com.feng.factory.abstractfactory;

public class MagicStrick extends Weapon{
	
	public void shoot()
	{
		System.out.println("使用魔法棒攻击敌人。。。");
	}
}
再看食物类,实现两个类,Apple和Mushroom
package com.feng.factory.abstractfactory;

public class Apple extends Food{

	public void printName()
	{
		System.out.println("Apple");
	}
}
package com.feng.factory.abstractfactory;

public class Mushroom extends Food{
	public void printName()
	{
		System.out.println("Mushroom");
	}

}
对于每一套方案,我们都应该有一个工厂,工厂要有一个统一的接口

先看统一的接口

package com.feng.factory.abstractfactory;

public abstract class AbstractFactory {

	public abstract Vehicle createVehicle();
	public abstract Weapon createWeapon();
	public abstract Food createFood();
}
每套方案都要继承这个抽象类,这里有两套方案,一种是DefaultFactory对应第一套方案,另一种是MagicFactory对应第二套方案

package com.feng.factory.abstractfactory;

public class DefaultFactory extends AbstractFactory{

	@Override
	public Vehicle createVehicle() {
		// TODO Auto-generated method stub
		return new Car();
	}

	@Override
	public Weapon createWeapon() {
		// TODO Auto-generated method stub
		return new Ak47();
	}

	@Override
	public Food createFood() {
		// TODO Auto-generated method stub
		return new Apple();
	}
}
package com.feng.factory.abstractfactory;

public class MagicFactory extends AbstractFactory{

	@Override
	public Vehicle createVehicle() {
		// TODO Auto-generated method stub
		return new Broom();
	}

	@Override
	public Weapon createWeapon() {
		// TODO Auto-generated method stub
		return new MagicStrick();
	}

	@Override
	public Food createFood() {
		// TODO Auto-generated method stub
		return new Mushroom();
	}
}
最后就是测试:

package com.feng.factory.abstractfactory;


public class Test {

	public static void main(String[] args) {
		
		//现在有一个用户,这个用户拿着Ak47,吃着苹果,开着车
		AbstractFactory factory = new DefaultFactory();
		Vehicle c = factory.createVehicle();
		c.run();
		Weapon w = factory.createWeapon();
		w.shoot();
		Food f = factory.createFood();
		f.printName();
	}

}
执行结果:

如果想换成另一套方案的话,在测试类中将AbstractFactory factory = new DefaultFactory(); 改为 AbstractFactory factory = new MagicFactory();即可其他的地方不需要改变

执行结果如下:



如果想增加新的方案,增加一个新的工厂即可,工厂继承AbstractFactory,如果要增加新的规定类型的产品,新建类就可以。

但是如果要添加新的类型,例如上面的例子

一个人开着XXX交通工具,拿着XXX武器,吃着XXX食物,去东北。。。。。

现在我要更改需求了,改为:

一个人开着XXX交通工具,拿着XXX武器,听着xxx音乐,吃着XXX食物,去东北。。。。。
这样的话新添加了一种类型,这种变化对抽象工厂模式的扩展是非常不利的。会引起大部分文件内容的改变。






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值