1、抽象工厂模式的定义
抽象工厂模式(Abstract Factory Pattern)是围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。在抽象工厂模式中,接口是负责创建一个相关对象的工厂,不需要显式指定它们的类。每个生成的工厂都能按照工厂模式提供对象。
2、抽象工厂模式特性
(1)意图:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
(2)主要解决:主要解决接口选择的问题。
(3)何时使用:系统的产品有多于一个的产品族,而系统只消费其中某一族的产品。
(4)如何解决:在一个产品族里面,定义多个产品。
(5)关键代码:在一个工厂里聚合多个同类产品。
3、抽象工厂模式的优缺点及应用场景
(1)优点:
1. 具体产品在应用层的代码隔离,无需关系创建的细节
2. 将一个系列的产品统一到一起创建
(2)缺点:
1. 规定了所有可能被创建的产品集合,产品族中扩展新的产品困难;
2. 增加了系统的抽象性和理解难度
(3)使用场景:
1. 系统中有多于一个的产品族,而每次只使用其中某一产品族。
2. 在很多软件系统中需要更换界面主题或者一键换肤。
3. DAO层支持多种类型的数据库,动态切换时。
4. 不同操作系统代码差异化,可以切换不同操作系统时。
(4)注意事项:
产品族难扩展,产品等级易扩展。
理解产品族和产品等级
产品族:一个品牌下面的所有产品;例如小米下面的打印机,扫码枪 称为小米的产品族;
产品等级:多个品牌下面的同种产品;例如惠普和小米下面的打印机 称为一个产品等级;
4、抽象工厂模式的结构和说明
- AbstractFactory:这是抽象工厂模式的核心,它与应用程序无关。是具体工厂角色必须实现的接口或者必须继承的父类。在java中它由抽象类或者接口来实现。
- ConcreteFactory:它含有和具体业务逻辑有关的代码。由应用程序调用以创建对应的具体产品的对象。它由具体的类来实现。
- AbstractProduct:它是具体产品继承的父类或者是实现的接口。在java中一般由抽象类或者接口来实现。
- Product:具体工厂角色所创建的对象就是此角色的实例。在java中由具体的类来实现
5、抽象工厂模式示例
5.1 题目
假设当前电脑上接了3种类型设备,每种类型的还有不同的厂商,打印机(惠普打印机,小米打印机。。。等等),扫码枪(惠普扫码枪,小米扫码枪。。。等等),身份证读卡器(惠普读卡器,小米读卡器。。。等等)
如何设计一个插件系统
需要符合以下要求:
1. 每种类型的都要能做到动态切换,比如打印机,可以随意切换不同的厂商。
2. 需要考虑扩展
3. 需要考虑代码复用
5.2 分析
打印机、扫码枪和读卡器是我们需要的产品,生产打印机、扫码枪和读卡器的惠普和小米是我们的工厂。
5.3 代码实现
5.3.1 创建打印机、扫码枪和读卡器的接口
读卡器接口
public interface IIdCard {
void read();
}
扫码枪接口
public interface ISaoma {
void saoma();
}
打印机接口
public interface IPrint{
void print();
}
5.3.2 创建实现上述接口的实现类
小米读卡器
public class MiCard implements IIdCard{
@Override
public void read() {
System.out.println("Inside MiCard::read() method.");
}
}
小米扫码枪
public class MISaoma implements ISaoma{
@Override
public void saoma() {
System.out.println("Inside MISaoma::saoma() method.");
}
}
小米打印机
public class MiPrint extends Miaaa {
@Override
public void print() {
System.out.println("Inside MiPrint::print() method.");
}
}
惠普读卡器
public class HPCard implements IIdCard{
@Override
public void read() {
System.out.println("Inside HPCard::read() method.");
}
}
惠普扫码枪
public class HPSaoma implements ISaoma{
@Override
public void saoma() {
System.out.println("Inside HPSaoma::saoma() method.");
}
}
惠普打印机
public class HPPrint implements IPrint{
@Override
public void print() {
System.out.println("Inside HPPrint::print() method.");
}
}
5.3.3 创建工厂模式的核心,根据参数决定获取那个产品族
//抽象工厂模式的核心,根据参数决定获取那个产品族
public abstract class AbStractFactory {
public abstract IPrint getPrint(String name);
public abstract IIdCard getCard(String name);
public abstract ISaoma getSaoma(String name);
}
5.3.4 创建扩展了 AbstractFactory 的工厂类,基于给定的信息生成实体类的对象
读卡器工厂
public class CardFactory extends AbStractFactory {
@Override
public IPrint getPrint(String name) {
return null;
}
@Override
public IIdCard getCard(String name) {
if ("Mi".equalsIgnoreCase(name)){
return new MiCard();
}else if ("HP".equalsIgnoreCase(name)){
return new HPCard();
}
return null;
}
@Override
public ISaoma getSaoma(String name) {
return null;
}
}
扫码枪工厂
public class SaomaFactory extends AbStractFactory {
@Override
public IPrint getPrint(String name) {
return null;
}
@Override
public IIdCard getCard(String name) {
return null;
}
@Override
public ISaoma getSaoma(String name) {
if ("Mi".equalsIgnoreCase(name)){
return new MISaoma();
}else if ("HP".equalsIgnoreCase(name)){
return new HPSaoma();
}
return null;
}
}
打印机工厂
public class PrintFactory extends AbStractFactory {
@Override
public IPrint getPrint(String name) {
if ("Mi".equalsIgnoreCase(name)){
return new MiPrint();
}else if ("HP".equalsIgnoreCase(name)){
return new HPPrint();
}
return null;
}
@Override
public IIdCard getCard(String name) {
return null;
}
@Override
public ISaoma getSaoma(String name) {
return null;
}
}
5.3.5 创建一个工厂创造器/生成器类,通过传递参数来获取工厂
public abstract class FactoryProducer {
static AbStractFactory getFactory(String s) {
if ("Card".equalsIgnoreCase(s)){//返回读卡器工厂
return new CardFactory();
}else if ("Print".equalsIgnoreCase(s)){//返回打印机工厂
return new PrintFactory();
}else if ("Saoma".equalsIgnoreCase(s)){//返回扫码枪工厂
return new SaomaFactory();
}
return null;
}
}
5.3.6 使用 FactoryProducer 来获取 AbstractFactory,通过传递类型信息来获取实体类的对象
public class AbstractFactoryPatternDemo {
public static void main(String[] args) {
System.out.println("=============读卡器================");
//获取读卡器工厂
AbStractFactory cardFactory= FactoryProducer.getFactory("Card");
//获取小米读卡器的对象
IIdCard miCard= cardFactory.getCard("Mi");
//调用小米读卡器的 read 方法
miCard.read();
//获取惠普读卡器的对象
IIdCard HPCard= cardFactory.getCard("HP");
//调用惠普读卡器的 read 方法
HPCard.read();
System.out.println("=============扫码枪================");
//获取扫码枪工厂
AbStractFactory saoMaFactory= FactoryProducer.getFactory("SaoMa");
//获取小米读卡器的对象
ISaoma miSaoma= saoMaFactory.getSaoma("Mi");
//调用小米读卡器的 saoma 方法
miSaoma.saoma();
//获取惠普读卡器的对象
ISaoma HPSaoma= saoMaFactory.getSaoma("HP");
//调用惠普读卡器的 read 方法
HPSaoma.saoma();
System.out.println("=============打印机================");
//获取扫码枪工厂
AbStractFactory printFactory= FactoryProducer.getFactory("print");
//获取小米读卡器的对象
IPrint miPrint= printFactory.getPrint("Mi");
//调用小米读卡器的 saoma 方法
miPrint.print();
//获取惠普读卡器的对象
IPrint HPPrint= printFactory.getPrint("HP");
//调用惠普读卡器的 read 方法
HPPrint.print();
}
}
5.3.7 测试结果
最后根据题目的要求,工厂自由组合即可。