C#设计模式系列:抽象工厂模式(AbstractFactory)
出自: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)的更多相关文章
- Java设计模式系列-抽象工厂模式
原创文章,转载请标注出处:https://www.cnblogs.com/V1haoge/p/10755412.html 一.概述 抽象工厂模式是对工厂方法模式的再升级,但是二者面对的场景稍显差别. ...
- 乐在其中设计模式(C#) - 抽象工厂模式(Abstract Factory Pattern)
原文:乐在其中设计模式(C#) - 抽象工厂模式(Abstract Factory Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 抽象工厂模式(Abstract Factor ...
- Java 设计模式之抽象工厂模式(三)
原文地址:Java 设计模式之抽象工厂模式(三) 博客地址:http://www.extlight.com 一.前言 上篇文章 <Java 设计模式之工厂模式(二)>,介绍了简单工厂模式和 ...
- C#设计模式之四抽象工厂模式(AbstractFactory)【创建型】
一.引言 写了3篇有关设计模式的文章了,大家有了些反馈,说能从中学到一些东西,我感到很欣慰,那就继续努力.今天我要写第四个模式了,该模式叫抽象工厂.上一篇文章我们讲了[工厂方法]模式,它是为了 ...
- C#设计模式之三抽象工厂模式(AbstractFactory)【创建型】
一.引言 写了3篇有关设计模式的文章了,大家有了些反馈,说能从中学到一些东西,我感到很欣慰,那就继续努力.今天我要写第四个模式了,该模式叫抽象工厂.上一篇文章我们讲了[工厂方法]模式,它是为了解决[简 ...
- Java设计模式系列之工厂模式
工厂模式将大量有共同接口的类实例化,工厂模式可以实现动态决定实例化哪一个类的对象,工厂模式在<Java与模式>中分为三类:1)简单工厂模式(Simple Factory):添加某一种类型的 ...
- C#设计模式(4)-抽象工厂模式
引言 上一篇介绍了设计模式中的简单工厂模式-C#设计模式(3)-工厂方法模式,本篇将介绍抽象工厂模式: 抽象工厂模式简介 抽象工厂模式(AbstractFactory):提供一个创建一系列相关或相互依 ...
- Head First设计模式之抽象工厂模式
一.定义 给客户端提供一个接口,可以创建多个产品族中的产品对象 ,而且使用抽象工厂模式还要满足一下条件: 1)系统中有多个产品族,而系统一次只可能消费其中一族产品. 2)同属于同一个 ...
- 【设计模式】抽象工厂模式 Abstract Factory Pattern
简单工厂模式是一个工厂类根据工厂方法的参数创建不出不同的产品, 工厂方法模式是每一个产品都有一个一一对应的工厂负责创建该产品.那么今天要讲的抽象工厂模式是一个工厂能够产生关联的一系列产品.抽象工厂模式 ...
- Java 设计模式之抽象工厂模式
抽象工厂模式(Abstract Factory Pattern)是围绕一个超级工厂创建其他工厂.该超级工厂又称为其他工厂的工厂.这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式. 在抽 ...
随机推荐
- 解决NSImage绘制的时候图像模糊
Mac下NSImage绘制模糊的原因之一是draw到了非整数像素上,框架在渲染的时候就会模糊. 针对这一原因写了以下工具: /** * @brief 一劳永逸的解决NSImage绘制的时候绘到浮点值像 ...
- mysql从文件中导入数据
linux: load data infile '/tmp/dnslog.txt' into table dnslog_cnnic_cn fields terminated by ' ' lines ...
- ypbind启动失败
[root@bs035 test]# cat /etc/yp.conf # /etc/yp.conf - ypbind configuration file# Valid entries are## ...
- LeetCode: Trapping Rain Water 解题报告
https://oj.leetcode.com/problems/trapping-rain-water/ Trapping Rain WaterGiven n non-negative intege ...
- show global status和show variables mysql 优化
mysql> show global status; 可以列出MySQL服务器运行各种状态值,我个人较喜欢的用法是show status like '查询值%'; 一.慢查询 mysql> ...
- Android 启动后台运行程序(Service)
Android开发中,当需要创建在后台运行的程序的时候,就要使用到Service.Service 可以分为有无限生命和有限生命两种.特别需要注意的是Service跟Activities是不同的(简单来 ...
- spring报错:Caused by: java.lang.IllegalStateException: Cannot convert value of type for property : no matching editors or conversion strategy found
原因分析:是因为类返回的类型跟期望的类型没有继承关系,返回的类型就SqlMapClient,它是通过实现了FactoryBean<SqlMapClient>接口的SqlMapClientF ...
- nio入门教程
1.通过拿NIO和传统IO做对比来了解NIO 面向流与面向缓冲 Java NIO和IO之间第一个最大的区别是,IO是面向流的,NIO是面向缓冲区的. Java IO面向流意味着每次从流中读一个或多个字 ...
- thrift与protobuffer的区别
thrift由facebook出品,protobuffer由google出品: 下面对比一下这两个的区别.参考:http://zhidao.baidu.com/link?url=yNLBeHhWokf ...
- 关于listView的item失去焦点不能点击 Item中包含Button 导致抢占焦点
今天发现一个问题.listView的item点击以后进入到下一个页面,下个页面有个返回按钮,直接返回回去以后点击事件不能触发,滑动或者重新打开这个listView,就可以达到原来的效果.后来发现是因为 ...