- 建议与另一篇博客搭配学习
抽象工厂模式
- 抽象工厂模式:围绕一个超级工厂创建其他工厂,该超级工厂又称为其他工厂的工厂
相关概念
- 定义:抽象模式提供了一个创建一系列相关或者相互依赖对象的接口,无需指定他们具体的类
- 适用场景:
- 客户端(应用端)不依赖于产品类实例如何被创建、实现等细节
- 强调一系列相关的产品对象(属于同一产品族),如果一起使用创建对象需要大量的重复代码
- 提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于具体的实现
- 优点:
- 具体产品在应用层的代码隔离,无需关心创建的细节
- 将一个系列的产品统一到一起创建
- 缺点:
- 规定了所有可能被创建的产品集合,产品族中扩展新的产品困难
- 增加了系统的抽象性和理解难度
【 注意 】产品结构和产品族的定义:产品族内的产品是由同一个工厂生产出来的;产品结构指的是产品所处的类别。举个例子,小米生产小米手机和小米路由器,华为生产华为手机和华为路由器,那么小米路由器和华为路由器就处于同一个产品结构等级;小米手机和小米路由器就处于同一个产品族,同理,华为手机和华为路由器也是处于同一个产品族。
总体结构
IProductFactory
就是工厂的抽象接口,XiaoMiFactory 和 HuaWeiFactory
是他的实现类IMobileProduct 和 IRouterProduct
是两个产品的接口
产品接口及其实现类
/**
* 手机产品接口
* @author Hey
*/
public interface IMobileProduct {
/**
* 手机开机
*/
void start();
/**
* 手机关机
*/
void shutdown();
/**
* 打电话
*/
void callup();
/**
* 发短信
*/
void sendMessage();
}
------------------------------------------------------------------
/**
* 小米手机
* @author Hey
*/
public class XiaoMiPhone implements IMobileProduct{
@Override
public void start() {
System.out.println("开启小米手机");
}
@Override
public void shutdown() {
System.out.println("关闭小米手机");
}
@Override
public void callup() {
System.out.println("使用小米手机打电话");
}
@Override
public void sendMessage() {
System.out.println("使用小米手机发短信");
}
}
------------------------------------------------------------------
/**
* 华为手机
* @author Hey
*/
public class HuaWeiPhone implements IMobileProduct{
@Override
public void start() {
System.out.println("开启华为手机");
}
@Override
public void shutdown() {
System.out.println("关闭华为手机");
}
@Override
public void callup() {
System.out.println("使用华为手机打电话");
}
@Override
public void sendMessage() {
System.out.println("使用华为手机发短信");
}
}
------------------------------------------------------------------
/**
* 路由产品接口
* @author Hey
*/
public interface IRouterProduct {
/**
* 路由器开机
*/
void start();
/**
* 路由器关机
*/
void shutdown();
/**
* 打开wifi
*/
void openWiFi();
/**
* 设置WiFi密码
*/
void setWiFiPassword();
}
------------------------------------------------------------------
/**
* 小米路由器
* @author Hey
*/
public class XiaoMiRouter implements IRouterProduct{
@Override
public void start() {
System.out.println("开启小米路由器");
}
@Override
public void shutdown() {
System.out.println("关闭小米路由器");
}
@Override
public void openWiFi() {
System.out.println("开启小米路由器的wifi");
}
@Override
public void setWiFiPassword() {
System.out.println("设置小米路由器的wifi密码");
}
}
------------------------------------------------------------------
/**
* 华为路由器
* @author Hey
*/
public class HuaWeiRouter implements IRouterProduct{
@Override
public void start() {
System.out.println("华为路由器");
}
@Override
public void shutdown() {
System.out.println("华为小米路由器");
}
@Override
public void openWiFi() {
System.out.println("开启华为路由器的wifi");
}
@Override
public void setWiFiPassword() {
System.out.println("设置华为路由器的wifi密码");
}
}
工厂接口及其实现类
/**
* 抽象产品工厂
* 可以理解为抽象的抽象
* @author Hey
*/
public interface IProductFactory {
//生产手机
IMobileProduct iMobileProduct();
//生产路由器
IRouterProduct iRouterProduct();
}
-----------------------------------------------
/**
* 华为工厂
* @author Hey
*/
public class HuaWeiFactory implements IProductFactory {
@Override
public IMobileProduct iMobileProduct() {
return new HuaWeiPhone();
}
@Override
public IRouterProduct iRouterProduct() {
return new HuaWeiRouter();
}
}
-----------------------------------------------
/**
* 小米工厂
* @author Hey
*/
public class XiaoMiFactory implements IProductFactory {
@Override
public IMobileProduct iMobileProduct() {
return new XiaoMiPhone();
}
@Override
public IRouterProduct iRouterProduct() {
return new XiaoMiRouter();
}
}
消费者 Consumer类
/**
* 消费者
* @author Hey
*/
public class Consumer {
public static void main(String[] args) {
System.out.println("============ 小米系列的产品 ===========");
//创建小米工厂
XiaoMiFactory xiaoMiFactory = new XiaoMiFactory();
//获得小米工厂生产的产品
IMobileProduct xiaoMiMobile = xiaoMiFactory.iMobileProduct();
//使用小米手机
xiaoMiMobile.start();
xiaoMiMobile.callup();
xiaoMiMobile.sendMessage();
xiaoMiMobile.shutdown();
//使用小米路由器
IRouterProduct xiaoMiRouter = xiaoMiFactory.iRouterProduct();
xiaoMiRouter.start();
xiaoMiRouter.setWiFiPassword();
xiaoMiRouter.openWiFi();
xiaoMiRouter.shutdown();
System.out.println("============ 华为系列的产品 ===========");
//创建华为工厂
HuaWeiFactory huaWeiFactory = new HuaWeiFactory();
//获得华为工厂生产的产品
IMobileProduct huaWeiMobile = huaWeiFactory.iMobileProduct();
//使用华为手机
huaWeiMobile.start();
huaWeiMobile.callup();
huaWeiMobile.sendMessage();
huaWeiMobile.shutdown();
//使用华为路由器
IRouterProduct huaWeiRouter = huaWeiFactory.iRouterProduct();
huaWeiRouter.start();
huaWeiRouter.setWiFiPassword();
huaWeiRouter.openWiFi();
huaWeiRouter.shutdown();
}
}
解析
- 抽象工厂模式即将产品的生产再抽象化成一个接口,当有一个新的产品需要被生产的时候,就可以创建一个工厂实现抽象接口,也对工厂形成了一种约束
- 抽象产品的接口也就无需指定他们具体的类,当你需要某一个产品的时候直接到生产的工厂去拿即可
- 举个例子:在前面的例子中,五菱和特斯拉依托于
CarFactory
生产,那么如果我要获得大众的车,就要修改代码,违背了开闭原则;那么在抽象工厂模式中,我只需要新建一个大众的Factory
,然后在里面生产生产一个Car
即可 - 可是如果生产的产品需要增加,例如新增一个笔记本的产品,那么就需要修改 生产产品的抽象类,而一旦修改了这个接口,那么下面的实现类就要跟着一起修改,就会违反了开闭原则
- 同理,如果在一些比较稳定的情况下,就可以使用抽象工厂模式
小结
- 抽象工厂模式:不可以增加产品族里的产品,但是可以增加产品族!