抽象工厂(Abstract Factory)模式

抽象工厂(Abstract Factory)模式

隶属类别——对象创建型模式

1. 意图

提供一个创建一系列相关或互相依赖对象的接口,而无需明确指定它们的具体的类

2. 别名

Kit

3. 动机

考虑一组支持多种视感(look-and-feel)标准的用户界面工具包,例如Motif和Presentation Manager。不同的视感风格为诸如滚动条、窗口和按钮等用户界面”窗口组件“定义不同的外观和行为。为保证视感风格标准间的可移植性,一个应用不应该为一个特定的视感外观硬编码它的窗口组件。在整个应用中实例化特定既视感风格窗口组件类将使得以后很难改变视感风格。

为解决这一问题我们可以定义一个抽象的WidgeFactory类,这个类声明了一个用来创建每一个类基本窗口组件的接口。每一类窗口组件都有一个抽象类,而具体子类则实现了窗口组件的特定视感风格。对于每一个抽象窗口组件类,WidgetFactory接口都有一个返回新窗口组件对象的操作。客户调用这些操作以获得窗口组件实例,但客户并不知道他们他们正在使用的是哪些具体类。这样客户就不依赖于一般的视感风格,如下页图所示:

在这里插入图片描述

每一种视感标准都对应一个具体的WidgetFactory子类。每一子类实现那些勇于创建合适视感风格窗口组件的操作。例如,MotifWidgetFactory的CreateScrollBar操作实例化并返回一个Motif滚动条,而相应的PMWidgetFactory操作返回一个Presentation Manager的滚动条。客户仅通过WidgetFactory接口创建组件,它们并不知道哪些类实现了既定视感风格的窗口组件。换言之,客户仅与抽象类定义的接口交互,而不使用特定的具体类的接口。

WidgetFactory也增强了具体窗口组件类之间依赖关系。一个Motif的滚动条应该与Motif按钮、Motif正文编辑器一起使用,这一约束条件作为使用MotifWidgetFactory的结果被自动加上。

4. 适用性

在以下情况可以使用Abstract Factory模式

  • 一个系统要独立于它的产品的创建、组合和表示时
  • 一个系统要由多个产品系列中的一个来配置时
  • 当你要强调一系列相关的产品对象的设计以便进行联合使用时。
  • 当你提供一个产品类库,而只想显示它们的接口而不是实现时

5. 结构

此模式的结果如下图所示:
在这里插入图片描述

6. 参与者

  • AbstractFactory(WidgetFactory)

    ——声明一个创建抽象产品对象的操作接口

  • ConcreteFactory(MotifyWidgetFactorym PMWidgetFactory)

    ——实现创建具体产品的操作

  • AbstractProduct(Window,ScrollBar)

    ——为一类产品对象声明一个接口(并不是指实际接口,而指抽象方法,一个入口)

  • ConcreteProduct(MotifyWindow,MotifScrollBar)

    ——定义一个将被相应的具体工厂创建的产品对象

    ——实现AbstractProduct接口

  • Client

    ——仅使用有AbstractFactory和AbstractProduct类声明的接口。

7. 协作

  • 通常在运行时刻创建ConcreteFactory类的实例。这一具体的工厂创建具有特定实现的产品对象。为创建不同的产品对象,客户应该使用不同的具体工厂。
  • AbstractFactory将产品对象的创建延迟到它的子类ConcreteFactory子类

8. 效果

Abstract Factory模式有下面的一些优点和缺点:

优点:

  • 1.它分离了具体的类 Abstract Factory模式帮助控制一个应用创建的对象的类。因为一个工厂封装创建产品对象的责任和过程,它将客户与类的实现分离。客户通过它们的抽象接口操纵实例。产品的类名也在具体工厂的实现中被分离;它们不出现在客户代码中。
  • 2.它使得易于交换产品系列 一个具体工厂类在一个应用中仅出现一次——即在它初始化的时候,这使得改变一个应用的具体工厂变得很容易。它只需改变具体的工厂即可使用不同的产品配置,这是因为一个抽象工厂创建了一个完整的产品系列,所以整个产品系列会立刻改变。在我们用户界面的例子中,我们仅需转换到相应的工厂对象并重新创建接口,就可实现从Motif窗口组件转换为Presentation Manager窗口组件(例如ConcreteFactory1可以改变为返回ProductB2)。
  • 3.它有利于产品的一致性 当一个系列中的产品对象呗设计成一起工作是,一个应用一次只能使用同一个系列中的对象,这一点很重要,而AbstractFactory很容易实现这一点。

缺点:

  • 难以支持新种类的产品 难以扩展抽象工厂以生产新种类的产品。这是因为Abstract Factory接口确定了可以被创建的产品的集合。支持新种类的产品就需要扩展该工厂接口,这将涉及Abstract Factory类及所有子类的改变。我们会在实现一节讨论这个问题的一个解决办法

9. 实现

下面是实现Abstract Factory模式的一些应该注意的点:

  • 1.将工厂作为单件 一个应用中一般每个产品系列只需要一个ConcreteFactory的实例,因此工厂通常最好实现在一个Singleton。

  • 2.创建产品 Abstract Factory仅声明一个创建产品的接口,真正创建产品是由ConcreteProduct子类实现的。最通常的一个办法是为每一个产品定义一个工厂方法。一个具体的工厂将为每个产品重定义该工厂方法以指定产品。虽然这样的实现很简单,但他却要求每个产品系列都要有一个新的具体工厂子类,即使这些产品系列的差别很小。

    如果有多个可能的产品系列。具体工厂也可以使用Prototype来实现。具体工厂使用产品系列中的每一个产品的原型实例来初始化,且它通过复杂它的原型来创建新的产品。在基于原型的方法中,使得不是每个新的产品系列都需要一个新的具体工厂类。具体的Java例子 ?

  • 3.定义可扩展的工厂 Abstract Factory通常为每一个它可以生产的产品定义一个操作。产品的种类被编码在操作型构中。增加一种新的产品要求编码AbtractFactory的接口以及所有与它相关的类。一个更灵活但不太安全的设计是给创建对象的操作增加一个参数。该参数指指定了将被创建的对象的种类。它可以是一个类标识符、一个整数、一个字符串,或其他任何可以标识这种产品的东西。实际上使用这种方法,Abstract Factory只需要一个”Make“操作和一个指示要创建对象的种类的参数。这是前面已经讨论过的基于原型的和基于类的抽象工厂的抽象工厂的技术。

    与C++这样的静态类型语言相比,这一变化容易用在类似于Smalltalk这样的动态类型言语中。仅当所有的对象都有相同的抽象基类,或者当产品对象可以被请求它们的客户安全的强制转换成正确的类型时,你才能在C++中使用它,Factory的实现部分说明了怎么样在C++实现这样的参数化操作。

    该方法即使不需要类型强制转化,但仍有一个本质的问题:所有的产品将返回类型所给定的相同的抽象接口返回给客户。客户将不能区分或者对一个产品的类别进行安全的假定。如果一个客户需要进行与特定子类相关的操作,而这个操作却不能通过抽象接口得到。虽然客户可以实施一个向下类型转化(例如在C++中用dynamic_cast),但这并不总是可行或安全的,因为向下类型转化可能会失败。这个是一个典型的高度灵活和可扩展接口的权衡折衷。

10. 代码示例

首先是创建AbstractFactory——PizzaIngredientFactory.java

public interface PizzaIngredientFactory {
   
	
	public Dough createDough();
	public Sauce createSauce();
	public Cheese createCheese();
	public Veggies[] createVeggies();
	public Pepperoni createPepperoni();
	public Clams createClam();
}

上述提到对具体工厂使用单例,有利于节省成本,当下比较好用的单例应该是其他开发者在stackoverflow向我推荐的使用Enum作为单例,并且在某些需要同步的方法上使用Synchronized关键字

ConcreteFactory——ChicagoPizzaIngredientFactory.java & ChicagoPizzaIngredientFactory.java

ChicagoPizzaIngredientFactory.java

public enum ChicagoPizzaIngredientFactory implements PizzaIngredientFactory {
   
	CHICAGO_FACTORY_INSTANCE;
	
	@Override
	public synchronized Dough createDough() {
   
		return new ThickCrustDough()
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1) 优秀的程序应该是这样的:阅读时,感觉很优雅;新增功能时,感觉很轻松;运行时,感觉很快速,这就需要设计模式支撑。2) 设计模式包含了大量的编程思想,讲授和真正掌握并不容易,网上的设计模式课程不少,大多讲解的比较晦涩,没有真实的应用场景和框架源码支撑,学习后,只知其形,不知其神。就会造成这样结果: 知道各种设计模式,但是不知道怎么使用到真实项目。本课程针对上述问题,有针对性的进行了升级 (1) 授课方式采用 图解+框架源码分析的方式,让课程生动有趣好理解 (2) 系统全面的讲解了设计模式,包括 设计模式七大原则、UML类图-类的六大关系、23种设计模式及其分类,比如 单例模式的8种实现方式、工厂模式的3种实现方式、适配器模式的3种实现、代理模式的3种方式、深拷贝等3) 如果你想写出规范、漂亮的程序,就花时间来学习下设计模式吧课程内容和目标本课程是使用Java来讲解设计模式,考虑到设计模式比较抽象,授课采用 图解+框架源码分析的方式1) 内容包括: 设计模式七大原则(单一职责、接口隔离、依赖倒转、里氏替换、开闭原则、迪米特法则、合成复用)、UML类图(类的依赖、泛化和实现、类的关联、聚合和组合) 23种设计模式包括:创建型模式:单例模式(8种实现)、抽象工厂模式、原型模式、建造者模式、工厂模式。结构型模式:适配器模式(3种实现)、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模式(3种实现)。行为型模式:模版方法模式、命令模式、访问者模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式(Interpreter模式)、状态模式、策略模式、职责链模式(责任链模式)2) 学习目标:通过学习,学员能掌握主流设计模式,规范编程风格,提高优化程序结构和效率的能力。
### 回答1: Abstract Factory 模式是一种创建型设计模式,它提供了一种创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。这个模式的主要目的是将客户端代码与具体类的创建分离,从而使客户端代码能够与抽象接口进行交互,而不是与具体实现进行交互。 ### 回答2: Abstract Factory 模式是一种软件设计模式,它提供了一种创建相关或依赖对象族的方法。它属于创建型模式的一种。 Abstract Factory 模式的核心思想是将具体对象的实例化操作封装到接口中,由工厂类来创建这些实例。这样可以隐藏对象的具体实现细节,使得系统更加灵活、可扩展和易于维护。 在 Abstract Factory 模式中,有四个角色: 1. 抽象工厂Abstract Factory):定义了一系列创建抽象产品对象的方法,所有具体工厂类必须实现这些方法。 2. 具体工厂(Concrete Factory):实现了抽象工厂中定义的创建产品对象的方法,返回具体产品的实例。 3. 抽象产品(Abstract Product):定义了产品对象的通用接口,具体产品类必须实现这些接口。 4. 具体产品(Concrete Product):实现了抽象产品中定义的接口,是具体工厂创建的对象。 Abstract Factory模式是工厂方法模式的升级版,它在产品族的维度上进行了扩展。工厂方法模式只能创建单一类型的产品,而Abstract Factory模式能创建多个类型的产品。这使得Abstract Factory模式更加符合开闭原则,可以方便地扩展新的产品系列。 使用Abstract Factory模式可以将产品的创建和使用解耦,客户端只需要通过抽象接口来获取产品,不用关心具体的实现。同时,具体工厂负责创建产品,符合单一职责原则,提高了代码的可读性和可维护性。 总之,Abstract Factory模式提供了一种抽象的方式来创建相关的对象族,可以有效地降低系统的耦合性,提高系统的灵活性和可扩展性。但是它也增加了系统的复杂性,因此在设计系统时需要权衡利弊。 ### 回答3: Abstract Factory 模式是一种创建型设计模式,它提供了一种创建一系列相关或依赖对象的方法。它通过提供一个接口来创建一组相关的对象,而无需指定具体的类。 在 Abstract Factory 模式中,有一个抽象工厂类,它定义了创建对象的方法。具体的工厂类继承自抽象工厂类,并实现了其中的方法,用于创建具体的对象。每个具体工厂类创建一组相关的对象,这些对象在抽象工厂类中定义的接口下进行操作。 Abstract Factory 模式的最大优势是将客户端代码与具体类解耦,使得具体类的变化不会影响到客户端代码。客户端通过使用抽象工厂类和抽象产品类进行编程,而不是直接依赖于具体的对象。这样,如果需要更换一套创建对象的逻辑,只需要更换具体的工厂类即可,而无需修改客户端代码。这种灵活性使得 Abstract Factory 模式非常适合多对象产品系列的创建。 Abstract Factory 模式还可以保证创建的对象相互之间有关联,从而保持了系统的一致性。在具体工厂类中,只会创建相关的对象,并确保这些对象是一起工作的,它们之间有相互依赖关系。因此,使用 Abstract Factory 模式可以确保一组对象能够协同工作,实现系统的完整功能。 总而言之,Abstract Factory 模式通过提供一个接口来创建一组相关的对象,使得客户端代码与具体类解耦,并保持对象之间的关联。它能够提供灵活性和扩展性,适用于多对象产品系列的创建。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值