抽象工厂模式
定义:
是围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。在抽象工厂模式中,接口是负责创建一个相关对象的工厂,不需要显式指定它们的类。每个生成的工厂都能按照工厂模式提供对象。提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
优点:
- 具体产品在应用层的代码隔离,无需关心创建的细节。
- 将一个系列的产品统一到一起创建。
缺点:
- 规定了所有可能被创建的产品集合,产品族中扩展的产品困难;
- 增加了系统的抽象性和理解难度
-
Creator:产品族工厂,定义了一系列的产品生产行为
-
ConcreteCreator:具体的产品族工厂
-
Product:抽象产品接口
-
ProductA1/A2/B1/B2:都是具体的产品,实现了相应的产品接口
为了更好理解抽象工厂模式,需要先搞清楚产品等级和产品族的概念,举个粟子:手机有小米手机、华为手机,它们都是手机,这些具体的手机和抽象手机就构成了一个产品等级结构。同样的,路由器有小米路由器,华为路由器,这些具体的路由器和抽象路由器就构成了另外一个产品等级结构,实质上产品等级结构即产品的继承结构。小米手机位于手机产品等级结构中,小米路由器位于路由器的产品等级结构中,而小米手机和小米路由器都是小米公司生产的,就构成了一个产品族,同理,华为手机和华为路由器也构成了一个产品族 。划重点就是产品族中的产品都是由同一个工厂生产的,位于不同的产品等级结构
代码实现
- 定义抽象产品接口
//手机产品接口
public interface IPhoneProduct {
//开机
void start();
//关机
void shutdown();
//拨打电话
void callUp();
//发送短信
void sendSMS();
}
//路由器产品接口
public interface IRouterProduct {
//开机
void start();
//关机
void shutdown();
//开启wifi
void openWifi();
//设置参数
void setting();
}
- 定义小米品牌手机和路由器产品实现类、华为品牌手机和路由器产品实现类
//小米手机产品
public class XiaomiPhone implements IPhoneProduct {
@Override
public void start() {
System.out.println("开启小米手机");
}
@Override
public void shutdown() {
System.out.println("关闭小米手机");
}
@Override
public void callUp() {
System.out.println("用小米手机打电话");
}
@Override
public void sendSMS() {
System.out.println("用小米手机发短信");
}
}
//小米路由器产品
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 setting() {
System.out.println("设置小米路由器参数");
}
}
//华为手机产品
public class HuaweiPhone implements IPhoneProduct {
@Override
public void start() {
System.out.println("开启华为手机");
}
@Override
public void shutdown() {
System.out.println("关闭华为手机");
}
@Override
public void callUp() {
System.out.println("用华为手机打电话");
}
@Override
public void sendSMS() {
System.out.println("用华为手机发短信");
}
}
//华为路由器产品
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 setting() {
System.out.println("设置华为路由器参数");
}
}
- 定义一个抽象工厂接口,感觉称为抽象产品族工厂可能更容易理解,毕竟它不止生产一种产品
//抽象产品工厂(定义了同一个产品族的产品生产行为)
public interface IProductFactory {
//生产手机
IPhoneProduct produceTelPhone();
//生产路由器
IRouterProduct produceRouter();
}
//小米产品工厂
public class XiaomiProductFactory implements IProductFactory {
@Override
public IPhoneProduct produceTelPhone() {
System.out.println(">>>>>>生产小米手机");
return new XiaomiPhone();
}
@Override
public IRouterProduct produceRouter() {
System.out.println(">>>>>>生产小米路由器");
return new XiaomiRouter();
}
}
//华为产品工厂
public class HuaweiProductFactory implements IProductFactory{
@Override
public IPhoneProduct produceTelPhone() {
System.out.println(">>>>>>生产华为手机");
return new HuaweiPhone();
}
@Override
public IRouterProduct produceRouter() {
System.out.println(">>>>>>生产华为路由器");
return new HuaweiRouter();
}
}
- 客户端
//客户端
public class Client {
public static void main(String[] args) {
System.out.println("===================小米系列产品=================");
//小米产品工厂实例
IProductFactory xiaomiProductFactory = new XiaomiProductFactory();
//生产小米路由器
IRouterProduct xiaomiRouter = xiaomiProductFactory.produceRouter();
xiaomiRouter.start();
xiaomiRouter.setting();
xiaomiRouter.openWifi();
xiaomiRouter.shutdown();
//生产小米手机
IPhoneProduct xiaomiPhone = xiaomiProductFactory.produceTelPhone();
xiaomiPhone.start();
xiaomiPhone.callUp();
xiaomiPhone.sendSMS();
xiaomiPhone.shutdown();
System.out.println("===================华为系列产品=================");
//华为产品工厂实例
IProductFactory huaweiProductFactory = new HuaweiProductFactory();
//生产华为路由器
IRouterProduct huaweiRouter = huaweiProductFactory.produceRouter();
huaweiRouter.start();
huaweiRouter.setting();
huaweiRouter.openWifi();
huaweiRouter.shutdown();
//生产华为手机
IPhoneProduct huaweiPhone = huaweiProductFactory.produceTelPhone();
huaweiPhone.start();
huaweiPhone.callUp();
huaweiPhone.sendSMS();
huaweiPhone.shutdown();
}
}
实际使用中,都需要根据业务去权衡使用工厂方法还是抽象工厂,前者关注点在产品等级上,后者关注点在产品族上,对于稳定的产品族,也即是产品等级数量稳定,使用抽象工厂会更加有效率,毕竟不再是一个工厂生产一种产品,而是一个工厂生产多种同族产品,对于不稳定的产品族,单独使用工厂方法会显得更加灵活!