讲述
抽象工厂模式是工厂模式中最抽象的,能抽取的全都抽取了。
此模式可以向客户端提供一个接口,使客户端不必指定对象的具体类型,就能创建多个类型的对象。
要素
要想实现工厂方法模式,我们需要的要素有(与工厂方法模式同,意义不同):
首先要有具体的角色,即具体的实例(菜肴)。
要有共同的抽象(锅碗瓢盆)。
及具体的工厂(饭店)。
还有抽象工厂(餐饮公司)。
注意:抽象工厂的方法对应产品系列,具体工厂对应产品族。
什么意思呢?
接着工厂方法模式聊
我的餐饮公司旗下有了几个菜系的菜馆,但是业绩一直上不去,突然有一天,我发现北方人爱吃川菜,但并不是四川人做的川菜,而是喜欢北方人特有的川菜做法,同理,南方人爱吃的鲁菜的做法也不是山东厨子的做法,于是,我开始转型了,将川菜馆和鲁菜馆拆分,成立了江北菜馆(长江以北)和江南菜馆(长江以南),分别做适合地域口味的菜。
拆分后的菜馆,都可以做川菜和鲁菜(这就是工厂)
川菜和鲁菜就是产品系列
江南菜馆就是一个产品族(有川菜和鲁菜)
好处就是同一个产品族协同工作时,保证客户端使用的是同一产品族的对象(即江北菜馆做的肯定是北方人爱吃的做法)
坏处就是产品族拓展比较困难,要想增加一个菜系(粤菜),则既要在抽象工厂中增加方法,也要在所有的实现中增加实现。(即我要在江北菜馆和江南菜馆都要找各自的厨师,势必开销会变大),代码量增大。
实现代码
代码可在码云中下载(包名为c_abstractFactory)
https://gitee.com/XiaoSa12138/java-models
公司改革代码
/**
* 菜的共同抽象,这里指菜的材料等
*/
public interface Cai {
void get();
}
/**
* 笼统的川菜
*/
public abstract class ChuanCai implements Cai {
public abstract void get();
}
//北方对于川菜的做法
public class NorthChuanCai extends ChuanCai{
public void get() {
System.out.println("北方人爱吃的麻婆豆腐.....");
}
}
//南方对于川菜的做法
public class SouthChuanCai extends ChuanCai{
public void get() {
System.out.println("南方人爱吃的麻婆豆腐.....");
}
}
/**
* 笼统的鲁菜
*/
public abstract class LuCai implements Cai {
public abstract void get();
}
//北方对于鲁菜的做法
public class NorthLuCai extends LuCai {
public void get() {
System.out.println("北方人爱吃的糖醋鲤鱼.....");
}
}
//南方对于鲁菜的做法
public class SouthLuCai extends LuCai {
public void get() {
System.out.println("南方人爱吃的糖醋鲤鱼.....");
}
}
/**
* 工厂抽象类(餐饮公司)
*/
public interface CaiFactory {
Cai getLuCai();
Cai getChuanCai();
}
/**
* 北方菜生产工厂
*/
public class NorthCaiFactory implements CaiFactory {
public Cai getLuCai() {
return new NorthLuCai();
}
public Cai getChuanCai() {
return new NorthChuanCai();
}
}
/**
* 南方菜生产工厂
*/
public class SouthCaiFactory implements CaiFactory {
public Cai getLuCai() {
return new SouthLuCai();
}
public Cai getChuanCai() {
return new SouthChuanCai();
}
}
/**
* 主类
*/
public class Main {
public static void main(String[] args) {
//北方菜馆
CaiFactory northCaiFactory = new NorthCaiFactory();
northCaiFactory.getChuanCai().get();
northCaiFactory.getLuCai().get();
//南方菜馆
CaiFactory southCaiFactory = new SouthCaiFactory();
southCaiFactory.getChuanCai().get();
southCaiFactory.getLuCai().get();
}
}
此次改革也是有弊端的,例如:增加菜系
/**
* 笼统的粤菜
*/
public abstract class YueCai implements Cai {
public abstract void get();
}
//北方对于粤菜的做法
public class NorthYueCai extends YueCai {
public void get() {
System.out.println("北方人爱吃的烧鹅.....");
}
}
//南方对于粤菜的做法
public class SouthYueCai extends YueCai {
public void get() {
System.out.println("南方人爱吃的烧鹅.....");
}
}
/**
* 北方菜生产工厂增加方法
*/
public class NorthCaiFactory implements CaiFactory {
public Cai getLuCai() {
return new NorthLuCai();
}
public Cai getChuanCai() {
return new NorthChuanCai();
}
//拓展
public Cai getYueCai() {
return new NorthYueCai();
}
}
/**
* 南方菜生产工厂增加方法
*/
public class SouthCaiFactory implements CaiFactory {
public Cai getLuCai() {
return new SouthLuCai();
}
public Cai getChuanCai() {
return new SouthChuanCai();
}
//拓展
public Cai getYueCai() {
return new SouthYueCai();
}
}
/**
* 主类
*/
public class Main {
public static void main(String[] args) {
//北方菜馆
CaiFactory northCaiFactory = new NorthCaiFactory();
northCaiFactory.getChuanCai().get();
northCaiFactory.getLuCai().get();
//南方菜馆
CaiFactory southCaiFactory = new SouthCaiFactory();
southCaiFactory.getChuanCai().get();
southCaiFactory.getLuCai().get();
//拓展
northCaiFactory.getYueCai().get();
southCaiFactory.getYueCai().get();
}
}