出自:http://www.cnblogs.com/libingql/archive/2012/12/09/2809754.html

1. 抽象工厂模式简介

1.1 定义

  抽象工厂(Abstract Factory)模式意图:为创建一组相关或相互依赖对象提供了一个接口,而且无需指定它们的具体类。

  抽象工厂可以向客户提供一个接口,是客户可以在不必指定产品具体类型的情况下,创建多个产品家族中的产品对象,它强调的“系列对象”的变化。

1.2 使用频率

   高

2. 抽象工厂模式结构

2.1 结构图

2.2 参与者

  抽象工厂模式参与者:

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

  ◊ ConcreteFactory:实现创建具体产品对象的操作

  ◊ AbstractProduct:声明一类产品对象接口

  ◊ Product

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

    °实现AbstractProduct接口

  ◊ Client:使用AbstractFactory和AbstractProduct类声明的接口

  在抽象工厂模式中,产品的创建由ConcreteFactory来完成,从结构图中可以看出,抽象工厂模式的ConcreteFactory不是负责一种具体Product的创建,而是负责一个Product族的创建。

3. 抽象工厂模式结构实现

  AbstractProductA.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace DesignPatterns.AbstractFactoryPattern.Structural
{
public abstract class AbstractProductA
{
}
}

  AbstractProductB.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace DesignPatterns.AbstractFactoryPattern.Structural
{
public abstract class AbstractProductB
{
public abstract void Interact(AbstractProductA a);
}
}

  ProductA1.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace DesignPatterns.AbstractFactoryPattern.Structural
{
public class ProductA1 : AbstractProductA
{
}
}

  ProductB1.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace DesignPatterns.AbstractFactoryPattern.Structural
{
public class ProductB1 : AbstractProductB
{
public override void Interact(AbstractProductA a)
{
Console.WriteLine(this.GetType().Name + " interacts with " + a.GetType().Name);
}
}
}

  ProductA2.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace DesignPatterns.AbstractFactoryPattern.Structural
{
public class ProductA2 : AbstractProductA
{
}
}

  ProductB2.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace DesignPatterns.AbstractFactoryPattern.Structural
{
public class ProductB2 : AbstractProductB
{
public override void Interact(AbstractProductA a)
{
Console.WriteLine(this.GetType().Name + " interacts with " + a.GetType().Name);
}
}
}

  ConcreteFactory1.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace DesignPatterns.AbstractFactoryPattern.Structural
{
public class ConcreteFactory1 : AbstractFactory
{
public override AbstractProductA CreateProductA()
{
return new ProductA1();
} public override AbstractProductB CreateProductB()
{
return new ProductB1();
}
}
}

  ConcreteFactory2.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace DesignPatterns.AbstractFactoryPattern.Structural
{
public class ConcreteFactory2 : AbstractFactory
{
public override AbstractProductA CreateProductA()
{
return new ProductA2();
} public override AbstractProductB CreateProductB()
{
return new ProductB2();
}
}
}

  AbstractFactory.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace DesignPatterns.AbstractFactoryPattern.Structural
{
public abstract class AbstractFactory
{
public abstract AbstractProductA CreateProductA(); public abstract AbstractProductB CreateProductB();
}
}

  Client.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace DesignPatterns.AbstractFactoryPattern.Structural
{
public class Client
{
private AbstractProductA _abstractProductA;
private AbstractProductB _abstractProductB; public Client(AbstractFactory factory)
{
_abstractProductB = factory.CreateProductB();
_abstractProductA = factory.CreateProductA();
} public void Run()
{
_abstractProductB.Interact(_abstractProductA);
}
}
}

  Program.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; using DesignPatterns.AbstractFactoryPattern.Structural; namespace DesignPatterns.AbstractFactoryPattern
{
class Program
{
static void Main(string[] args)
{
// Abstract factory #1
AbstractFactory factory1 = new ConcreteFactory1();
Client client1 = new Client(factory1);
client1.Run(); // Abstract factory #2
AbstractFactory factory2 = new ConcreteFactory2();
Client client2 = new Client(factory2);
client2.Run(); // Wait for user input
Console.ReadKey();
}
}
}

  运行输出:

ProductB1 interacts with ProductA1
ProductB2 interacts with ProductA2
请按任意键继续. . .

4. 抽象工厂模式实践应用

  以KFC为例阐述抽象工厂模式的应用,假设现在KFC的食品直接没有任何关联,不可以分类,各个Product相互独立。这样工厂方法模式就可以很好解决,定义一系列的简单工厂,用户没要求一种食品就使用一个合适的简单工厂来生产相应的Product就可以。

  但实际情况下,KFC的产品还可以进行套餐出售,假设KFC的产品可以分为食品Food和饮料Drink,Food和Drink分别构成了一个产品族,一个产品族就是一系列相似对象的抽象。KFC出售2种套餐,一种是经济型,包括鸡翅和可乐;另一种是豪华型,包括鸡腿和咖啡。用户只需要指出需要的套餐名即可获得相应的Food和Drink。这种情况下,工厂方法模式将不再适用,而采用抽象工厂模式进行实现。

  KFCFood.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace DesignPatterns.AbstractFactoryPattern.Practical
{
/// <summary>
/// Product族1,KFC食品
/// </summary>
public abstract class KFCFood
{
public abstract void Display();
}
}

  Chicken.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace DesignPatterns.AbstractFactoryPattern.Practical
{
public class Chicken : KFCFood
{
public override void Display()
{
Console.WriteLine("鸡腿 + 1");
}
}
}

  Wings.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace DesignPatterns.AbstractFactoryPattern.Practical
{
public class Wings : KFCFood
{
public override void Display()
{
Console.WriteLine("鸡翅 + 1");
}
}
}

  KFCDrink.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace DesignPatterns.AbstractFactoryPattern.Practical
{
/// <summary>
/// Product族2,KFC饮料
/// </summary>
public abstract class KFCDrink
{
public abstract void Display();
}
}

  Coke.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace DesignPatterns.AbstractFactoryPattern.Practical
{
public class Coke : KFCDrink
{
public override void Display()
{
Console.WriteLine("可乐 + 1");
}
}
}

  Coffee.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace DesignPatterns.AbstractFactoryPattern.Practical
{
public class Coffee : KFCDrink
{
public override void Display()
{
Console.WriteLine("咖啡 + 1");
}
}
}

  IKFCFactory.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace DesignPatterns.AbstractFactoryPattern.Practical
{
/// <summary>
/// 抽象工厂,生产套餐
/// </summary>
public interface IKFCFactory
{
KFCFood CreateFood();
KFCDrink CreateDrink();
}
}

  CheapPackageFactory.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace DesignPatterns.AbstractFactoryPattern.Practical
{
/// <summary>
/// 经济型套餐,包括鸡翅和可乐
/// </summary>
public class CheapPackageFactory : IKFCFactory
{
public KFCFood CreateFood()
{
return new Wings();
}
public KFCDrink CreateDrink()
{
return new Coke();
}
}
}

  LuxuryPackageFactory.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace DesignPatterns.AbstractFactoryPattern.Practical
{
/// <summary>
/// 豪华型套餐,包括鸡腿和咖啡
/// </summary>
public class LuxuryPackageFactory : IKFCFactory
{
public KFCFood CreateFood()
{
return new Chicken();
} public KFCDrink CreateDrink()
{
return new Coffee();
}
}
}

  Program.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; using DesignPatterns.AbstractFactoryPattern.Practical; namespace DesignPatterns.AbstractFactoryPattern
{
class Program
{
static void Main(string[] args)
{
IKFCFactory factory = new CheapPackageFactory();
KFCFood food = factory.CreateFood();
food.Display(); KFCDrink drink = factory.CreateDrink();
drink.Display();
}
}
}

  运行输出:

鸡翅 + 1
可乐 + 1
请按任意键继续. . .

5. 抽象工厂模式应用分析

5.1 抽象工厂模式适用情形

  ◊ 同一个产品族的Product在一起使用时,而且它们之间是相互依赖的,不可分离

  ◊ 系统需要由相互关联的多个对象来构成

  ◊ 当想提供一组对象而不显示它们的实现过程,只显示它们的接口

  ◊ 系统不应当依赖一些具体Product类

5.2 抽象工厂模式的特点

  ◊ 隔离了具体类的生成,客户不需要知道怎样生成每一个具体Product,什么时间生成的。它将客户与具体的类分离,依赖于抽象类,耦合性低。

  ◊ 一个产品族中的多个对象设计成一起工作,它能保证客户端始终只使用一个产品族中的对象。这对一些需要根据当前环境来决定其行为的软件系统来说是非常实用的一种设计模式。

  ◊ 有利于更换产品系列,由于客户端只依赖于抽象类,更换产品系列时,只需要更改一下具体工厂名就可以。

  ◊ 难以支持新种类的产品,这是因为抽象工厂接口确定了可以被创建的产品集合,支持新种类的产品就需要扩展该工厂接口,这将引起抽象工厂类及其所有子类的改变。

5.3 抽象工厂模式与工厂方法模式区别

  ◊ 工厂方法模式只有一个抽象产品类,而抽象工厂模式可以有多个抽象产品类。

  ◊ 工厂方法模式针对一个产品等级结构,可以派生出多个具体产品类;抽象工厂模式针对面向多个产品等级结构,每个抽象产品类可以派生出多个具体产品类。

C#设计模式系列:抽象工厂模式(AbstractFactory)的更多相关文章

  1. Java设计模式系列-抽象工厂模式

    原创文章,转载请标注出处:https://www.cnblogs.com/V1haoge/p/10755412.html 一.概述 抽象工厂模式是对工厂方法模式的再升级,但是二者面对的场景稍显差别. ...

  2. 乐在其中设计模式(C#) - 抽象工厂模式(Abstract Factory Pattern)

    原文:乐在其中设计模式(C#) - 抽象工厂模式(Abstract Factory Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 抽象工厂模式(Abstract Factor ...

  3. Java 设计模式之抽象工厂模式(三)

    原文地址:Java 设计模式之抽象工厂模式(三) 博客地址:http://www.extlight.com 一.前言 上篇文章 <Java 设计模式之工厂模式(二)>,介绍了简单工厂模式和 ...

  4. C#设计模式之四抽象工厂模式(AbstractFactory)【创建型】

    一.引言     写了3篇有关设计模式的文章了,大家有了些反馈,说能从中学到一些东西,我感到很欣慰,那就继续努力.今天我要写第四个模式了,该模式叫抽象工厂.上一篇文章我们讲了[工厂方法]模式,它是为了 ...

  5. C#设计模式之三抽象工厂模式(AbstractFactory)【创建型】

    一.引言 写了3篇有关设计模式的文章了,大家有了些反馈,说能从中学到一些东西,我感到很欣慰,那就继续努力.今天我要写第四个模式了,该模式叫抽象工厂.上一篇文章我们讲了[工厂方法]模式,它是为了解决[简 ...

  6. Java设计模式系列之工厂模式

    工厂模式将大量有共同接口的类实例化,工厂模式可以实现动态决定实例化哪一个类的对象,工厂模式在<Java与模式>中分为三类:1)简单工厂模式(Simple Factory):添加某一种类型的 ...

  7. C#设计模式(4)-抽象工厂模式

    引言 上一篇介绍了设计模式中的简单工厂模式-C#设计模式(3)-工厂方法模式,本篇将介绍抽象工厂模式: 抽象工厂模式简介 抽象工厂模式(AbstractFactory):提供一个创建一系列相关或相互依 ...

  8. Head First设计模式之抽象工厂模式

    一.定义 给客户端提供一个接口,可以创建多个产品族中的产品对象 ,而且使用抽象工厂模式还要满足一下条件:     1)系统中有多个产品族,而系统一次只可能消费其中一族产品.      2)同属于同一个 ...

  9. 【设计模式】抽象工厂模式 Abstract Factory Pattern

    简单工厂模式是一个工厂类根据工厂方法的参数创建不出不同的产品, 工厂方法模式是每一个产品都有一个一一对应的工厂负责创建该产品.那么今天要讲的抽象工厂模式是一个工厂能够产生关联的一系列产品.抽象工厂模式 ...

  10. Java 设计模式之抽象工厂模式

    抽象工厂模式(Abstract Factory Pattern)是围绕一个超级工厂创建其他工厂.该超级工厂又称为其他工厂的工厂.这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式. 在抽 ...

随机推荐

  1. PairRDD中算子aggregateByKey图解

    PairRDD 有几个比较麻烦的算子,常理解了后面又忘记了,自己按照自己的理解记录好,以备查阅 1.aggregateByKey aggregate 是聚合意思,直观理解就是按照Key进行聚合. 转化 ...

  2. UBoot启动代码第一阶段流程

    http://blog.csdn.net/xautfengzi/article/details/7470134 前段时间了看了UBoot的源码,放了一段时间之后忘得差不多了.现做一些注释,方便以后温习 ...

  3. 安卓手机数据恢复软件-DiskDigger Pro

    以前的手机是支持大容量存储模式,可以被分配到盘符,但是自从手机不支持U盘大容量存储模式只能MTP模式之后,想要做数据恢复麻烦了很多啊! 经过多方查找,终于找到了这个能在手机上用的软件DiskDigge ...

  4. LeetCode: Sort Colors 解题报告

    Sort ColorsGiven an array with n objects colored red, white or blue, sort them so that objects of th ...

  5. Ubuntu设置root密码

    最初使用系统时,只有当前管理员的密码,root密码为随机生成的. 通过 sudo passwd 设置root密码,然后su获得root,也就是最高权限

  6. ios开发之修改 UITableview 滚动条颜色的方法

    UITableview 的滚动条默认颜色是黑色的,如果 UItableview 背景也是深颜色,则滚动条会变的很不明显.您可以用下面这行代码来改变滚动条的颜色 self.tableView.indic ...

  7. JDBC 查询的三大参数 setFetchSize prepareStatement(String sql, int resultSetType, int resultSetConcur)

    JDBC 查询的三大参数 本文转载至 http://blog.csdn.net/turkeyzhou/article/details/5115228 DBC1.0 .JDBC2.0 .JDBC3.0  ...

  8. linux异步通知

    简述 linux下异步方式有两种:异步通知和异步IO(AIO),aio请参考:linux异步IO--aio 异步通知的含义是:一旦设备就绪,则主动通知应用程序,这样应用程序就不需要查询设备状态,准确称 ...

  9. hdu2222 KeyWords Search AC自动机入门题

    /** 链接:http://acm.hdu.edu.cn/showproblem.php?pid=2222 题意:题意:给定N(N <= 10000)个长度不大于50的模式串,再给定一个长度为L ...

  10. 【C】——压缩字符串

    编一个函数,输入一个字符串,要求做一个新字符串,把其中所有的一个或多个连续的空白字符都压缩为一个空格.这里所说的空白包括空格.'\t'.'\n'.'\r'.例如原来的字符串是: This Conten ...