在上篇文章 23种设计模式01—工厂模式 中介绍了简单工厂模式和工厂方法模式, 但是简单工厂模式在添加新的产品师,需要修改工厂类,违背了开闭原则(OCP原则); 工厂方法模式,提供一个抽象工厂角色,一旦要创建新的同一产品的不同型号, 只需要创建一个具体工厂角色,用于创建对应的产品,而不用修改原有的代码,解决了简单工厂的缺点。 但是,如果要产生不同系列的产品,工厂方法模式就无能为力了。
一、抽象工厂模式首先我们来描述一个人, 开着车, 嘴里叼着苹果, 手里拿着ak47,很潇洒。。。 这个人有三个对象描述他的状态,车(交通工具),苹果(食物),ak47(武器)
package com.chb.factoryDEsingPattern_AbstractFactory;
public class Car {
public void run() {
System.out.print("老子开着车,");
}
}
package com.chb.factoryDEsingPattern_AbstractFactory;
public class Apple {
public void eat() {
System.out.print("嘴里叼着苹果,");
}
}
package com.chb.factoryDEsingPattern_AbstractFactory;
public class AK47 {
public void shoot() {
System.out.println("手里拿着ak47, da da da...");
}
}
这是个怎么样的人呢
package com.chb.factoryDEsingPattern_AbstractFactory;
public class Test {
public static void main(String[] args) {
Car car = new Car();
car.run();
Apple apple = new Apple();
apple.eat();
AK47 ak47 = new AK47();
ak47.shoot();
}
}
结果:
老子开着车,嘴里叼着苹果,手里拿着ak47, da da da...
但是老子吃的,用的,武器都是自己造的,这个太费事,不好,给我来个工厂,可以创造这些产品,
package com.chb.factoryDEsingPattern_AbstractFactory;
public class DefaultFactory {
public Car createCar(){
return new Car();
}
public Apple createApple() {
return new Apple();
}
public AK47 createAk47() {
return new AK47();
}
}
这个工厂帮我创建所需要的产品
package com.chb.factoryDEsingPattern_AbstractFactory;
public class Test {
public static void main(String[] args) {
//我要找到这个工厂
DefaultFactory df = new DefaultFactory();
//这个工厂帮我创建我所需要的所有商品
Car car = df.createCar();
car.run();
Apple apple = df.createApple();
apple.eat();
AK47 ak47 = df.createAk47();
ak47.shoot();
}
}
又不满足了, 普通人做烦了,老子要做哈利波特,
哈利波特骑着扫把, 使用魔法棒, 吃毒蘑菇
package com.chb.factoryDEsingPattern_AbstractFactory;
public class Broom {
public void run() {
System.out.println("扫把,给老子冲...");
}
}
package com.chb.factoryDEsingPattern_AbstractFactory;
public class Mushroom {
public void eat() {
System.out.print("吃个蘑菇回血了,");
}
}
package com.chb.factoryDEsingPattern_AbstractFactory;
public class MagicStick {
public void shoot() {
System.out.print("Avada Kedavra, 烧死你。。。");
}
}
活不能自己干, 来个魔法工厂
package com.chb.factoryDEsingPattern_AbstractFactory;
public class MagicFactory {
public Broom createBroom() {
return new Broom();
}
public Mushroom createMushroom() {
return new Mushroom();
}
public MagicStick createMagicStick() {
return new MagicStick();
}
}
检验一下装备怎么样
不管是凡人套装,还是魔法套装,就是三个系列产品: 交通工具:Car VS Broom 食物:Apple VS Mushroom 武器: AK47 VS MagicStick 我来定义一个规范, 产生这三个产品, 让那两个SB**当苦力**
规范交通工具可以跑, 食物可以吃, 武器有攻击力。
package com.chb.factoryDEsingPattern_AbstractFactory;
public interface Vehicle {
void run();
}
package com.chb.factoryDEsingPattern_AbstractFactory;
public interface Food {
void eat();
}
package com.chb.factoryDEsingPattern_AbstractFactory;
public interface Weapon {
void shoot();
}
空手套白狼厂长将规范给两个厂长
于是他们都按照规范做产品, 下面只展示一个案例
package com.chb.factoryDEsingPattern_AbstractFactory;
public interface AbstractFactory {
public abstract Food createFood();
public abstract Vehicle crateVehicle();
public abstract Weapon createWeapon();
}
两个厂长为了生计,付出一些代价,成为第三方(做苦力)
package com.chb.factoryDEsingPattern_AbstractFactory;
public class DefaultFactory implements AbstractFactory{
@Override
public Food createFood() {
return new Apple();
}
@Override
public Vehicle crateVehicle() {
return new Car();
}
@Override
public Weapon createWeapon() {
return new AK47();
}
}
package com.chb.factoryDEsingPattern_AbstractFactory;
public class MagicFactory implements AbstractFactory{
@Override
public Food createFood() {
return new Mushroom();
}
@Override
public Vehicle crateVehicle() {
return new Broom();
}
@Override
public Weapon createWeapon() {
return new MagicStick();
}
}
规范订好了, 小弟苦力找了, 就剩下钱多人傻的大爷了
小狼呀, 给我来套凡人套装
好的,来了:
在这里,充分使用了父类引用指向子类对象,展现了好处。
package com.chb.factoryDEsingPattern_AbstractFactory;
public class Test {
public static void main(String[] args) {
// 下发指令, 小弟(DefaultFactory)干活
AbstractFactory af = new DefaultFactory();
Vehicle vehicle = af.crateVehicle();
vehicle.run();
Food food =af.createFood();
food.eat();
Weapon weapon = af.createWeapon();
weapon.shoot();
}
}
老子开着车,嘴里叼着苹果,手里拿着ak47, da da da...
小狼呀, 给我来套魔法套装
好的,来了:
老白呀, 老子怎么觉得缺点什么, 衣食无忧, 有车游山玩水, 有枪闯天下,还缺什么呢? 老白: 爷, 酒足饭饱思淫欲, 你还缺一个妞,嘿嘿! 对, 老白知我心呀, 老白给爷弄个妞, 老白: 好的,通知下去,给大爷弄个妞来 凡人(魔法)厂长: 白爷,我们没有这个生产线, 而且你的规范里也没有这个要求, 如果你修改规范, 我们生产线要大改, 而且成本提高。 老白: 这一动,伤筋动骨,到底变不变。。。不改,生产不了 于是老白卒(抽象工厂模式遇到难题)
由上面对话可知,抽象工厂模式生产系列产品很好,但是在添加新的系列产品时,需要修改抽象工厂,同时具体工厂要实现对象的方法。违背了开闭原则。