设计模式 — 抽象工厂模式(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 一.场景描述 ...
随机推荐
- chrome常用扩展程序汇总(程序员版)
chrome常用扩展程序之程序员版 1.chrome扩展程序 Chrome插件是一个由Web技术开发.用来增强浏览器功能的小程序,其实就是一个由HTML.CSS.JS.图片等静态资源组成的一个.crx ...
- 文本编辑利器Notepad++ 10个强大而又鲜为人知的特性【转】
文本编辑利器Notepad++ 10个强大而又鲜为人知的特性 - 为程序员服务
- word 2013 标题设置多级列表
1.问题 要设置标题为多级列表,批量应用 2.解决 1选标题1 2选标题2 ...以此类推.点确定保存即可
- jmeter笔记(7)--参数化--用户定义的变量
录制的脚本里面有很多的相同的数据的时候,比如服务器ip,端口号等,当更换服务器的时候,就需要手动的修改脚本里面对应的服务器ip和端口号,比较繁琐,jmeter里面有一个用户自定义变量能很好的解决这个问 ...
- Gitlab安装简明文档
1.关于Gitlab CE / GitLab EE版本的区别:Gitlab CE(Community Edition):Gitlab社区版,可以免费试用,无官方支持.GitLab EE(Enterpr ...
- 修改CentOS6.5默认主机名(root下操作)
使用CentOS6.5官方镜像安装完毕之后,默认的主机名为localhost,不便管理,我们需要根据实际情况修改. 此处我准备讲默认的主机名 localhost 改为 comex01-ct65 第一步 ...
- @WebFilter注解
@WebFilter @WebFilter 用于将一个类声明为==过滤器==,该注解将会在部署时被容器处理,容器将根据具体的属性配置将相应的类部署为过滤器.该注解具有下表给出的一些常用属性 ( 以下所 ...
- (转)spring异常抛出触发事务回滚策略
背景:在面试时候问到事务方法在调用过程中出现异常,是否会传递的问题,平时接触的比较少,有些懵逼. spring异常抛出触发事务回滚策略 Spring.EJB的声明式事务默认情况下都是在抛出unchec ...
- 洛谷P1032 字串变换-题解
https://www.luogu.org/problemnew/show/P1032--(题目传送) 好在数据范围很小,暴力一点也能过.思路较简单,按照所有规则,从第一位开始广搜. 注意:1.str ...
- 在PHP中如何把数组写成配置文件
1.配置文件 <?php return array ( 556770 => '65460d6684dcad3d0a92f1feb7fde199', 567701 => '9c2acd ...