zoukankan      html  css  js  c++  java
  • 设计模式之抽象工厂模式

      工厂模式属于创建型设计模式,它提供了一种创建对象的最佳方式。

      抽象工厂模式是工厂方法模式的升级版,是所有形态的工厂模式中最为抽象和最具一般性的一种形态。

      定义:为创建一组相关或相互依赖的对象提供一个接口,而且无需指定它们的具体类。

      问题描述:使用工厂方法模式,产品类和工厂类一一对应,当种类过多的时候,将不利于系统的维护。

      解决方案:使用一个抽象工厂来定义一个产品族,前提是这些产品必须存在相关或者相互依赖的关系。

      结构图

      说明

      (1)抽象产品类(IProduct):抽象工厂模式中至少包含一个抽象产品类,每个抽象产品类派生出一个产品结构,定义了该产品结构中所有派生类的公开方法,方便于该产品的扩展;

      (2)具体产品类:实现其对应的抽象产品类定义的方法;

      (3)抽象工厂类(IFactory):声明了一组用于创建一个产品族的方法;

      (4)具体工厂类:每个具体工厂类不再仅仅创建一个产品,而是由抽象工厂类定义的创建多个产品。

      每一个模式都是针对一定问题的解决方案。工厂方法模式针对的是一个产品等级结构,而抽象工厂模式针对的是多个产品等级结构。

      举个栗子:我喜欢养狗和猫,我养了两条狗,唤做黑黑和白白,还养了两只猫,唤做喵喵和呜呜,狗爱吃骨头,猫爱吃鱼。

      根据抽象工厂模式的思想,我们这样来实现功能:

      1. 两个抽象产品类:IDog和ICat,均定义两个方法introduce()和eatFood()。代码如下:

             

             

      2. 具体产品类BlackDog和WhiteDog实现接口IDog。代码如下:

             

             

      3. 具体产品类BlackCat和WhiteCat实现接口ICat。代码如下:

             

             

      4. 一个抽象工厂类:AnimalFactory,声明一组用于创建一个产品族的方法(keepDog()和keepCat()),白狗和白猫、黑狗和黑猫。代码如下:

             

      5. 两个具体工厂类:WhiteAnimalFactory()和BlackAnimalFactory(),前者负责生产白狗和白猫,后者负责生产黑狗和黑猫。代码如下:

              

             

      6. 在类AbstractFactoryFragment中分别使用不同的工厂类生产出不同的多个产品对象,实现功能。代码如下:

             

      7. 运行后的效果,如图所示:

             

      综上所述,工厂方法可以看作是特殊情况下的抽象工厂,即只包含一个产品结构,每个产品族只有一个产品。抽象工厂模式也符合开闭原则,新增一个产品族时,仅需要增加具体的产品族和具体的工厂类。如果需要更改产品结构,那么就要去修改所有的工厂类,对扩展造成一定的难度。

      优点

      (1)隔离了具体的类,并隐藏了一个产品族中产品的关联关系。如果要更改产品族,只要更换到对应的具体工厂上即可;

      (2)有利于产品的一致性;

      (3)新增一个产品族,无需更改原有的代码,符合开闭原则。

      缺点:产品结构无法扩展,一旦扩展需要对原有的代码进行较大的修改,甚至需要修改抽象层代码。

      使用场景

      (1)产品类型较多,但它们之间存在相关或互相依赖的关系,可以形成产品族类,且使用者不需要去关心产品对象如何创建、组合和表达的细节;

      (2)系统的产品至少有一个产品族,而使用者只需要消费其中某一族的产品;

      (3)产品等级结构稳定,后期不会出现结构上的更改。

      总结:无论是简单工厂模式,工厂方法模式,还是抽象工厂模式,它们都属于工厂模式,最终的目的都是为了接耦,它们的使用方式都十分相似,可以相互转换,灵活演变,我们无需关心究竟使用哪种模式来实现,只要关心是否降低了耦合度就可以了。

  • 相关阅读:
    使用Modelsim对Nios II系统进行系统级仿真
    电视相关知识学习
    SAD和SATD的区别[摘]
    vim自动补全括号的最好方法
    vim sinppets插件介绍
    在centos下安装开发环境
    初始化以及动态设置Edit控件的背景及字体颜色
    CTreeCtrl SetItemData 释放问题
    C#4.0 新特性 匿名方法,lambds
    对象序列化Serialization与Deserialize方法进行反序列化
  • 原文地址:https://www.cnblogs.com/chenxkang/p/6691053.html
Copyright © 2011-2022 走看看