什么是抽象工厂方法模式
属于创建型模型,抽象工厂模式提供一个创建一系列相关或相互依赖对象的接口
无须指定它们具体的类。
抽象工厂方法模式使用场景
抽象工厂方法模式强调一系列相关的产品对象(属于同一产品族)一起使用时创建对象需要大量重复的代码。抽象工厂方法模式的使用场景比较特殊,所以没有简单工厂方法和工厂方法模式常用。
工厂方法模式创建的对象由一个纬度决定,抽象工厂方法模式创建的对象不止由一个纬度决定。抽象工厂方法模式的纬度可以分为产品族和产品等级。
工厂方法针对的是产品等级结构,抽象工厂模式针对的是产品族,将一个系列的产品族统一到一起创建。
抽象工厂方法模式示例
还是之前简单工厂方法模式的例子。
要求:根据不同的请求类型(read、write、delete、execute)选择不同的helper帮助构建不同的请求对象。
之前,工厂根据不同的请求类型创建不同的RequestHelper,不同的请求类型就是产品族,但是如果除了要创建RequestHelper,还要根据不同的请求类型创建ReponseHelper呢?如果还是通过工厂方法模式创建,那针对每一种请求类型又要创建一个工厂类,也就是8个工厂类。如果以后还要根据请求类型的不同创建其他对象,那就要再增加4个工厂类,过多的工厂类会增加系统的维护难度。
这里就可以使用抽象工厂方法模式,让一个工厂类负责创建一个产品族的对象创建,这样可以有效减少工厂类的个数。
public interface IHelperFactory{
RequestHelper createRequestHelper();
ResponseHelper createResponseHelper();
}
public class ReadHelperFactory implements IHelperFactory{
@Override
public RequestHelper createRequestHelper(){
return new ReadRequestHelper();
}
@Override
public ResponseHelper createResponseHelper(){
return new ReadResponseHelper();
}
}
public class WriteHelperFactory implements IHelperFactory{
@Override
public RequestHelper createRequestHelper(){
return new WriteRequestHelper();
}
@Override
public ResponseHelper createResponseHelper(){
return new WriteResponseHelper();
}
}
//创建一个创建工厂的简单工厂
public class HelperFactoryContainer{
private static final Map<String,IHelperFactory> cacheHelper = new HashMap<>();
static{
cacheHelper.put("read",new ReadHelperFactory());
cacheHelper.put("write",new WriteHelperFactory());
cacheHelper.put("delete",new DeleteHelperFactory());
cacheHelper.put("execute",new ExecuteHelperFactory());
}
public static IHelperFactory createHelperFactory(String type){
if(StringUtils.isEmpty(type)){
return new IllegalArgumentException("...");
}
return cacheHelper.get(type.toLowerCase());
}
}
//客户端应用
public Request createRequest(Command command){
String type = command.getType();
IHelperFactory helperFactory= HelperFactoryContainer.createHelperFactory(type);
RequestHelper = helperFactory.createRequestHelper();
return RequestHelper.createRequest();
}
以上便是抽象工厂方法模式的实现与调用。如果以后需要增加请求类型,增加相应的工厂类并实现IHelperFactory即可,但是如果需要增加一个产品等级,即根据不同的请求类型创建一种其他的对象,那这种情况会破坏代码的开闭原则。需要修改接口和每个工厂类。