抽象工厂模式,比工厂模式具有更高层次的抽象。当要返回一系列相关类中的某一个,而每个类都能根据需要返回不同的对象时,可以使用这种模式。换句话说,抽象工厂是一个工厂对象,他能返回一系列相关类中的一个类。可以用简单工厂决定返回那个类。通常认为,实验式的例子应该引用汽车制造产,我们希望丰田汽车完全使用丰田配件,而福特汽车完全使用福特配件。可以把每个汽车制造厂设想为抽象工厂,配件作为一组相关的类。

花园规划工厂
    我们可以考虑一下实际的例子,字应用程序里要用到抽象工厂。假设读者编写一个程序来规划花园,这可能是季生植物型花园、蔬菜型花园、
或者多年植物花园。不管规划哪种类型的花园,都会遇到如下问题:
1.边缘种植什么植物
2.中央种植什么植物
3.阴凉部分种植什么植物
(可能还会有许多类似的问题,我们这里假设以上三种)这里想设计一个基类Garden(花园),用类中的方法回答这些问题。

 1 using System; 2 using System.Drawing ; 3 namespace Gardener 4 { 5     /// <summary> 6 /// Summary description for Garden. 7 /// </summary> 8     public class Garden { 9         protected Plant center, shade, border;10         protected bool showCenter, showShade, showBorder;11         //select which ones to display12         public void setCenter() {showCenter = true;}13         public void setBorder() {showBorder =true;}14         public void setShade() {showShade =true;}15         //draw each plant16         public void draw(Graphics g) {17             if (showCenter) center.draw (g, 100, 100);18             if (showShade) shade.draw (g, 10, 50);19             if (showBorder) border.draw (g, 50, 150);20         }21     }22 }

  Plant对象设置植物的名字,在draww方法被调用时绘制自己

 1 using System; 2 using System.Drawing; 3  4 namespace Gardener 5 { 6     /// <summary> 7 /// Summary description for Plant. 8 /// </summary> 9     public class Plant     {10         private string name;11         private Brush br;12         private Font font;13 14         public Plant(string pname) {15             name = pname;     //save name16             font = new Font ("Arial", 12);17             br = new SolidBrush (Color.Black );18         }        19         //-------------20         public void draw(Graphics g, int x, int y) {21             g.DrawString (name, font, br, x, y);22         }23     }24 }

  用设计模式术语来讲,Garden接口就是抽象工厂。它定义了具体类中的方法,并返回一系列相关类中的某个类。这里将中央植物,边缘植物
喜阴植物作为三个相关类。抽象工厂也能返回更具体的花园信息,例如土壤的PH值或灌溉需等。
    在实际中,规划每一种类型的花园都要查阅一个详尽的植物信息库,而在这个简单的例子里,没类植物只给出一种。例如,对蔬菜花园,只给出下列几种植物

 1 using System; 2  3 namespace Gardener 4 { 5     /// <summary> 6 /// Summary description for VeggieGarden. 7 /// </summary> 8     public class VeggieGarden : Garden     { 9         public VeggieGarden() {10             shade = new Plant("Broccoli");11             border = new Plant ("Peas");12             center = new Plant ("Corn");13         }14     }15 }

我们用类似的方法创建Garden类的两个子类:PerennialGarden和AnnualGarden。因为每个具体类都实现了父类中的方法,所以都可以看做一个
具体的工厂。现在我们有了一系列的Garden对象,每一个对象都能创建一类Plant对象。在下图中说明了这一点

  我们很容易就构建出了工厂的驱动程序,他根据用户选的单选按钮返回一个Garden对象,用户界面如下。每一次选择一种新的花园类型时,都要屏幕,将复选框设置为未选中状态。然后选择一个复选框,画出相应的植物类型。

  由于每种花园(及植物)都要知道如何绘制自己,所以应该有一个draw方法,在屏幕上画出相应的植物名,由于我们用复选框来说明要话的植物类型,所以设置了一个布尔型变量,用它指出要画的每种植物类型,Garden对象包含了三个设置方法,用于指出绘制的每一种类型的植物。

1     public void setCenter() {showCenter = true;}2     public void setBorder() {showBorder =true;}3     public void setShade() {showShade =true;}

我们在图片框(pictureBox)里用元表示阴影区域,在图片框中还要给出植物的名字。从PictureBox类派生出一个新类GardenPic,并将画圆和
花园植物名称等信息传递给它,这是完成上述任务最好的方法,因此,不仅需要一耳光GardenMake窗口类中添加一个Paint的方法,还要在该窗口所
包含的PictureBox类中添加该方法。它覆盖了基类Control中的OnPaint事件。

 1     public class GdPic : System.Windows.Forms.PictureBox  2     { 3         /// <summary>  4 /// Required designer variable. 5 /// </summary> 6         private System.ComponentModel.Container components = null; 7         private Brush br; 8         private Garden gden; 9         private void init () {10             br = new SolidBrush (Color.LightGray );11         }12         public GdPic()     {13             // This call is required by the Windows.Forms Form Designer.14             InitializeComponent();15             init();16         }17         public void setGarden(Garden garden) {18             gden = garden;19         }20         protected override void OnPaint ( PaintEventArgs pe ){21             Graphics g = pe.Graphics;22             g.FillEllipse (br, 5, 5, 100, 100);23             if(gden != null)24                 gden.draw (g);    25         }

  处理单选按钮盒按钮事件,单机三个单选按钮中某一个,就会创建一个该类型的花园,并把它传给图片框,还要清除所有的复选框。

 1         private void opAnnual_CheckedChanged(object sender, EventArgs e) { 2             setGarden( new AnnualGarden ()); 3         } 4         //----- 5         private void opVegetable_CheckedChanged(object sender, EventArgs e) { 6             setGarden( new VeggieGarden ()); 7         } 8         //----- 9         private void opPerennial_CheckedChanged(object sender, EventArgs e) {10             setGarden( new PerennialGarden ());11         }        12         //-----13         private void setGarden(Garden gd) {14             garden = gd;            //save current garden15             gdPic1.setGarden ( gd);    //tell picture bos16             gdPic1.Refresh ();        //repaint it17             ckCenter.Checked =false;    //clear all18             ckBorder.Checked = false;    //check19             ckShade.Checked = false;    //boxes20         }

  单击一个复选框曲线是相应的植物名,要调用对应的花园方法去设置要显示的名称,然后调用图片框的Refresh方法重画。

 1         private void ckCenter_CheckedChanged(object sender, System.EventArgs e) { 2             garden.setCenter (); 3             gdPic1.Refresh (); 4         } 5         //----- 6         private void ckBorder_CheckedChanged(object sender, System.EventArgs e) { 7             garden.setBorder(); 8             gdPic1.Refresh (); 9         }10         //-----11         private void ckShade_CheckedChanged(object sender, System.EventArgs e) {12             garden.setShade ();13             gdPic1.Refresh ();14         }

抽象工厂效果
    抽象工厂的一个主要目的是要能隔离要生成的工具类。这些类的实际类名隐藏在工厂里,在客户端根本不知道。由于类的隔离,可以自由改动或交换这些
生成类系列。此外由于只要生成一类具体的类,系统会避免读者误用不同生成系类中的类。但是添加新的类系列要费一些心思 ,因为读者要定义一些
心的、无二义性的条件使工厂返回新的类系列。尽管抽象工厂生成的所有类都是有相同的基类,但还是无法避免某些子类具有额外的、与其他类不同的方法,
这中问题有两种解决方案:或者在基类中定义所有的方法,或者在是再派生出一个新的基类接口,它包含读者需要的所有方法和所有花园类型的子类。

转载于:https://www.cnblogs.com/sunjinpeng/archive/2012/03/27/2419561.html

设计模式 抽象工厂(Abstract Factory Pattern)相关推荐

  1. 设计模式--抽象工厂(Abstract Factory)模式

    模式定义 提供一个创建一系列相关或互相依赖对象的接口,而无需指定它们具体的类 类图 应用场景 程序需要处理不同系列的相关产品,但是你不希望它依赖于这些产品的具体类时可以使用抽象工厂模式 优点 1.可以 ...

  2. c++设计模式--抽象工厂(abstract factory)

    一.原理讲解 为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类. 1.1意图 定义一个创建对象的接口,让子类决定实例化哪个类.该模式使类对象的创建延迟到子类. 1.2应用场景 一个 ...

  3. 设计模式学习笔记——抽象工厂(Abstract Factory)模式

    设计模式学习笔记--抽象工厂(Abstract Factory)模式 @(设计模式)[设计模式, 设计模式中文名, 设计模式英文名] 设计模式学习笔记抽象工厂Abstract Factory模式 基本 ...

  4. 设计模式(四)——工厂模式(Factory Pattern)

    工厂模式(Factory Pattern) 意义 工厂模式 实现了创建者和调用者的分离.将实例化对象的代码提取出来,放到一个类中统一管理和维护,达到和主项目的依赖关系的解耦.从而提高项目的扩展和维护性 ...

  5. [设计模式-创建型]抽象工厂(Abstract Factory)

    概括 名称 Abstract Factory 结构 动机 提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类. 适用性 一个系统要独立于它的产品的创建.组合和表示时. 一个系统要由多个 ...

  6. 《研磨设计模式》chap7 抽象工厂 Abstract Factory

    场景:配电脑,多种CPU.主板 1. 正常编码 1.1 cpu //CPU的接口 public interface CPUApi {//示意方法,CPU具有运算的功能 public void calc ...

  7. C2:抽象工厂 Abstract Factory

    提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类. 应用场景: 一系列相互依赖的对象有不同的具体实现.提供一种"封装机制"来避免客户程序和这种"多系列具 ...

  8. 【设计模式】工厂模式 Factory Pattern

    1)简单工厂(不是模式) 简单工厂只是一种变成习惯,并非23种设计模式之一. 简单工厂提供将实例话那种类型留给运行时判断,而非编译时指定.简单工厂模式就是由一个工厂类根据传入的参数决定创建出哪一个类的 ...

  9. 设计模式 - 抽象工厂模式(abstract factory pattern) 详解

    抽象工厂模式(abstract factory pattern) 详解 本文地址: http://blog.csdn.net/caroline_wendy/article/details/270916 ...

最新文章

  1. 花了两天,终于把 Python 的 setup.py 给整明白了
  2. R语言_高级数据管理
  3. Shell教程(三):数组/Arrays、基本运算符
  4. openlayers入门开发系列之地图属性查询篇
  5. python全栈-Day 1
  6. 人生实苦,可这就是人生
  7. 用异或的性质实现简单加密解密
  8. 横跨7个版本的OpenStack无感知热升级在360的落地与实践
  9. 如何监控 Tomcat?Zabbix 与 Cloud Insight 对比
  10. 小程序商店刷榜_微信小程序店铺如何做引流,带来转化?
  11. 改变MyEclipse默认编码方式
  12. 计算机专业期末总结200字,学期末自我总结200字
  13. 命名实体识别难在哪?
  14. winpe linux系统安装win7,WINPE+LINUX+DOS 完美者U盘维护系统V8.6 及安装方法
  15. vue实现页面跳转过渡效果 transition
  16. 扁平化风格职业规划PPT模板
  17. vim和emac体验
  18. 软件工程 -- 系统流程图
  19. Spring三种切面
  20. http://localhost:8080/ 无法访问

热门文章

  1. keras-yolov3 + Kalman-Filter 进行人体多目标追踪(含代码)
  2. Microsfot Office Communicator 聊天记录 外挂
  3. 如何固定电脑ip地址
  4. 类火墙的iptables
  5. R语言编程艺术(4)R对数据、文件、字符串以及图形的处理
  6. Replication的犄角旮旯(四)--关于事务复制的监控
  7. 基于FPGA的跨时钟域信号处理——专用握手信号
  8. Nuget 管理报repositories.config 访问路径被拒绝 解决办法
  9. JQuery学习系列(三)语法
  10. 在Maple 9中察看内置函数的原代码的三种方法