设计模式 — 抽象工厂模式(Abstract Factory)
工厂模式已经分析了简单工厂模式和工厂方法模式。并且了解了工厂方法模式去简单工厂模式的延伸,工厂方法模式如果不把工厂类抽象的话,就是简单工厂模式。由前面两个工厂模式可以猜测出抽象工厂模式应该是这两种工厂模式的另外一个变化。先来看一下它的定义。
提供一个创建一系列相关或相互依赖的对象的接口,而无需指定它们具体的类。
先简单介绍一下定义的意思,就是需要创建一个接口,这个接口的作用就是用来创建一个以上的对象的,并且这些对象是相互依赖的,还不需要指定它们具体实现的类,应该是别创建对象的类。为了更好的理解,就用急速PDF阅读器切换皮肤为例子来介绍一下。
切换皮肤有多个地方是同时变动风格的。为了例子的简洁易懂,就那下面那个地方为例
- 背景
- 软件头部
很容易看出来,皮肤修改这二个是相互关联的,相互依赖的。不然出来的效果就是似是而非了。
代码示例
给出切换皮肤需要配置的三个部分的类
//系统背景接口(产品A)
public interface SystemBackground {
public String controlStyle();
} //系统头部(产品B)
public interface SystemHead {
public String controlStyleB();
} //系统简洁大气背景风格 (产品A1)
public class SystemBackgroundImplA implements SystemBackground { @Override
public String controlStyle() {
// TODO Auto-generated method stub
return "简洁大气的背景风格";
} } //系统中国风背景(产品A2)
public class SystemBackgoundImplB implements SystemBackground{ @Override
public String controlStyle() {
// TODO Auto-generated method stub
return "中国风的背景风格";
} } //系统简洁大气头部(产品B1)
public class SystemHeadImplA implements SystemHead { @Override
public String controlStyleB() {
// TODO Auto-generated method stub
return "简洁大气的系统头部";
} } //系统中国风头部(产品B2)
public class SystemHeadImplB implements SystemHead { @Override
public String controlStyleB() {
// TODO Auto-generated method stub
return "中国风的系统头部";
} }
工厂类
//工厂接口
public interface SkinFactory {
public void createBackgroundSkin(); public void createHeadSkin();
} //简洁大气皮肤工厂类
public class SkinFactoryJjdq implements SkinFactory { @Override
public void createBackgroundSkin() {
// TODO Auto-generated method stub
SystemBackground sbg = new SystemBackgroundImplA();
System.out.println("切换了"+sbg.controlStyle());
} @Override
public void createHeadSkin() {
// TODO Auto-generated method stub
SystemHead sh = new SystemHeadImplA();
System.out.println("切换了"+sh.controlStyleB());
} } //中国风皮肤工厂类
public class SkinFactoryZgf implements SkinFactory { @Override
public void createBackgroundSkin() {
SystemBackground sbg = new SystemBackgoundImplB();
System.out.println("切换了"+sbg.controlStyle());
} @Override
public void createHeadSkin() {
// TODO Auto-generated method stub
SystemHead sh = new SystemHeadImplB();
System.out.println("切换了"+sh.controlStyleB());
} }
客户端调用
public class Client {
public static void main(String[] args) {
SkinFactory sf = new SkinFactoryJjdq();
//简洁大气
System.out.println("--------开始切换【简洁大气】皮肤-----------");
sf.createHeadSkin();
sf.createBackgroundSkin();
System.out.println("*******切换【简洁大气】皮肤结束"); //中国风
System.out.println("\n --------开始切换【中国风】皮肤-----------");
sf = new SkinFactoryZgf();
sf.createHeadSkin();
sf.createBackgroundSkin();
System.out.println("++++++++切换【中国风】皮肤结束");
}
}
分析此设计模式
这个例子就是抽象工厂模式的所要解决的问题。把这个例子结构展示出来,可以更好的理解抽象工厂。
通过结构图看出来,工厂类有两个方法来创建产品类,并且这两个方法创建的对象是相互关联的。抽象工厂模式重点就在创建相互关联的对象。还拿例子来说,可以看出来工厂类有两个工厂方法。就是创建两个对象。但是不是随意创建的。他们是相互关联的,如果工厂类中一个创建的是简洁大气的头部皮肤,另外一个是中国风的背景。那出来的皮肤肯定就不是一个成功的产品了。所以他们一定是相互关联的。如果理解了工厂方法模式,那么对于抽象工厂模式来说,只要理解创建相互关联的对象这部分。就基本理解了抽象工厂模式要解决问题的本质。
如果产品族横向扩展(对于这个例子增加新的皮肤),那么添加新的具体工厂实现工厂就扣即可;纵向扩展(对于本例子来说,就是修改皮肤不仅是系统头部和背景,还有另外的依赖部分,比如滑动杆样式),这就需要修改工厂类了。
适应场景
- 一个产品要独立于它的创建组合和表示时。
- 一个系统需要由多个产品系列中的一个来配置时,并且是由多个相互依赖的部分组合成一个产品的。
- 当你提供一个产品类库,只是想显示它们的接口而不是实现时。
三个工厂模式的区别
三个工厂模式是相互关联的,简单工厂是工厂模式中的最简单的一些表达。他的任务就是把需要创建的对象和调用地方解耦。简单工厂类充当桥梁作用,没有考虑其他更多的问题。但是他有弊端,就是不能灵活扩展,只要想扩展,就需要修改工厂类。
为了解决这个问题,就发展了工厂方法模式。把工厂类用抽象类表示,实现具体的产品就用继承抽象工厂类的具体工厂来负责,这样就解决了简单工厂里面的扩展问题。
业务场景纷繁复杂,需要创建的对象也可能是复杂的,为了完成一定功能,需要创建相互关联的多个类。于是,在工厂方法模式基础上,让工厂类实现多个工厂方法。他们创建的对象相互关联共同完成特定功能。这就变成了抽象工厂模式。
小结
至此,工厂模式系统已经介绍完毕,他们都属于创建者模式。简单工厂模式和工厂方法模式使用的场景基本没有什么区别,只是当业务复杂,考虑扩展时候。就舍弃简单工厂而选用工厂方法模式。个人认为很系统应该也是重构发展的。一个场景可能开始用的简单工厂模式,但是随着系统不断发展,为了更灵活扩展,就修改成工厂方法模式。抽象工厂类使用场景看似很清晰,使用也是在系统不断扩展使用场景渐渐清晰的。工厂模式到这里了,如果以后发现没有理解到部分,再进行补充进来
设计模式 — 抽象工厂模式(Abstract Factory)的更多相关文章
- 设计模式 - 抽象工厂模式(abstract factory pattern) 具体解释
抽象工厂模式(abstract factory pattern) 详细解释 本文地址: http://blog.csdn.net/caroline_wendy/article/details/2709 ...
- C#设计模式——抽象工厂模式(Abstract Factory Pattern)
一.概述在软件开发中,常常会需要创建一系列相互依赖的对象,同时,由于需求的变化,往往存在较多系列对象的创建工作.如果采用常规的创建方法(new),会造成客户程序和对象创建工作的紧耦合.对此,抽象工厂模 ...
- Objective-C设计模式——抽象工厂模式Abstract Factory(对象创建)
抽象工厂模式 理解了工厂方法模式,其实抽象工厂和工厂方法模式有很多的相似之处.抽象工厂同样是分离客户端对象的创建和逻辑代码的,但是抽象工厂往往是产生一组数据而不单单是产生一个产品. 抽象工厂提供一个创 ...
- 大话设计模式--抽象工厂模式 Abstract Factory -- C++实现实例
1. 抽象工厂模式: 提供一个创建一系列相关或者相互依赖对象的接口,而无需指定他们具体的类. 下面是工厂方法模式: 下面是抽象工厂模式: 和工厂方法模式相比 抽象工厂模式可以有多个Product抽象, ...
- 乐在其中设计模式(C#) - 抽象工厂模式(Abstract Factory Pattern)
原文:乐在其中设计模式(C#) - 抽象工厂模式(Abstract Factory Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 抽象工厂模式(Abstract Factor ...
- 【设计模式】抽象工厂模式 Abstract Factory Pattern
简单工厂模式是一个工厂类根据工厂方法的参数创建不出不同的产品, 工厂方法模式是每一个产品都有一个一一对应的工厂负责创建该产品.那么今天要讲的抽象工厂模式是一个工厂能够产生关联的一系列产品.抽象工厂模式 ...
- .NET设计模式(2):1.2 抽象工厂模式(Abstract Factory)
概述 抽象工厂模式(Abstract Factory)是所有形态的工厂模式中最为抽象和最具一般性的一种形态.抽象工厂模式是指当有多个抽象角色时,使用的一种工厂模式.抽象工厂模式可以向客户端提供一个接口 ...
- 二十四种设计模式:抽象工厂模式(Abstract Factory Pattern)
抽象工厂模式(Abstract Factory Pattern) 介绍提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类. 示例有Message和MessageModel,Messag ...
- 【UE4 设计模式】抽象工厂模式 Abstract Factory Pattern
概述 描述 提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类:具体的工厂负责实现具体的产品实例 抽象工厂中每个工厂可以创建多种产品(如苹果公司生产iPhone.iPad): 工厂方法 ...
- 抽象工厂模式(Abstract Factory)C#实例
抽象工厂模式(Abstract Factory)C#实例 本文出处http://www.dofactory.com/net/abstract-factory-design-pattern 一.场景描述 ...
随机推荐
- linux搭建所遇到的坑elasticsearch-6.3.0
注意: 不能使用主账号(root账号运行,必须使用子账号登录) 第一步安装:: wget https://artifacts.elastic.co/downloads/elasticsearch/el ...
- chainsql异常记录
- centos7下使用docker安装gitlab
环境背景: Docker化已经成为一种热门,记录一下使用docker引擎安装gitlab的过程. 测试环境: 系统 软件 依赖 CentOS 7.4 GitLab(latest) docker-ce ...
- GWAS研究中case和control的比例是有讲究的?
GWAS研究中,表型分两种.第一种是线性的表型,如果身高.体重.智力等:第二种是二元的表型,比如患病和未患病,即通常所说的case和control.对于表型是线性的样本来说,是不存在case和cont ...
- cookie 和 session 的异同
cookie和session机制是web中常用的跟踪技术,用来跟踪用户的整个会话.cookie通过在客户端记录信息确定用户的身份,session通过在服务器端记录信息确定用户身份. (1)cookie ...
- java基础-容器-Set
Set:set不存重复元素,如果是使用set存储java预定义的Integer,String等类型会很简单,如果是存储自定义类型的数据类型,就必须要重新定义equals()方法以确保set中保存的对象 ...
- ES 常用java api
java rest client 有两种: 1.Java Low Level REST Client :用于Elasticsearch的官方低层客户端.它允许通过http与Elasticsearch集 ...
- vue DES 加密
安装crypto-js cnpm install crypto-js --save 封装一个des.js ECB模式 import cryptoJs from 'crypto-js' // DES加密 ...
- jmeter中的函数
1.函数帮助 1.tool-------->function helper dialog 可以查看函数帮助 2.jmeter中的函数 1.函数格式 ${__funcctionname(var ...
- C#decimal四舍五入格式化
Console.WriteLine(string.Format("{0:####}", 594884.539)); Console.WriteLine(string.Format( ...