设计模式-抽象工厂模式

来源:互联网 发布:java 修改图片名字 编辑:程序博客网 时间:2024/05/29 16:25

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

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

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

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

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

一个人开着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{@Overridepublic Vehicle createVehicle() {// TODO Auto-generated method stubreturn new Car();}@Overridepublic Weapon createWeapon() {// TODO Auto-generated method stubreturn new Ak47();}@Overridepublic Food createFood() {// TODO Auto-generated method stubreturn new Apple();}}
package com.feng.factory.abstractfactory;public class MagicFactory extends AbstractFactory{@Overridepublic Vehicle createVehicle() {// TODO Auto-generated method stubreturn new Broom();}@Overridepublic Weapon createWeapon() {// TODO Auto-generated method stubreturn new MagicStrick();}@Overridepublic Food createFood() {// TODO Auto-generated method stubreturn 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食物,去东北。。。。。
这样的话新添加了一种类型,这种变化对抽象工厂模式的扩展是非常不利的。会引起大部分文件内容的改变。






0 0
原创粉丝点击