更正上一篇最后对于抽象工厂的描述
抽象工厂模式(Abstract Factory Pattern)是围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
在抽象工厂模式中,接口是负责创建一个相关对象的工厂,不需要显式指定它们的类。每个生成的工厂都能按照工厂模式提供对象。
定义:定义了一个接口用于创建相关或有依赖关系的对象族,而无需明确指定具体类
使用场景:
1、客户端(应用层)不依赖于产品类实例如何被创建、实现等细节
2、强调一系列相关的产品对象(属于同一产品族)一起使用创建对象需要大量的重复代码
3、提供一个产品类的库,所有的产品以同样的接口实现,从而使得客户端不依赖于具体的实现
优点:
1、当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象。
2、具体产品在应用层的代码隔离,无需关心创建的细节
3、将一个系列的产品统一到一起创建
缺点:
1、产品族扩展困难,要增加一个系列的某一产品,既要在抽象的ProductFactory里加代码,又要在具体类里面加代码。
2、增加了系统的抽象性和理解难度
注意事项:产品族难扩展,产品等级易扩展。
实例
每个企业都有自己的各种产品,如华为有自己的手机、路由器和电视等,小米同样也有这些产品。每个公司的产品就属于一个产品簇。
针对每一个产品都写一个接口,这些接口规定了这些产品所共有的功能,各个公司产品的特点在其实现类里扩展
public interface IPhone {
void start();
void callUp();
void sendMes();
void shutDown();
}
public interface IRouter {
void start();
void openWIFI();
void setting();
}
然后针对这些接口,每个公司(品牌)都有它的实现类,这些具体类实现了对应的接口,每个类都实现了对应的接口,实现了代码的复用又可以各自规定自己产品的特性,实现了扩展
public class HuaweiPhone implements IPhone{
@Override
public void start() {
System.out.println("华为手机开机");
}
@Override
public void callUp() {
System.out.println("华为手机打电话");
}
@Override
public void sendMes() {
System.out.println("华为手机发消息");
}
@Override
public void shutDown() {
System.out.println("华为手机关机");
}
}
public class HuaweiRouter implements IRouter{
@Override
public void start() {
System.out.println("华为路由器开机");
}
@Override
public void openWIFI() {
System.out.println("华为路由器打开WIFI");
}
@Override
public void setting() {
System.out.println("华为路由器设置");
}
}
public class XiaomiPhone implements IPhone{
@Override
public void start() {
System.out.println("小米手机开机");
}
@Override
public void callUp() {
System.out.println("小米手机呼叫");
}
@Override
public void sendMes() {
System.out.println("小米手机发消息");
}
@Override
public void shutDown() {
System.out.println("小米手机关机");
}
}
public class XiaomiRouter implements IRouter{
@Override
public void start() {
System.out.println("小米路由器打开");
}
@Override
public void openWIFI() {
System.out.println("小米路由器打开WIFI");
}
@Override
public void setting() {
System.out.println("小米路由器打开设置");
}
}
每个公司都有自己的工厂,这些工厂又有着一些共性,比如都生产手机以及路由器,那么就将这些共性提取出来抽象出一个这些工厂的上级工厂
public interface IProductFactory {
//生产手机
IPhone iPhone();
//生产路由器
IRouter iRouter();
}
每个具体品牌的工厂都实现这个公共工厂,然后再扩展自己工厂的特有特性
public class XiaomiFactory implements IProductFactory {
@Override
public IPhone iPhone() {
return new XiaomiPhone();
}
@Override
public IRouter iRouter() {
return new XiaomiRouter();
}
}
public class HuaweiFactory implements IProductFactory{
@Override
public IPhone iPhone() {
return new HuaweiPhone();
}
@Override
public IRouter iRouter() {
return new HuaweiRouter();
}
}
如此就实现了产品簇的隔离
public class Consumer {
public static void main(String[] args) {
System.out.println("=========华为系列产品=========");
HuaweiFactory huaweiFactory = new HuaweiFactory();
IPhone huaweiPhone = huaweiFactory.iPhone();
huaweiPhone.callUp();
IRouter huaweiRouter = huaweiFactory.iRouter();
huaweiRouter.start();
System.out.println("=========小米系列产品=========");
XiaomiFactory xiaomiFactory = new XiaomiFactory();
IRouter xiaomiRouter = xiaomiFactory.iRouter();
xiaomiRouter.openWIFI();
IPhone xiaomiPhone = xiaomiFactory.iPhone();
xiaomiPhone.sendMes();
}
}
简单工厂模式和工厂方法模式都是针对一个产品进行的品牌分离,当这个品牌拥有多个产品时,为了进行代码的复用和内聚就需要使用抽象工厂模式。
产品族难扩展,产品等级易扩展的理解,即当增加一个拥有已知(代码里)产品的品牌时不用改动原来的代码,而当增加一个产品时,既需要增加一个产品接口,还需要各个品牌厂商的工厂类里添加该商品,还要在抽象工厂类增加一个制造该产品的功能。
三种工厂模式的使用选择
简单工厂 : 用来生产同一等级结构中的任意产品。(不支持拓展增加产品)
工厂方法 :用来生产同一等级结构中的固定产品。(支持拓展增加产品)
抽象工厂 :用来生产不同产品族的全部产品。(支持拓展增加产品;支持增加产品族)