Gof23种设计模式(2)——抽象工厂模式(Abstract Factory)

2020年8月6日13:41:49 评论 67

1 基础知识

1.1 标准定义

抽象工厂模式标准定义:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。

1.2 分析和说明

抽象工厂模式是一个创建性的模式。与工厂方法模式一样,它要求工厂类和产品类分开。但是核心工厂类不再负责所有产品的创建,而是将具体创建的工作交给子类去做,成为一个抽象工厂角色,仅负责给出具体工厂类必须实现的接口,而不接触哪一个产品类应当被实例化这种细节。一个具体的工厂类负责创建产品族中的各个产品。其实质就是由1个工厂类层次、N个产品类层次和N×M个产品组成。

Gof23种设计模式(2)——抽象工厂模式(Abstract Factory)

图1 抽象工厂结构

Abstract Factory结构如图1所示。抽象工厂模式包括四个角色:抽象工厂角色;具体工厂类角色;抽象产品角色和具体产品角色。分别描述如下。

抽象工厂(Abstract Factory)角色:担任这个角色的是工厂方法模式的核心,它是与应用系统的商业逻辑无关的。通常使用接口或者抽象类实现,而所有的具体工厂类必须实现这个接口或继承这个抽象类。

具体工厂类(Concrete Factory)角色:这个角色直接在客户端的调用下创建产品的实例。这个角色含有选择合适的产品对象的逻辑,而这个逻辑是与应用系统的商业逻辑紧密相关的。实际应用中使用具体类来实现这个角色。

抽象产品(Abstract Product)角色:担任这个角色的类是工厂方法模式所创建的对象的父类,或它们共同拥有的接口。通常使用接口或者抽象类来实现这一角色。

具体产品(Concrete Product)角色:抽象工厂模式所创建的任何产品对象都是某一个具体产品类的实例。这是客户端最终需要的东西,其内部一定充满了应用系统的商业逻辑。实际应用中使用具体类来实现这个角色。

2 应用场景举例

比如几家公司同时能生产计算机和电话。但是计算机系列包括PC机、笔记本电脑和服务器。电话系列包括座机电话和手机。对于这种情况就可以采用抽象工厂模式。其业务用例图见图3。

Gof23种设计模式(2)——抽象工厂模式(Abstract Factory)

图2 抽象工厂模式的用例图

在这里可以把Company理解为抽象工厂(Abstract Factory)角色。CompanyA和CompanyB是具体工厂(Concrete Creator)角色。Computer和Telephone是两类不同的抽象产品(Product)角色。NotebookComputer和PersonalComputer是基于Computer抽象产品的具体产品(Concrete Product)角色。DesktopPhone和Mobile是基于Telephone抽象产品的具体产品(Concrete Product)角色。其实现类图如图3所示。

Gof23种设计模式(2)——抽象工厂模式(Abstract Factory)

图3 抽象工厂模式的类图

抽象工厂模式实现的顺序图如图4所示,其实现步骤描述:
①创建一个Company1对象;
②调用Company1对象buildProduct方法,实际上从Company1对象创建一个Computer产品,为PersonalComputer对象。
③对PersonalComputer对象采取doUse方法;
④⑤与②③步骤一样,不过产生的是NotebookComputer对象。
⑥调用Company1对象buildProduct方法,实际上从Company1对象创建一个Telephone产品,为DesktopPhone对象。
⑦对DesktopPhone对象采取doUse方法;
⑧⑨与⑥⑦步骤一样,不过产生的是Mobile对象。

Gof23种设计模式(2)——抽象工厂模式(Abstract Factory)

图4 抽象工厂模式实现顺序图

3.Java的实现程序代码

Java程序实现主要包括Company接口文件,Computer抽象类文件,Telephone抽象类文件,CompanyA类文件,CompanyB类文件,Mobile类文件、DesktopPhone类文件、NotebookComputer类文件和PersonalComputer类文件等9个文件。其关系如图3所示。下面分别列出这9个文件的程序代码,最后列出测试代码并显示输出结果。

Company属于抽象工厂(Abstract Factory)角色,Company的接口程序代码清单01所示。

程序代码清单01

public interface Company {
    public Computer bulidComputer(String Parameter);
    public Telephone bulidTelephone(String Parameter);
}

Computer抽象类和Telephone抽象类属于抽象产品(Abstract Product)角色,Computer和Telephone抽象类程序代码清单02所示。

程序代码清单02

public abstract class Computer {
    public void doUse(){}
}
public abstract class Telephone {
    public void doUse(){}
}

CompanyA类和CompanyB类属于具体工厂类(Concrete Factory)角色,CompanyA类和CompanyB类程序代码清单03所示。

程序代码清单03

public class CompanyA implements Company{

    public Computer bulidComputer(String Parameter){
         if (Parameter.equals("个人电脑")) {
              return new PersonalComputer();
         } else if (Parameter.equals("笔记本电脑")) {
              return new NotebookComputer();
         } else {
              return null;
         }
    }

    public Telephone bulidTelephone(String Parameter){
         if (Parameter.equals("座机电话")) {
             return new DesktopPhone();
         } else if (Parameter.equals("手机")) {
             return new Mobile();
         } else {
             return null;
         }
    }

}

public class CompanyB implements Company{

    public Computer bulidComputer(String Parameter){
        if (Parameter.equals("个人电脑")) {
            return new PersonalComputer();
        } else if (Parameter.equals("笔记本电脑")) {
            return new NotebookComputer();
        } else {
            return null;
        }
    }

    public Telephone bulidTelephone(String Parameter){
        if (Parameter.equals("座机")) {
            return new DesktopPhone();
        } else if (Parameter.equals("手机")) {
            return new Mobile();
        } else {
            return null;
        }
    }

}

Mobile类和DesktopPhone类属于具体产品(Concrete Product)角色,Mobile类和DesktopPhone类程序代码清单04所示。

程序代码清单04

public class Mobile extends Telephone {
	public void doUse() {
		System.out.println("这是手机的功能");
	}
}

public class DesktopPhone extends Telephone {
	public void doUse() {
		System.out.println("这是座机电话的功能");
	}
}

NotebookComputer类和PersonalComputer类属于具体产品(Concrete Product)角色,NotebookComputer类和PersonalComputer类程序代码清单05所示。

程序代码清单05

public class NotebookComputer extends Computer {
	public void doUse() {
		System.out.println("这是笔记本电脑的功能");
	}
}

public class PersonalComputer extends Computer {
	public void doUse() {
		System.out.println("这是个人计算机的功能");
	}
}

抽象工厂模式测试程序的代码清单06如下:

程序代码清单06

public class Client {

	public static void main(String[] args) {

		Company company1 = new CompanyA();
		Computer computer1 = company1.bulidComputer("个人电脑");
		computer1.doUse();

		Computer computer2 = company1.bulidComputer("笔记本电脑");
		computer2.doUse();

		Telephone telephone1 = company1.bulidTelephone("座机电话");
		telephone1.doUse();

		Telephone telephone2 = company1.bulidTelephone("手机");
		telephone2.doUse();
	}
}

抽象工厂模式测试类输出结果如下所示:

这是个人计算机的功能
这是笔记本电脑的功能
这是座机电话的功能
这是手机的功能

4 扩展和说明

抽象工厂模式也是应用比较广泛的设计模式。对于抽象工厂模式,从两个层次上进行扩展。

一种是从抽象工厂中继承出来的具体工厂。即上述场景中的CompanyA,CompanyB,可以根据情况在增加CompanyC、CompanyD等。

一种是对产品进行扩充。可以增加一个产品类族,如计算机、手机、再增加电视机等。还有一种是增加具体的产品。如计算机下面还可以增加服务器等。


参考链接

5种创建型模式:

Gof23种设计模式(1)——工厂模式(Factory Method)
Gof23种设计模式(2)——抽象工厂模式(Abstract Factory)
Gof23种设计模式(3)——建造模式(Builder)
Gof23种设计模式(4)——原型模式(Prototype)
Gof23种设计模式(5)——单例模式(Singleton)
Gof23种设计模式 —— 创建型模式总结和比较

回到总目录Gof23种设计模式(全解析)

(转载自微信公众号:架构设计模式)

素课网
  • 本文由 发表于 2020年8月6日13:41:49
  • 转载请注明:https://www.suketech.com/8794.html
设计模式:面向对象设计的六大原则 - 总结 设计模式

设计模式:面向对象设计的六大原则 – 总结

开闭原则是面向对象设计中最基础的设计原则,它指导我们如何建立稳定灵活的系统。开闭原则可能是设计模式六项原则中定义最模糊的一个了,它只告诉我们对扩展开放,对修改关闭,可是到底如何才能做到对扩展开放,对修...
匿名

发表评论

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: