2.抽象工厂(Abstract Factory)
常规的对象创建方法:
//创建一个Road对象
Road road =new Road();
new 的问题:
实现依赖,不能应对“具体实例化类型”的变化。
解决思路:
封装变化点-----哪里变化,封装哪里
潜台词: 如果没有变化,当然不需要额外的封装!
工厂模式的缘起
变化点在“对象创建”,因此就封装“对象创建”
面向接口编程----依赖接口,而非依赖实现
最简单的解决方法:
class RoadFactory
{
public static Road CreateRoad()
{
return new Road();
}
}
//创建一个Road对象
Road road=roadFactory.CreateRoad();
创建一系列相互依赖对象的创建工作:
假设一个游戏开场景:
我们需要构造"道路"、"房屋"、"地道","从林"...等等对象
工厂方法如下:
class RoadFactory
{
public static Road CreateRoad()
{
return new Road();
}
public static Building CreateBuilding()
{
return new Building();
}
public static Tunnel CreateTunnel()
{
return new Tunnel();
}
public static Jungle CreateJungle()
{
return new Jungle();
}
}
调用方式如下:
Road road = RoadFactory.CreateRoad();
Building building = RoadFactory.CreateBuilding();
Tunnel tunnel = RoadFactory.CreateTunnel();
Jungle jungle = RoadFactory.CreateJungle();
如上可见简单工厂的问题:
不能应对"不同系列对象"的变化。比如有不同风格的场景---对应不同风格的道路,房屋、地道....
如何解决:
使用面向对象的技术来"封装"变化点。
动机(Motivate):
在软件系统中,经常面临着"一系统相互依赖的对象"的创建工作:同时,由于需求的变化,往往存在更多系列对象的创建工作。
如何应对这种变化?如何绕过常规的对象创建方法(new),提供一种"封装机制"来避免客户程序和这种"多系列具体对象创建工作"的紧耦合?
意图(Intent):
提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
----《设计模式》GOF
结构图(Struct):
适用性:
1.一个系统要独立于它的产品的创建、组合和表示时。
2.一个系统要由多个产品系统中的一个来配置时。
3.当你要强调一系列相关的产品对象的设计以便进行联合使用时。
4.当你提供一个产品类库,而只想显示它们的接口不是实现时。
生活例子:

结构图代码实现:
public abstract class AbstractFactory
{
public abstract AbstractProductA CreateProductA(); public abstract AbstractProductB CreateProductB();
}
public class ConcreteFactory1 : AbstractFactory
{ public override AbstractProductA CreateProductA()
{
return new ProductA1();
} public override AbstractProductB CreateProductB()
{
return new ProductB1();
}
}
public class ConcreteFactory2 : AbstractFactory
{ public override AbstractProductA CreateProductA()
{
return new ProductA2();
} public override AbstractProductB CreateProductB()
{
return new ProductB2();
}
}
public abstract class AbstractProductA
{
public abstract void Interact(AbstractProductB b);
}
public class ProductA1 : AbstractProductA
{
public override void Interact(AbstractProductB b)
{
Console.WriteLine(this.GetType().Name + "interact with " + b.GetType().Name);
}
}
public class ProductA2 : AbstractProductA
{
public override void Interact(AbstractProductB b)
{
Console.WriteLine(this.GetType().Name + "interact with " + b.GetType().Name);
}
}
public abstract class AbstractProductB
{
public abstract void Interact(AbstractProductA a);
}
public class ProductB1 : AbstractProductB
{
public override void Interact(AbstractProductA a)
{
Console.WriteLine(this.GetType().Name + " interact with " + a.GetType().Name);
}
}
public class ProductB2 : AbstractProductB
{
public override void Interact(AbstractProductA a)
{
Console.WriteLine(this.GetType().Name + " interact with " + a.GetType().Name);
}
}
public class Client
{
private AbstractProductA AbstractProductA;
private AbstractProductB AbstractProductB; public Client(AbstractFactory factory)
{
AbstractProductA = factory.CreateProductA();
AbstractProductB = factory.CreateProductB();
} public void Run()
{
AbstractProductA.Interact(AbstractProductB);
AbstractProductB.Interact(AbstractProductA);
}
}
public static void Main()
{
// Abstractfactory1
AbstractFactory factory1 = new ConcreteFactory1();
Client c1 = new Client(factory1);
c1.Run(); //Abstractfactory1
AbstractFactory factory2 = new ConcreteFactory2();
Client c2 = new Client(factory2);
c2.Run();
}
如果不存在”多系列对象创建“的需求变化,则没必要应用Abstract Factory模式,静态工厂方法足矣。
"系列对象"指的是这些对象之间有相互依赖、或作用的关系。例如游戏开发场景中的"道路"与"房屋"依赖,“道路”与“地道”的依赖。
Abstract Factory模式主要在于应对"新系列"的需求变动。其缺点在于难以应对”新对象“的需求变动。
Abstract Factory模式经常和Factory Method模式共同组合来应对“对象创建”的需求变化。
2.抽象工厂(Abstract Factory)的更多相关文章
- 抽象工厂(Abstract Factory),工厂方法(Factory Method),单例模式(Singleton Pattern)
在谈工厂之前,先阐述一个观点:那就是在实际程序设计中,为了设计灵活的多态代码,代码中尽量不使用new去实例化一个对象,那么不使用new去实例化对象,剩下可用的方法就可以选择使用工厂方法,原型复制等去实 ...
- 面向对象设计——抽象工厂(Abstract Factory)模式
定义 提供一个创建一系列相关或者相互依赖对象的接口,而无需指定它们具体的类.抽象工厂允许客户使用抽象的接口来创建一组相关的产品,而不需要知道或关心实际产出的具体产品是什么.这样一来,客户就能从具体的产 ...
- 设计模式——抽象工厂(Abstract Factory)
提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们的具体类. ——DP UML类图 模式说明 抽象工厂与工厂方法在定义上最明显的区别是“创建一系列相关或相互依赖对象的接口”,由此可以看出抽象工 ...
- 5、抽象工厂 abstract factory 将关联组件组成产品 创建型模式
趁热打铁,紧跟着上一节的工厂方法模式.这一节介绍一下抽象工厂模式,以及分析俩个模式的不同 1.何为抽象模式? 抽象工厂模式(Abstract Factory Pattern)是围绕一个超级工厂创建其他 ...
- 工厂模式[3] 抽象工厂 Abstract Factory
简介 1.简单工厂,或静态工厂,产品接口 定义:专门定义一个类来负责创建其他类的实例,被创建的实例通常具有共同的父类或实现同一接口 优点:客户端可以直接消费产品,而不必关心具体产品的实现(不关心对象的 ...
- 设计模式四: 抽象工厂(Abstract Factory)
简介 抽象工厂模式是创建型模式的一种, 与工厂方法不同的是抽象工厂针对的是生产一组相关的产品, 即一个产品族. 抽象工厂使用工厂方法模式来生产单一产品, 单一产品的具体实现分别属于不同的产品族. 抽象 ...
- C2:抽象工厂 Abstract Factory
提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类. 应用场景: 一系列相互依赖的对象有不同的具体实现.提供一种“封装机制”来避免客户程序和这种“多系列具体对象创建工作”的紧耦合 UM ...
- Java 工厂模式(一)— 抽象工厂(Abstract Factory)模式
一.抽象工厂模式介绍: 1.什么是抽象工厂模式: 抽象工厂模式是所有形态的工厂模式中最为抽象和最具有一般性的一种形态,抽象工厂模式向客户端提供一个接口,使得客户端在不知道具体产品的情类型的情况下,创建 ...
- 【设计模式】——抽象工厂Abstract Factory
模式意图 提供对象的使用接口,隐藏对象的创建过程. 模式结构 AbstractFactory 提供创建对象的接口. ConcreteFactory 提供真正创建对象的实现类,用于组合并创建不同的对象, ...
- Headfirst设计模式的C++实现——抽象工厂(Abstract Factory)
Dough.h #ifndef _DOUGH_H #define _DOUGH_H class Dough { }; #endif ThinCrustDough.h #ifndef _THIN_CRU ...
随机推荐
- 在 Activity 中实现 getContentView 操作
2017/9/8 17:17:03 前言 最近接到个需要优化Android原生系统设置APK的任务.这个任务里面有一个更换应用背景图片的需求.我手里的这个设备是一个平板设备,使用了一下这个 ...
- 安卓Android基础四天
网页源码查看器 HttpURLConnection:用于发送和接受数据 ScrollView只能由一个孩子 消息机制的写法(***) anr Application not response 应用无响 ...
- centos安装php7.2环境
centos安装php7.2环境 安装apache服务 yum -y install httpd 首先获取rpm: rpm -Uvh https://dl.fedoraproject.org/pub/ ...
- Quartus prime 16.0 in_system memory content editor 使用
前言 quartus提供了片内存储器的实时查看与修改,而不用编译工程,很棒.你可以方便的查看到存储器中到底存储了什么东西. 流程 1.打开: 2.主界面: 3.设置jtag项之后,查看即可. sign ...
- Leetcode 215. 数组中的第K个最大元素 By Python
在未排序的数组中找到第 k 个最大的元素.请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素. 示例 1: 输入: [3,2,1,5,6,4] 和 k = 2 输出: 5 ...
- Nowcoder | [题解-N189]牛客OI赛制测试赛3
这场说实话确实水(逃*1),表示差一点就AK了(逃*2),然而被卡两个特判的我\(ssfd\)...\(qwq\) 表示这是第一次发整场比赛的题解...还请各位大佬原谅我太蒻写的垃圾啊\(qwq\). ...
- luogu3292 幸运数字 (点分治+线性基)
首先第一眼是一个倍增套线性基,但是$O(Qlog^2Vlog^N)=10^{10}$的复杂度... 即使是st表也只是变成了$O(Nlog^2Vlog^N)$啊 考虑点分治,相对于倍增显著减少了线性基 ...
- JetBrains全家桶破解思路(最新更新:2019-04-17)
JetBrains全家桶破解思路(以DataGrip为例) 2019-04-17 add new key 2019-01-24 add new key and code 2018-12-24 add ...
- Linux网络那点事(CentOS、Ubuntu、Kali)
跨平台系列汇总:http://www.cnblogs.com/dunitian/p/4822808.html#linux 在Ubuntu18.04中,传统的配置/etc/network/interfa ...
- Transactional ejb 事务陷阱
对应ejb,默认是对整个类使用事务.所以所有方法都开启事务. 而对于用TransactionAttribute注释来引用容器管理的事务,只能在第一级的方法中使用.对应类中的方法再调用其它类中方法,注释 ...