1 名词解释
产品等级:指产品的类型一样,品牌不一样。例如空调是一种产品类型,美的空调与格力空调是不同的品牌。
产品族:同一个品牌的不同产品。例如美的的空调,电饭锅,热水器属于同一产品族。
这里引用一个图片来具体说明这两个名词解释。(来自引用2)
2 定义
是一种为访问类提供一个创建一组相关或相互依赖对象的接口,且访问类无须指定所要产品的具体类就能得到同族的不同等级的产品的模式结构。抽象工厂模式是工厂方法模式的升级版本,工厂方法模式只生产一个等级的产品,而抽象工厂模式可生产多个等级的产品。
3 三种工厂的方法的区别
首先挂两个链接,一个是我写的简单工厂模式的链接,一个是工厂方法模式的链接。
简单工厂模式中工厂类包含了必要的逻辑,工厂类依据逻辑判断从而产生不同的类实例。但要加一个类实例的创建,我们需要修改简单工厂类的代码,增加逻辑判断,相当于我们开放了功能的扩展,又开放了代码的修改,违背的开闭原则。
工厂方法模式把逻辑判断转移到客户端中,在客户端中选择不同的工厂得到实例化对象。我们需要添加一个实例化对象的创建时,只需要增加一个继承创建实例化对象工厂接口的类。
工厂方法模式的缺点在于会增加很多类,如果有很多实例化对象,每个对象都需要一个工厂类来专门创建对应的对象,造成类的数量很多,增加管理难度。
简单工厂模式与工厂方法模式都只能创建同一等级的产品,比如空调工厂只能生产空调,不能生产电视机,而抽象工厂模式能创建产品族,比如小米的工厂既能创建小米空调,又能创建小米电视,还能创建小米投影仪。
使用抽象工厂模式一般要满足以下条件:
1.系统中有多个产品族,每个具体工厂创建同一族但属于不同等级结构的产品。
2.系统一次只可能消费其中某一族产品,即同族的产品一起使用。
4 优缺点
抽象工厂模式除了具有工厂方法模式的优点外,其他主要优点如下。
1.可以在类的内部对产品族中相关联的多等级产品共同管理,而不必专门引入多个新的类来进行管理。
2.当需要产品族时,抽象工厂可以保证客户端始终只使用同一个产品的产品组。
3.抽象工厂增强了程序的可扩展性,当增加一个新的产品族时,不需要修改原代码,满足开闭原则。
其缺点是:
1.当产品族中需要增加一个新的产品时,所有的工厂类都需要进行修改。增加了系统的抽象性和理解难度。例如定义工厂能生产电视,空调。小米工厂与美的工厂继承抽象工厂都能生产电视和空调,现在工厂添加一个功能生产电饭煲,那小米工厂与美的工厂都需要修改。
5 结构与实现
抽象工厂模式的主要角色如下。
1.抽象工厂(Abstract Factory):提供了创建产品的接口,它包含多个创建产品的方法 newProduct(),可以创建多个不同等级的产品。
2.具体工厂(Concrete Factory):主要是实现抽象工厂中的多个抽象方法,完成具体产品的创建。
3.抽象产品(Product):定义了产品的规范,描述了产品的主要特性和功能,抽象工厂模式有多个抽象产品。
4.具体产品(ConcreteProduct):实现了抽象产品角色所定义的接口,由具体工厂来创建,它同具体工厂之间是多对一的关系。
如下图所示:(来自引用2)
6 代码示例
业务逻辑与简单工厂模式相同。业务需求是审核公司线上商城每一笔订单的用户评论和商户评论(对用户评论的一个回复),因为两种评论的模型有一些属性的不同,用户评论对应一个实体(UserComment)一张数据表(user_comment),商户回应评论对应一个实体(MerchantComment)一张数据表(merchant_comment)。两个实体,两张数据表,对应两个mapper(持久层框架用的Mybatis Plus)。现在前端调用接口对评论进行审核,返回审核的结果,审核结果中有一个参数(identity)标识是审核用户评论还是审核商户评论,依据identity的值在service层调用不同的mapper对数据进行持久化存储。
本例的抽象工厂既能创建mapper,也能创建comment,不同的产品等级。
6.1 抽象的评论 CommonComment
**
* @program: design-pattern-learning
* @author: zgr
* @create: 2021-09-01 16:28
**/
@Data
public class CommonComment {
private Integer id;
private String commentContent;
private String commentResult;
}
6.2 商户评论 MerchantComment
/**
* @program: design-pattern-learning
* @author: zgr
* @create: 2021-09-01 16:29
**/
@Data
public class MerchantComment extends CommonComment {
private String merchantName;
}
6.3 用户评论 UserComment
**
* @program: design-pattern-learning
* @author: zgr
* @create: 2021-09-01 16:29
**/
@Data
public class UserComment extends CommonComment {
private String userName;
}
6.4 抽象mapper接口 Mapper
/**
* @program: design-pattern-learning
* @author: zgr
* @create: 2021-09-01 16:24
**/
public interface Mapper<T> {
/**
* 存储实体到数据库
*
* @param entity 存储的实体
*/
void saveEntity(T entity);
}
6.5 商户品论mapper MerchantCommentMapper
/**
* @program: design-pattern-learning
* @author: zgr
* @create: 2021-09-01 16:26
**/
public class MerchantCommentMapper implements Mapper<MerchantComment> {
@Override
public void saveEntity(MerchantComment merchantComment) {
System.out.println("存储的是审核商户回复内容," + merchantComment.getMerchantName());
}
}
6.6 用户评论mapper
**
* @program: design-pattern-learning
* @author: zgr
* @create: 2021-09-01 16:26
**/
public class UserCommentMapper implements Mapper<UserComment> {
@Override
public void saveEntity(UserComment userComment) {
System.out.println("存储的是审核用户评论内容," + userComment.getUserName());
}
}
6.7 抽象工厂 MyAbstractFactory
/**
* @program: design-pattern-learning
* @author: zgr
* @create: 2021-09-28 11:37
**/
public interface MyAbstractFactory {
/**
* 创建mapper实例
* @return mapper实例
*/
Mapper createMapperInstance();
/**
* 创建评论实例
* @return 评论实例
*/
CommonComment createCommentInstance();
}
6.8 生产商户产品的具体工厂 MerchantCommentConcreteFactory
/**
* @program: design-pattern-learning
* @author: zgr
* @create: 2021-09-29 11:08
**/
public class MerchantCommentConcreteFactory implements MyAbstractFactory{
@Override
public Mapper createMapperInstance() {
return new MerchantCommentMapper();
}
@Override
public CommonComment createCommentInstance() {
MerchantComment merchantComment = new MerchantComment();
merchantComment.setId(1);
merchantComment.setCommentContent("商户评论类容");
merchantComment.setCommentResult("商户评论审核结果");
merchantComment.setMerchantName("hello,我是商户评论");
return merchantComment;
}
}
6.9 生产用户产品的具体工厂 UserCommentConcreteFactory
/**
* @program: design-pattern-learning
* @author: zgr
* @create: 2021-09-29 11:08
**/
public class UserCommentConcreteFactory implements MyAbstractFactory{
@Override
public Mapper createMapperInstance() {
return new UserCommentMapper();
}
@Override
public CommonComment createCommentInstance() {
UserComment userComment = new UserComment();
userComment.setId(1);
userComment.setCommentContent("用户评论类容");
userComment.setCommentResult("用户评论审核结果");
userComment.setUserName("hello,我是用户评论");
return userComment;
}
}
6.10 主函数
/**
* @program: design-pattern-learning
* @author: zgr
* @create: 2021-09-23 10:51
**/
public class MainClass {
public static void main(String[] args) {
boolean flag = true;
while (flag) {
//模拟接口参数
Scanner sc = new Scanner(System.in);
String identity = sc.nextLine();
if (identity.equals("exit")) {
System.out.println("退出系统");
flag = false;
} else {
if (identity.equals("user")) {
MyAbstractFactory factory = new UserCommentConcreteFactory();
Mapper mapper = factory.createMapperInstance();
mapper.saveEntity(factory.createCommentInstance());
}else if (identity.equals("merchant")) {
MyAbstractFactory factory = new MerchantCommentConcreteFactory();
Mapper mapper = factory.createMapperInstance();
mapper.saveEntity(factory.createCommentInstance());
} else {
System.out.println("身份标识参数输入错误");
continue;
}
}
}
}
}
6.11 运行结果
7 引用
1.《大话设计模式》