文章目录
- 一、抽象工厂模式简介
- 二、抽象工厂模式适用场景
- 三、抽象工厂模式优缺点
- 四、产品等级结构和产品族
- 五、抽象工厂模式代码示例
- 1、冰箱抽象类
- 2、美的冰箱实现类
- 3、格力冰箱实现类
- 4、空调抽象类
- 5、美的空调实现类
- 6、格力空调实现类
- 7、工厂抽象接口 ( 重点 )
- 8、美的工厂实现类 ( 重点 )
- 9、格力工厂实现类 ( 重点 )
- 10、测试类
一、抽象工厂模式简介
抽象工厂模式 : 提供 一个 创建 一系列 相关 或 相互依赖 对象 的接口 ;
创建目标对象时 , 只需要直到对象的抽象类型或接口类型即可 , 不需要知道具体的实现类型 ;
抽象工厂模式类型 : 创建型 ;
抽象工厂模式 可以将 一组具有同一主题 , 单独的工厂 封装起来 ;
在使用时 , 客户端 创建 抽象工厂 的实现 , 使用 抽象工厂 作为接口 , 来创建这一主题的对象 ;
使用的时候 , 不需要知道 从内部 工厂方法中获得的 对象 的具体类型 ;
客户端 只 使用这些对象的 通用接口 ;
抽象工厂模式 实现了 一组对象的 实现细节 与 使用 分离 ;
二、抽象工厂模式适用场景
抽象工厂模式适用场景 :
- 忽略创建细节 : 客户端 不关心 产品实例 如何 被创建 , 实现等细节 ;
- 创建产品族 : 强调 一系列 相关的 产品对象 , 一般是 同一个产品族 , 一起使用 创建对象需要大量重复的代码 ;
- 产品类库 : 提供 一个 产品类 的库 , 所有的产品 以 同样的接口出现 , 使 客户端不依赖于具体实现 ;
使用抽象工厂模式 , 可以在工厂变化时 , 不需要修改 客户端 使用工厂的 代码 ;
三、抽象工厂模式优缺点
抽象工厂模式优点 :
- 隔离产品代码 : 在 应用层 隔离 具体产品的代码 , 客户端 无须关心 产品创建 的细节 ;
- 创建产品族 : 将 一个系列 的 产品族 , 统一到一起创建 ;
抽象工厂模式缺点 :
- 扩展困难 : 规定了 所有 可能 被创建 的 产品集合 , 产品族 中 扩展 新的产品 困难 , 需要 修改抽象工厂的接口 ;
- 增加难度 : 增加了系统的 抽象性 和 理解难度 ;
四、产品等级结构和产品族
下图中 , 有 椭圆形 , 圆形 , 正方形 , 三种产品 ;
- 产品族 : 相同颜色的代表一个产品族 ;
- 产品等级结构 : 相同形状的代表同一个产品等级结构 ;
如 : 方型 - 洗衣机 , 圆形 - 空调 , 椭圆 - 冰箱 ;
- 横向 看 产品族 : 某 品牌下 有 方型 - 洗衣机 , 圆形 - 空调 , 椭圆 - 冰箱 , 这是一个产品族 ;
- 纵向看产品等级结构 : 椭圆 - 冰箱 , 纵向指的是不同品牌的冰箱 ;
工厂方法模式 针对的是 产品等级结构 , 可以 扩展多个相同的产品 ;
抽象工厂模式 针对的是 产品族 , 在 某个品牌 的工厂中取出 洗衣机 类 , 取出的肯定是 该品牌的洗衣机实例对象 ;
只要指出 产品所在的 产品族 以及 产品所在的 产品等级结构 , 就可以唯一确定一个产品 ;
左侧的 纵坐标轴 上的 工厂 是 具体的工厂 , 从该具体的工厂中 创建的实例 是 该产品族中的实例 ;
使用 工厂模式 还是 抽象工厂模式 , 要看具体的业务场景 ;
当一个工厂 可以 创建 分属于 不同 产品等级结构 的 一个 产品族 中的 不同对象时 , 使用 抽象工厂模式 ;
如 :
- 工厂 中可以创建 相同品牌的 洗衣机 , 冰箱 , 空调 等产品 , 使用 抽象工厂模式 ;
- 如果 工厂中创建 不同品牌的空调 , 则使用 工厂方法模式 ;
五、抽象工厂模式代码示例
如果要新增 产品族 , 只需要增加 产品族工厂 , 对应的产品类 即可 ;
如果要新增 产品等级 , 很麻烦 , 需要修改所有的产品族工厂 , 这就违背了开闭原则 ;
产品等级结构固定 , 需要多个产品组合在一起形成产品族的 业务场景 , 适合使用抽象工厂模式 ;
业务场景 : 有两个电器品牌 , 美的 和 格力 ; 每个品牌下都有 冰箱 和 空调 产品 ;
1、冰箱抽象类
package abstractfactory;/*** 冰箱抽象类*/
public abstract class Fridge {public abstract void produce();
}
2、美的冰箱实现类
package abstractfactory;/*** 美的冰箱*/
public class MideaFridge extends Fridge {@Overridepublic void produce() {System.out.println("生产美的冰箱");}
}
3、格力冰箱实现类
package abstractfactory;/*** 格力冰箱*/
public class GreeFridge extends Fridge {@Overridepublic void produce() {System.out.println("生产格力冰箱");}
}
4、空调抽象类
package abstractfactory;/*** 空调抽象类*/
public abstract class AirConditioner {public abstract void produce();
}
5、美的空调实现类
package abstractfactory;/*** 美的空调*/
public class MideaAirConditioner extends AirConditioner {@Overridepublic void produce() {System.out.println("生产美的空调");}
}
6、格力空调实现类
package abstractfactory;/*** 格力空调*/
public class GreeAirConditioner extends AirConditioner {@Overridepublic void produce() {System.out.println("生产格力空调");}
}
7、工厂抽象接口 ( 重点 )
package abstractfactory;/*** 抽象工厂方法*/
public interface Factory {/*** 生产冰箱* @return*/Fridge getFridge();/*** 生产空调* @return*/AirConditioner getAirConditioner();
}
8、美的工厂实现类 ( 重点 )
package abstractfactory;/*** 美的工厂*/
public class MideaFactory implements Factory {@Overridepublic Fridge getFridge() {return new MideaFridge();}@Overridepublic AirConditioner getAirConditioner() {return new MideaAirConditioner();}
}
9、格力工厂实现类 ( 重点 )
package abstractfactory;/*** 格力抽象工厂*/
public class GreeFactory implements Factory {@Overridepublic Fridge getFridge() {return new GreeFridge();}@Overridepublic AirConditioner getAirConditioner() {return new GreeAirConditioner();}
}
10、测试类
package abstractfactory;public class Main {public static void main(String[] args) {// 生产 美的 品牌的 冰箱 和 空调Factory mideaFactory = new MideaFactory();// 美的冰箱Fridge mideaFridge = mideaFactory.getFridge();mideaFridge.produce();// 美的空调AirConditioner mideaAirConditioner = mideaFactory.getAirConditioner();mideaAirConditioner.produce();System.out.println();// 生产 格力 品牌的 冰箱 和 空调Factory greeFactory = new GreeFactory();// 格力冰箱Fridge greeFridge = greeFactory.getFridge();greeFridge.produce();// 格力空调AirConditioner greeFridgeAirConditioner = greeFactory.getAirConditioner();greeFridgeAirConditioner.produce();}
}
执行结果 :
生产美的冰箱
生产美的空调生产格力冰箱
生产格力空调