AbstractFactory抽象工厂(创建型模式)
动机:
在软件系统中,经常面临着“一系列相互依赖的对象”的创建工作;同时,由于需求的变化,往往存在更多系列对象的创建工作。
如何应对这种变化?如何绕过常规的对象创建方法(new),提供一种“封装机制”来避免客房程序和这种“多系列具体对象创建工作”的支耦合?
意图:
提供一个接口,让该接口负责创建一系列“相关或者相互依赖的对象”,无需指定它们具体的类。
出自:《设计模式》GoF
Abstract Factory模式的几个要点:
1、如果没有应对“多系列对象构建”的需求变化,则没有必要使用Abstract Factroy模式,这里使用简单的静态工厂完全可以。
2、“系列对象”指的是这些对象之间有相互依赖、或作用的关系,例如游戏开发场景中的“道路”与“房屋”的依赖,“道路”与“地道”的依赖。
3、Abstract Factory模式主要在于应对“新系列”的需求变动。其缺点在于难以应用“新对象”的需求变动。
4、Abstract Factory模式经常和Factory Method模式共同组合来应对“对象创建”的需求变化。
稳定部分
1using System;
2using System.Drawing ;
3namespace 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 display
12 public void setCenter() {showCenter = true;}
13 public void setBorder() {showBorder =true;}
14 public void setShade() {showShade =true;}
15 //draw each plant
16 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}
23
变化部分:2using System.Drawing ;
3namespace 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 display
12 public void setCenter() {showCenter = true;}
13 public void setBorder() {showBorder =true;}
14 public void setShade() {showShade =true;}
15 //draw each plant
16 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}
23
1using System;
2using System.Drawing ;
3
4namespace Gardener
5{
6 /// <summary>
7 /// Summary description for AnnualGarden.
8 /// </summary>
9 public class AnnualGarden : Garden
10 {
11 public AnnualGarden () {
12 shade = new Plant("Coleus");
13 border = new Plant ("Alyssum");
14 center = new Plant ("Marigold");
15 }
16 }
17public class PerennialGarden : Garden
18 {
19 public PerennialGarden() {
20 shade = new Plant("Astilbe");
21 border = new Plant ("Dicentrum");
22 center = new Plant ("Sedum");
23 }
24 }
25public class VeggieGarden : Garden {
26 public VeggieGarden() {
27 shade = new Plant("Broccoli");
28 border = new Plant ("Peas");
29 center = new Plant ("Corn");
30 }
31 }
32}
33
工厂:
2using System.Drawing ;
3
4namespace Gardener
5{
6 /// <summary>
7 /// Summary description for AnnualGarden.
8 /// </summary>
9 public class AnnualGarden : Garden
10 {
11 public AnnualGarden () {
12 shade = new Plant("Coleus");
13 border = new Plant ("Alyssum");
14 center = new Plant ("Marigold");
15 }
16 }
17public class PerennialGarden : Garden
18 {
19 public PerennialGarden() {
20 shade = new Plant("Astilbe");
21 border = new Plant ("Dicentrum");
22 center = new Plant ("Sedum");
23 }
24 }
25public class VeggieGarden : Garden {
26 public VeggieGarden() {
27 shade = new Plant("Broccoli");
28 border = new Plant ("Peas");
29 center = new Plant ("Corn");
30 }
31 }
32}
33
1using System;
2using System.Collections;
3using System.ComponentModel;
4using System.Drawing;
5using System.Data;
6using System.Windows.Forms;
7
8namespace Gardener
9{
10 /// <summary>
11 /// Summary description for GdPic.
12 /// </summary>
13 public class GdPic : System.Windows.Forms.PictureBox
14 {
15 /// <summary>
16 /// Required designer variable.
17 /// </summary>
18 private System.ComponentModel.Container components = null;
19 private Brush br;
20 private Garden gden;
21 private void init () {
22 br = new SolidBrush (Color.LightGray );
23 }
24 public GdPic() {
25 // This call is required by the Windows.Forms Form Designer.
26 InitializeComponent();
27 init();
28 }
29 public void setGarden(Garden garden) {
30 gden = garden;
31 }
32 protected override void OnPaint ( PaintEventArgs pe ){
33 Graphics g = pe.Graphics;
34 g.FillEllipse (br, 5, 5, 100, 100);
35 if(gden != null)
36 gden.draw (g);
37 }
38
39 /// <summary>
40 /// Clean up any resources being used.
41 /// </summary>
42 protected override void Dispose( bool disposing )
43 {
44 if( disposing )
45 {
46 if(components != null)
47 {
48 components.Dispose();
49 }
50 }
51 base.Dispose( disposing );
52 }
53
54 Component Designer generated code
67
68 }
69}
70
主程序:2using System.Collections;
3using System.ComponentModel;
4using System.Drawing;
5using System.Data;
6using System.Windows.Forms;
7
8namespace Gardener
9{
10 /// <summary>
11 /// Summary description for GdPic.
12 /// </summary>
13 public class GdPic : System.Windows.Forms.PictureBox
14 {
15 /// <summary>
16 /// Required designer variable.
17 /// </summary>
18 private System.ComponentModel.Container components = null;
19 private Brush br;
20 private Garden gden;
21 private void init () {
22 br = new SolidBrush (Color.LightGray );
23 }
24 public GdPic() {
25 // This call is required by the Windows.Forms Form Designer.
26 InitializeComponent();
27 init();
28 }
29 public void setGarden(Garden garden) {
30 gden = garden;
31 }
32 protected override void OnPaint ( PaintEventArgs pe ){
33 Graphics g = pe.Graphics;
34 g.FillEllipse (br, 5, 5, 100, 100);
35 if(gden != null)
36 gden.draw (g);
37 }
38
39 /// <summary>
40 /// Clean up any resources being used.
41 /// </summary>
42 protected override void Dispose( bool disposing )
43 {
44 if( disposing )
45 {
46 if(components != null)
47 {
48 components.Dispose();
49 }
50 }
51 base.Dispose( disposing );
52 }
53
54 Component Designer generated code
67
68 }
69}
70
1using System;
2using System.Drawing;
3using System.Collections;
4using System.ComponentModel;
5using System.Windows.Forms;
6using System.Data;
7
8namespace Gardener
9{
10 /// <summary>
11 /// Summary description for Form1.
12 /// </summary>
13 public class Form1 : System.Windows.Forms.Form
14 {
15 private System.Windows.Forms.GroupBox groupBox1;
16 private Gardener.GdPic gdPic1;
17 private System.Windows.Forms.RadioButton opAnnual;
18 private System.Windows.Forms.RadioButton opVegetable;
19 private System.Windows.Forms.RadioButton opPerennial;
20 private System.Windows.Forms.CheckBox ckCenter;
21 private System.Windows.Forms.CheckBox ckBorder;
22 private System.Windows.Forms.CheckBox ckShade;
23 /// <summary>
24 /// Required designer variable.
25 /// </summary>
26 private System.ComponentModel.Container components = null;
27 private Garden garden;
28 private void init() {
29 }
30 public Form1()
31 {
32 //
33 // Required for Windows Form Designer support
34 //
35 InitializeComponent();
36 init();
37 //
38 // TODO: Add any constructor code after InitializeComponent call
39 //
40 }
41
42 /// <summary>
43 /// Clean up any resources being used.
44 /// </summary>
45 protected override void Dispose( bool disposing )
46 {
47 if( disposing )
48 {
49 if (components != null)
50 {
51 components.Dispose();
52 }
53 }
54 base.Dispose( disposing );
55 }
56
57 Windows Form Designer generated code
169
170 /// <summary>
171 /// The main entry point for the application.
172 /// </summary>
173 [STAThread]
174 static void Main()
175 {
176 Application.Run(new Form1());
177 }
178
179
180 private void opAnnual_CheckedChanged(object sender, EventArgs e) {
181 setGarden( new AnnualGarden ());
182 }
183 //-----
184 private void opVegetable_CheckedChanged(object sender, EventArgs e) {
185 setGarden( new VeggieGarden ());
186 }
187 //-----
188 private void opPerennial_CheckedChanged(object sender, EventArgs e) {
189 setGarden( new PerennialGarden ());
190 }
191 //-----
192 private void setGarden(Garden gd) {
193 garden = gd; //save current garden
194 gdPic1.setGarden ( gd); //tell picture bos
195 gdPic1.Refresh (); //repaint it
196 ckCenter.Checked =false; //clear all
197 ckBorder.Checked = false; //check
198 ckShade.Checked = false; //boxes
199 }
200 private void ckCenter_CheckedChanged(object sender, System.EventArgs e) {
201 garden.setCenter ();
202 gdPic1.Refresh ();
203 }
204 //-----
205 private void ckBorder_CheckedChanged(object sender, System.EventArgs e) {
206 garden.setBorder();
207 gdPic1.Refresh ();
208 }
209 //-----
210 private void ckShade_CheckedChanged(object sender, System.EventArgs e) {
211 garden.setShade ();
212 gdPic1.Refresh ();
213 }
214 }
215}
216
2using System.Drawing;
3using System.Collections;
4using System.ComponentModel;
5using System.Windows.Forms;
6using System.Data;
7
8namespace Gardener
9{
10 /// <summary>
11 /// Summary description for Form1.
12 /// </summary>
13 public class Form1 : System.Windows.Forms.Form
14 {
15 private System.Windows.Forms.GroupBox groupBox1;
16 private Gardener.GdPic gdPic1;
17 private System.Windows.Forms.RadioButton opAnnual;
18 private System.Windows.Forms.RadioButton opVegetable;
19 private System.Windows.Forms.RadioButton opPerennial;
20 private System.Windows.Forms.CheckBox ckCenter;
21 private System.Windows.Forms.CheckBox ckBorder;
22 private System.Windows.Forms.CheckBox ckShade;
23 /// <summary>
24 /// Required designer variable.
25 /// </summary>
26 private System.ComponentModel.Container components = null;
27 private Garden garden;
28 private void init() {
29 }
30 public Form1()
31 {
32 //
33 // Required for Windows Form Designer support
34 //
35 InitializeComponent();
36 init();
37 //
38 // TODO: Add any constructor code after InitializeComponent call
39 //
40 }
41
42 /// <summary>
43 /// Clean up any resources being used.
44 /// </summary>
45 protected override void Dispose( bool disposing )
46 {
47 if( disposing )
48 {
49 if (components != null)
50 {
51 components.Dispose();
52 }
53 }
54 base.Dispose( disposing );
55 }
56
57 Windows Form Designer generated code
169
170 /// <summary>
171 /// The main entry point for the application.
172 /// </summary>
173 [STAThread]
174 static void Main()
175 {
176 Application.Run(new Form1());
177 }
178
179
180 private void opAnnual_CheckedChanged(object sender, EventArgs e) {
181 setGarden( new AnnualGarden ());
182 }
183 //-----
184 private void opVegetable_CheckedChanged(object sender, EventArgs e) {
185 setGarden( new VeggieGarden ());
186 }
187 //-----
188 private void opPerennial_CheckedChanged(object sender, EventArgs e) {
189 setGarden( new PerennialGarden ());
190 }
191 //-----
192 private void setGarden(Garden gd) {
193 garden = gd; //save current garden
194 gdPic1.setGarden ( gd); //tell picture bos
195 gdPic1.Refresh (); //repaint it
196 ckCenter.Checked =false; //clear all
197 ckBorder.Checked = false; //check
198 ckShade.Checked = false; //boxes
199 }
200 private void ckCenter_CheckedChanged(object sender, System.EventArgs e) {
201 garden.setCenter ();
202 gdPic1.Refresh ();
203 }
204 //-----
205 private void ckBorder_CheckedChanged(object sender, System.EventArgs e) {
206 garden.setBorder();
207 gdPic1.Refresh ();
208 }
209 //-----
210 private void ckShade_CheckedChanged(object sender, System.EventArgs e) {
211 garden.setShade ();
212 gdPic1.Refresh ();
213 }
214 }
215}
216