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)是围绕一个超级工厂创建其他工厂.该超级工厂又称为其他工厂的工厂.这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式. 在抽 ...
随机推荐
- 转载: 8个月从CS菜鸟到拿到Google Offer的经历+内推
8个月从CS菜鸟到拿到Google Offer的经历+内推 http://blog.csdn.net/fightforyourdream/article/details/17094127 http:/ ...
- Gson json解析工具
json 解析工具 ,谷歌出品 对象转换字符串 HashMap<String,String> hashMap = new HashMap<String, String>(); ...
- Makefile学习之路——4
变量的类别有递归扩展变量和简单扩展变量.只用一个“=”符号定义的变量被称为递归扩展变量.通过下面例子观察递归扩展变量的特点. .PHONY: all foo=$(bar) bar=$(ugh) ugh ...
- ORM框架为什么不流行了
程序员的逻辑是先写sql脚本,然后在编写对应的实体代码. orm框架的逻辑是先写实体代码,然后自动生成脚本,构建数据库,这和程序员的逻辑或习惯刚好相反,所以这类ORM框架渐渐的被淘汰了,例如:Hibe ...
- 一款纯css3实现的鼠标经过按钮特效
今天再给大家带来一款纯css3实现的鼠标经过按钮特效.这款按钮非常简单,但效果很好,非常漂亮.一起看下效果图: 在线预览 源码下载 实现的代码. html代码: <div align=&qu ...
- 【Visual Studio】VS常用调试技巧——笔记
CSDN的文档: https://msdn.microsoft.com/en-us/library/aa295838(v=vs.60).aspx 情景一:[监视]变量时,当运行离开当前函数后,怎么看到 ...
- [小技巧]Linux的一些信息获取
1. Linux 系统登录之后,显示如下 Last login: Thu Jan :: UTC on ttyS0 Linux xxx # PREEMPT Wed Jul :: CST armv7l 那 ...
- 决策树---ID3算法(介绍及Python实现)
决策树---ID3算法 决策树: 以天气数据库的训练数据为例. Outlook Temperature Humidity Windy PlayGolf? sunny 85 85 FALSE no ...
- 详解JNDI的lookup资源引用 java:/comp/env
ENC的概念: The application component environment is referred to as the ENC, the enterprise naming c ...
- Nodejs入门手记 (01):Hello World的WEB程序
声明:本文为原创文章,如需转载,请注明来源并保留原文链接Allong,谢谢! “滚滚长江东逝水,浪花淘尽英雄.是非成败转头空.” - <临江仙·杨慎·明> 很熟悉的旋律,鸡汤了一下:高考是 ...