什么是抽象工厂模式?
抽象工厂模式是所有形态的工厂模式中最为抽象和最其一般性的。抽象工厂模式可以向客户端
提供一个接口,使得客户端在不必指定产品的具体类型的情况下,能够创建多个产品族的产品对象。
举个例子,现在有两个品牌厂商,小米和华为,小米生产手机和路由器,华为也生产手机和路由器,但是小米生产的产品都是在小米的工厂生产的,华为的产品都是在华为的工厂生产的,但是这两个工厂要符合同一个工厂标准,也就是抽象工厂。另外两个厂商都生产手机,这个生产的手机要否和手机产品的标准,生产的路由器也要符合路由产品的标准。综上所述每个厂商都会生产不同的产品也就是产品簇。所以抽象工厂是针对整个产品簇的。
具体实现代码如下:
手机产品接口:
package abf;
/**
* 手机产品接口
*/
interface IPhoneProduct {
void call(); //打电话功能
void sendSMS(); //发短信功能
void open();//开机功能
void close();//关机功能
}
小米手机产品类:
package abf;
/**
* 小米手机产品
*/
public class XiaoMiPhone implements IPhoneProduct {
public void call() {
System.out.println("小米手机 call");
}
public void sendSMS() {
System.out.println("小米手机 sendSMS");
}
public void open() {
System.out.println("小米手机 open");
}
public void close() {
System.out.println("小米手机 close");
}
}
华为手机产品类:
package abf;
/**
* 华为手机产品
*/
public class HuaWeiPhone implements IPhoneProduct {
public void call() {
System.out.println("华为手机 call");
}
public void sendSMS() {
System.out.println("华为手机 sendSMS");
}
public void open() {
System.out.println("华为手机 open");
}
public void close() {
System.out.println("华为手机 close");
}
}
路由器产品接口:
package abf;
/**
* 路由产品接口
*/
interface IRouterProduct {
void open(); //开机功能
void close(); //关机功能
void wifi(); //wifi功能
}
小米路由器产品类:
package abf;
/**
*小米路由器产品
*/
public class XiaoMiRouter implements IRouterProduct {
public void open() {
System.out.println("小米路由器 open");
}
public void close() {
System.out.println("小米路由器 close");
}
public void wifi() {
System.out.println("小米路由器 wifi");
}
}
华为路由器产品接口:
package abf;
/**
* 华为路由器产品
*/
public class HuaWeiRouter implements IRouterProduct {
public void open() {
System.out.println("华为路由器 open");
}
public void close() {
System.out.println("华为路由器 close");
}
public void wifi() {
System.out.println("华为路由器 wifi");
}
}
抽象工厂
package abf;
/**
* 抽象工厂
*/
public interface AbstractFactory {
//生产手机
IPhoneProduct iphoneProduct();
//生产路由器
IRouterProduct irouterProduct();
}
小米工厂:
package abf;
/**
* 生产小米产品的工厂
*/
public class XiaoMiFactory implements AbstractFactory {
public IPhoneProduct iphoneProduct() {
return new XiaoMiPhone();
}
public IRouterProduct irouterProduct() {
return new XiaoMiRouter();
}
}
华为工厂:
package abf;
/**
* 生产华为产品的工厂
*/
public class HuaWeiFactory implements AbstractFactory{
public IPhoneProduct iphoneProduct() {
return new HuaWeiPhone();
}
public IRouterProduct irouterProduct() {
return new HuaWeiRouter();
}
}
创建产品的测试类:
package abf;
public class Consumer {
public static void main(String[] args) {
//创建小米工厂
XiaoMiFactory xiaoMiFactory = new XiaoMiFactory();
//小米工厂生产手机
IPhoneProduct iPhoneProduct = xiaoMiFactory.iphoneProduct();
iPhoneProduct.call();
iPhoneProduct.sendSMS();
//小米工厂生产路由器
IRouterProduct iRouterProduct = xiaoMiFactory.irouterProduct();
iRouterProduct.open();
iRouterProduct.wifi();
iRouterProduct.close();
//创建华为工厂
HuaWeiFactory huaWeiFactory = new HuaWeiFactory();
//华为工厂生产手机
IPhoneProduct iPhoneProduct1 = huaWeiFactory.iphoneProduct();
iPhoneProduct1.sendSMS();
iPhoneProduct1.call();
//华为工厂生产路由器
IRouterProduct iRouterProduct1 = huaWeiFactory.irouterProduct();
iRouterProduct1.open();
iRouterProduct1.wifi();
iRouterProduct1.close();
}
}
输出结果如下:
小米手机 call
小米手机 sendSMS
小米路由器 open
小米路由器 wifi
小米路由器 close
华为手机 sendSMS
华为手机 call
华为路由器 open
华为路由器 wifi
华为路由器 close
总结:
什么场景下使用抽象工厂?
当一系列的相关对象(产品簇)稳定的情况下可以使用抽象工厂,如果抽象工厂对象频繁发生变化时则不适用,比如上面的例子我需要增加笔记本电脑的生产,那么抽象工厂、具体实现的工厂都要发生变化,这就违反了设计模式的开闭原则,这样是不推荐的。