民初思韵网

加入收藏   设为首页
选择语言   传统中文
你好,请 登陆 或 注册
首页 人文思韵 传奇人物 历史思潮 时代作品 话题讨论 国民思韵 民初捐助 账户管理
  搜索  
    人文精神 >>> 技术的天空 温和的思绪
字体    

C#面向对象设计模式纵横谈 第3讲:Abstract Factory 抽象工厂模式
C#面向对象设计模式纵横谈 第3讲:Abstract Factory 抽象工厂模式
MSDN 网络广播 李建忠     阅读传统中文版

2005.11.15 李建忠

new的问题

常规的对象创建方法:

image

new的问题:

-实现依赖,不能应对“具体实例化类型”的变化

解决思路:

-封装变化点——哪里变化,封装哪里

-潜台词:如果没有变化,当然不需要额外的封装!

 

工厂模式的缘起

变化点在“对象创建”,因此就封装“对象创建”

面向接口编程——依赖接口,而非依赖实现

最简单的解决方法:

image

 

创建一系列相互依赖的对象

假设一个游戏开发场景:

我们需要构造“道路”、“房屋”、“地道”、“丛林”……等等对象

image

image

 

简单工厂的问题

简单工厂的问题:

-不能应对“不同系列对象”的变化。比如有不同风格的游戏场景——对应不同风格的道路、房屋、地道……客户程序相对稳定,但是静态的简单工厂却可能成为变化点。

如何解决:

-使用面向对象的技术来“封装”变化点

 

动机(Motivation)

在软件系统中,经常面临着“一系列相互依赖的对象”的创建工作;同时,由于需求的变化,往往存在更多系列对象的创建工作。

如何应对这种变化?如何绕过常规的对象创建方法(new),提供一种“封装机制”来避免客户程序和这种“多系列具体对象创建工作”的紧耦合?

 

意图(Intent)

提供一个接口,让该接口负责创建一系列“相关或者相互依赖的对象”,无需指定它们具体的类。

——《设计模式》GoF

 

结构(Structure)

image

A1和B1是一个系列,A2和B2是另一个系列。ConcreteFactory1是创建系列1的工厂方法,ConcreteFactory2是创建系列2的工厂方法。客户程序Client只依赖了AbstractFactory和AbstractProductA、AbstractProductB,也就是客户程序不依赖于具体实现,而是只依赖与抽象类。

如果现在需要创建一个系列3运用到客户程序,我们只需要再写一个系列3的工厂,继承自AbstractFactory,这个工厂提供了2个实现:

CreateProductA();

CreateProductB();

它们分别返回ProductA3(继承自AbstractProductA)、ProductB3(继承自AbstractProductB)。

也就是说,如果新增了系列3,Client程序可以完全不用改动,可能只需要该一些配置文件,增加一些新dll就可以应对变化。

 

游戏框架中的AbstractFactory应用

image

image

这个例子里,Road就是AbstractProductA1,Building就是AbstractProductB1,FacilitiesFactory就是AbstractFactory。

 

客户程序

image

可以看出,客户程序依赖的全部是抽象类,在客户程序代码中没有出现过任何具体的实现类。因为在系列需要变化的时候,是不需要改变抽象类的,只是增加一个抽象类的实现而已,又由于客户程序只依赖于抽象,所以系列变化的时候客户程序完全无需变化。

一个现代风格系列的实现

image

具体现代风格系列工厂实现

image

应用到具体程序(现代风格)

image

应用到具体程序(经典风格)

image

可以看出,风格由Modern改变为Classic的时候,我们封装好的GameManager客户程序没有改变,这就是我们想要的结果。GameManager的逻辑非常复杂,现在它的稳定,能够大大方便我们的工作。

 

AbstractFactory模式的几个要点

1.如果没有应对“多系列对象创建”的需求变化,则没有必要使用AbstractFactory模式,这时候使用简单的静态工厂完全可以。

2."系列对象"指的是这些对象之间有相互依赖、或作用的关系,例如游戏开发场景中“道路”与“房屋”的依赖,“道路”与“地道”的依赖。

3.AbstractFactory模式主要在于应对“新系列”的需求变动。其缺点在于难以应对“新对象”的需求变动。

4.AbstractFactory模式经常喝FactoryMethod模式共同组合来应对“对象创建”的需求变化。

例如,如果是风格不是经常变化,而是其他内容变化(例如今天要添加道路的类、明天要添加沙漠的类),这样用这种抽象工厂模式反而会把系统搞的很糟糕,因为抽象工厂类中的子类变化了,所有实现抽象工厂的类都需要去变化,重新实现,重新编译和部署。

也就是说关键要看变化的方向和轴线在哪里。如果变化的轴线在多风格,那抽象工厂模式就很适用;如果变化的轴线在抽象工厂里面的对象,就最好不要使用这种模式。

 

.NET框架中的AbstractFactory应用

在ASP.Net编译的时候,首先把aspx页面文件先编译成一个类,然后再把CodeBehind又编译成一个类,CodeBehind的类继承自Page类,而aspx页面的类又继承自CodeBehind类。在aspx页面中处理的WebControl和HtmlControl实际上用到了AbstractFactory的运用,但是这个运用更多是体现在业务层次。

 

Builder模式和AbstractFactory模式的区别

Builder模式更强调的是对象部分的构建这样一个严格的过程,它构建的是整个对象的各个部分。它把构建稳定下来之后,各个部分在变化,最后组合成一个整体的对象。

AbstractFactory模式构建的是一组系列交互的对象。

互相依赖、互相交互的对象和一个对象的各个部分是有区别的。

2010.9.22

2013-08-22 08:42

欢迎订阅我们的微信公众账号!
春秋茶馆订阅号
微信号 season-tea(春秋茶馆)
每天分享一篇科技/游戏/人文类的资讯,点缀生活,启迪思想,探讨古典韵味。
  清末民初历史人物  民初人物
高文费而隐 古德洁无华
杨霁园先生是民国时期宁波的一位大儒,一生致力于教育、述着,着作宏丰,在国学、文学等方面成就卓着,更兼他品行方端、至诚至孝,自1940年去世后,乡人及门生一直追思不息。但杨....
散文大家旷达风趣
梁实秋(1903年1月6日-1987年11月3日),号均默,原名梁治华,字实秋,笔名子佳、秋郎,程淑等,中国着名的散文家、学者、文学批评家、翻译家,华人世界第一个研究莎士....
资助民初精神网
        回顶部     写评论

 
评论集
#1楼    2014年11月11日11点37分   |    佚名网友   
每张图都不清楚 你他妈的是在贴个屁图啊 操
发表评论欢迎你的评论
昵称:     登陆  注册
主页:  
邮箱:  (仅管理员可见)

验证:   验证码(不区分大小写)  
© 2011   民初思韵网-清末民初传奇时代的发现与复兴   版权所有   加入收藏    设为首页    联系我们    1616导航