Home > Catalog, Factory Method, Tools > ActionScript 3.0 Design Pattern Catalog: Creational Patterns

ActionScript 3.0 Design Pattern Catalog: Creational Patterns

A Tale of Two Factories: One New and One Reused

This is the first of three posts on the actual AIR ActionScript 3.0 Design Pattern catalog. Previously, I had discussed the thinking that went into the design of the Catalog, and here is the first actual AIR application with the Creational Patterns portion of the catalog all set up and ready to use. Figure 1 shows what each page looks like: (By the way, the actual image in the catalog is almost twice the size as what you see in Figure 1.)

catalog1
Figure 1: Design Pattern Catalog Page

Before going on, you can download all of the source code and the AIR application by clicking the Download button. Additionally, you may want to access the Catalog Online.

download

I changed the color combinations. I concluded that Kuler’s 1944mustang color set was the best for this project because I needed a white background and I liked the orange for highlight. I used red for labeling on the diagrams, but it was used sparsely and provided a consistency.

After several false starts, I finally settled on the Factory Method, and by the time I was finished, I was glad I did. It’s an easy design pattern, keeps the classes loosely connected and is very flexible. In fact I used two Factory Method patterns—one was reused from an earlier application where the factory method was used to send DataProvider data to the Client. (See Refactoring with Multiple Design Patterns.)

The new Factory Method created instances of the pages assembled from several text fields and a graphic. Initially, I was going to have a single Product class and a different ConcreteProduct class for each pattern (23 in all), and that was exactly what I started doing. However, I soon discovered that the only thing that I needed to do was to pass a string parameter with the data name for each pattern, and a single ConcreteProduct class could handle the whole thing. Each of the classes representing a ConcreteProduct class was no smaller than the single general ConcreteProduct; so it did not necessitate bloating a class to cut down on the number of classes.

Finally, all of the data for the page are stored in folders for each individual design pattern. Each folder has a single PNG file and 12 text files. All of the contents of the 23 patterns have identical names and the pattern name is keyed to the folder name. Figure 2 shows an overview of the classes, the data folders and the Client connections to the data.
layout

Figure 2: Files and Data Folders
As you can see in Figure 2, using multiple design patterns of the same type is no different than using single design patterns or different design patterns simultaneously. All you need is to have your Client hooked in where it needs to make the request.

Files, Files, Everywhere!

Figure 2 shows only five of the needed 23 folders have been completed. Fortunately, only five design patterns are part of the Creational category; so I get a break between stints of the mind-numbing chore of adding text to text files. Adding the remaining folders is a matter of copying and pasting the current ones and then changing most of the text content and replacing the PNG file with the class diagram. If you’re in a hurry for the rest of the patterns you can do it yourself—most of the summaries are direct quotes from The Gang of Four or paraphrased to save space. The same is true with the rest of the materials, but I added the kinds of things that are specific to ActionScript 3.0, and of course the code snippets are all ActionScript 3.0. Figure 3 shows the contents of each folder:

files
Figure 3: Text and Graphic files

Because all of the headers are the same, none of them have to be changed, and some of the text files are simply single words such as the name of the design pattern or the type of pattern. Using the WhatVaries AIR app, it’s easy to get what varies in each pattern as well. However, getting all of the text for components (participants), code examples and uses can be tricky because there’s only limited space for each.

While it may be tedious to enter all of the data for each and every design pattern, you’ll learn a lot—especially if you are using the Gang of Four’s book or ActionScript 3.0 Design Patterns. Also, there’s a lot of information on this blog you can use to fill out the data.

To add further design patterns here’s all you have to do:

  • Copy and paste one of the current design pattern folders and all of its contents and then rename it using lower case no-space name. For example, the Chain of Responsibility can be named cor
  • Add the label name and the data name of the design pattern in the CatData class. Use the same lowercase name for the data name as you used to name the folder for the pattern.
  • Draw a class diagram with a width no greater than 500px and save it as a PNG file using the name, diagram.png in the folder where you have the other files for the pattern.
  • Open the text files and change the content to reflect the characteristics of the design pattern. The files with “head” in the filename (e.g., codehead.txt) should be left unchanged but still have to be in the folder

That’s it. It also reflects what I like about design patterns. Once you get the basic structure set up; changes and reuse are easy.

The Page-Making Factory

Since we’re reusing a design pattern, you can review it at Refactoring with Multiple Design Patterns . However, to understand how the new use of the Factory Method works, each of the classes are reviewed here.

First of all, the Client is remarkably clean, and all requests, other than the initial one to provide data for the List component, relies on user-input in the List menu. Only a single conditional statement is used anywhere in this application, and it can be found in the Client where checking content in the DisplayObject. So you’ll find a very simple Client making requests for data and to see the content of a design pattern. The following listing shows what little code is required in the Client class:

?View Code ACTIONSCRIPT
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
package
{
	import flash.display.Sprite;
	import fl.controls.List;
	import fl.data.DataProvider;
	import fl.events.ListEvent;
 
	//Client Class
 
	public class Client extends Sprite
	{
		private var factory:Creator = new ConcreteCreator  ;
		private var catalog:DataProvider;
		private var list:List = new List  ;
		private var dp:String;
		private var dpDisplay:Sprite;
 
		public function Client()
		{
			setMenu();
		}
 
		private function setMenu():void
		{
			//Re-use Factory that provides data for DataProvider
			var create:DPCreator = new ConcreteDPCreator  ;
			var catalog:DataProvider = new DataProvider  ;
			catalog = create.selectData();
			//Set up the list
			list.setSize(126,650);
			list.x = 0,list.y = 0;
			list.dataProvider = catalog;
			addChild(list);
			list.addEventListener(ListEvent.ITEM_CLICK,choosePattern);
		}
 
		private function choosePattern(e:ListEvent):void
		{
			dp = String(e.item.data);
			//Only conditional in the entire program
			if (dpDisplay)
			{
				removeChild(dpDisplay);
			}
 
			dpDisplay = factory.makeDP(dp);
			addChild(dpDisplay);
		}
	}
}

As you can see, once the List menu is set up, the choosePattern() method does all the work. Further it is accomplished using very little code.

The next class is the Creator. It supplies the interface for the factory. As an abstract class, it cannot be instantiated, but you can include implemented methods. In this case, one method is implemented and the other is abstract.

?View Code ACTIONSCRIPT
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package
{
	//Asbstract class
	//Creator
	import flash.display.Sprite;
	import flash.errors.IllegalOperationError;
 
	public class Creator
	{
		private var dpNow:Sprite;
 
		public function makeDP(dp:String):Sprite
		{
			dpNow = chooseDP(dp);
			return dpNow;
		}
 
		// ABSTRACT Method (must be overridden in a subclass)
		protected function chooseDP(dp:String):Sprite
		{
			throw new IllegalOperationError("Abstract method: must be overridden in a subclass");
			return null;
		}
	}
}

The factory itself is a subclass of the abstract Creator class. It must implement the abstract method, and really nothing else. Originally when I had planned on individual ConcreteProduct classes for each design pattern, I had a big switch statement with 23 cases. However, by adding a parameter to the Catalog constructor (the ConcreteProduct class), all that’s passed is a string based on the List selected item’s data value.

?View Code ACTIONSCRIPT
1
2
3
4
5
6
7
8
9
10
11
12
13
14
package
{
	//Factory
	import flash.display.Sprite;
	import flash.errors.IllegalOperationError;
 
	public class ConcreteCreator extends Creator
	{
		override protected function chooseDP(dp:String):Sprite
		{
			return(new Catalog(dp));
		}
	}
}

The Product and Concrete Product Classes

The big classes in this application are the two that handle the product elements. That should not come as a surprise because the product is pretty big—12 text fields with text and a graphic file. The abstract Product class has both abstract and implemented methods and lots of them. With 284 lines of code (including spaces and comments), this was the biggest abstract class I’d ever created. Half the methods are abstract and the other half are implemented. Essentially, it works like a giant getter/setter—or loader/placer to be more precise. Once each load is complete, a mirror function (method) “catches” the loaded materials and places it where it belongs on the DisplayObject (aka stage).

?View Code ACTIONSCRIPT
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
package
{
	import flash.errors.IllegalOperationError;
	import flash.net.URLLoader;
	import flash.display.Sprite;
	import flash.text.TextField;
	import flash.text.TextFieldType;
	import flash.events.Event;
	import flash.text.TextFormat;
 
	//Abstract class
	public class Product extends Sprite
	{
		private var loadCheck:URLLoader;
 
		private var txtFld:TextField = new TextField();
		private var typeFld:TextField = new TextField();
		private var sumHeadFld:TextField = new TextField();
		private var sumFld:TextField = new TextField();
		private var varyHeadFld:TextField = new TextField();
		private var varyFld:TextField = new TextField();
		private var usesHeadFld:TextField = new TextField();
		private var usesFld:TextField = new TextField();
		private var codeHeadFld:TextField = new TextField();
		private var codeFld:TextField = new TextField();
		private var comHeadFld:TextField = new TextField();
		private var comFld:TextField = new TextField();
 
		private var textFormat:TextFormat = new TextFormat();
		private const TEXTCOLOR:uint = 0x263248;
		private const TYPECOLOR:uint = 0xFF9800;
		private const HEADCOLOR:uint = 0x263248;
		private const BODYCOLOR:uint = 0x000000;
 
		protected function loadInfo(txtInfo:String):void
		{
			throw new IllegalOperationError("Abstract method: must be overridden in a subclass");
		}
 
		protected function loadType(txtInfo:String):void
		{
			throw new IllegalOperationError("Abstract method: must be overridden in a subclass");
		}
 
		protected function loadSumHead(txtInfo:String):void
		{
			throw new IllegalOperationError("Abstract method: must be overridden in a subclass");
		}
 
		protected function loadSum(txtInfo:String):void
		{
			throw new IllegalOperationError("Abstract method: must be overridden in a subclass");
		}
 
		protected function loadVaryHead(txtInfo:String):void
		{
			throw new IllegalOperationError("Abstract method: must be overridden in a subclass");
		}
 
		protected function loadVary(txtInfo:String):void
		{
			throw new IllegalOperationError("Abstract method: must be overridden in a subclass");
		}
 
		protected function loadUsesHead(txtInfo:String):void
		{
			throw new IllegalOperationError("Abstract method: must be overridden in a subclass");
		}
 
		protected function loadUses(txtInfo:String):void
		{
			throw new IllegalOperationError("Abstract method: must be overridden in a subclass");
		}
 
		protected function loadCodeHead(txtInfo:String):void
		{
			throw new IllegalOperationError("Abstract method: must be overridden in a subclass");
		}
 
		protected function loadCode(txtInfo:String):void
		{
			throw new IllegalOperationError("Abstract method: must be overridden in a subclass");
		}
 
		protected function loadComHead(txtInfo:String):void
		{
			throw new IllegalOperationError("Abstract method: must be overridden in a subclass");
		}
 
		protected function loadCom(txtInfo:String):void
		{
			throw new IllegalOperationError("Abstract method: must be overridden in a subclass");
		}
 
		//Already Loaded
		protected function nowLoaded(e:Event):void
		{
			loadCheck = URLLoader(e.target);
			textFormat.font = "Arial Black";
			textFormat.size = 18;
			txtFld.type = TextFieldType.DYNAMIC;
			txtFld.width = 300;
			txtFld.wordWrap = true;
			txtFld.textColor = TEXTCOLOR;
			txtFld.defaultTextFormat = textFormat;
			txtFld.text = loadCheck.data;
			addChild(txtFld);
			txtFld.x = 128,txtFld.y = 10;
		}
 
		protected function nowType(e:Event):void
		{
			loadCheck = URLLoader(e.target);
			textFormat.font = "Arial Black";
			textFormat.size = 14;
			typeFld.type = TextFieldType.DYNAMIC;
			typeFld.width = 300;
			typeFld.wordWrap = true;
			typeFld.textColor = TYPECOLOR;
			typeFld.defaultTextFormat = textFormat;
			typeFld.text = loadCheck.data;
			addChild(typeFld);
			typeFld.x = 368,typeFld.y = 16;
		}
 
		protected function nowSumHead(e:Event):void
		{
			loadCheck = URLLoader(e.target);
			textFormat.font = "Arial Black";
			textFormat.size = 14;
			sumHeadFld.type = TextFieldType.DYNAMIC;
			sumHeadFld.width = 175;
			sumHeadFld.wordWrap = true;
			sumHeadFld.textColor = HEADCOLOR;
			sumHeadFld.defaultTextFormat = textFormat;
			sumHeadFld.text = loadCheck.data;
			addChild(sumHeadFld);
			sumHeadFld.x = 148,sumHeadFld.y = 409;
		}
 
		protected function nowSum(e:Event):void
		{
			loadCheck = URLLoader(e.target);
			textFormat.font = "Arial";
			textFormat.size = 12;
			sumFld.type = TextFieldType.DYNAMIC;
			sumFld.width = 200;
			sumFld.wordWrap = true;
			sumFld.textColor = BODYCOLOR;
			sumFld.defaultTextFormat = textFormat;
			sumFld.text = loadCheck.data;
			addChild(sumFld);
			sumFld.x = 148,sumFld.y = 431;
		}
 
		protected function nowVaryHead(e:Event):void
		{
			loadCheck = URLLoader(e.target);
			textFormat.font = "Arial Black";
			textFormat.size = 14;
			varyHeadFld.type = TextFieldType.DYNAMIC;
			varyHeadFld.width = 175;
			varyHeadFld.wordWrap = true;
			varyHeadFld.textColor = HEADCOLOR;
			varyHeadFld.defaultTextFormat = textFormat;
			varyHeadFld.text = loadCheck.data;
			addChild(varyHeadFld);
			varyHeadFld.x = 684,varyHeadFld.y = 409;
		}
 
		protected function nowVary(e:Event):void
		{
			loadCheck = URLLoader(e.target);
			textFormat.font = "Arial";
			textFormat.size = 12;
			varyFld.type = TextFieldType.DYNAMIC;
			varyFld.width = 175;
			varyFld.wordWrap = true;
			varyFld.textColor = BODYCOLOR;
			varyFld.defaultTextFormat = textFormat;
			varyFld.text = loadCheck.data;
			addChild(varyFld);
			varyFld.x = 684,varyFld.y = 431;
		}
 
		protected function nowUsesHead(e:Event):void
		{
			loadCheck = URLLoader(e.target);
			textFormat.font = "Arial Black";
			textFormat.size = 14;
			usesHeadFld.type = TextFieldType.DYNAMIC;
			usesHeadFld.width = 175;
			usesHeadFld.wordWrap = true;
			usesHeadFld.textColor = HEADCOLOR;
			usesHeadFld.defaultTextFormat = textFormat;
			usesHeadFld.text = loadCheck.data;
			addChild(usesHeadFld);
			usesHeadFld.x = 148,usesHeadFld.y = 504;
		}
 
		protected function nowUses(e:Event):void
		{
			loadCheck = URLLoader(e.target);
			textFormat.font = "Arial";
			textFormat.size = 12;
			usesFld.type = TextFieldType.DYNAMIC;
			usesFld.width = 175;
			usesFld.wordWrap = true;
			usesFld.textColor = BODYCOLOR;
			usesFld.defaultTextFormat = textFormat;
			usesFld.text = loadCheck.data;
			addChild(usesFld);
			usesFld.x = 148,usesFld.y = 528;
		}
 
		protected function nowCodeHead(e:Event):void
		{
			loadCheck = URLLoader(e.target);
			textFormat.font = "Arial Black";
			textFormat.size = 14;
			codeHeadFld.type = TextFieldType.DYNAMIC;
			codeHeadFld.width = 175;
			codeHeadFld.wordWrap = true;
			codeHeadFld.textColor = HEADCOLOR;
			codeHeadFld.defaultTextFormat = textFormat;
			codeHeadFld.text = loadCheck.data;
			addChild(codeHeadFld);
			codeHeadFld.x = 350,codeHeadFld.y = 409;
		}
 
		protected function nowCode(e:Event):void
		{
			loadCheck = URLLoader(e.target);
			textFormat.font = "Courier New";
			textFormat.size = 12;
			codeFld.type = TextFieldType.DYNAMIC;
			codeFld.width = 323;
			codeFld.height = 215;
			codeFld.wordWrap = true;
			codeFld.textColor = BODYCOLOR;
			codeFld.defaultTextFormat = textFormat;
			codeFld.text = loadCheck.data;
			addChild(codeFld);
			codeFld.x = 350,codeFld.y = 430;
		}
 
		protected function nowComHead(e:Event):void
		{
			loadCheck = URLLoader(e.target);
			textFormat.font = "Arial Black";
			textFormat.size = 14;
			comHeadFld.type = TextFieldType.DYNAMIC;
			comHeadFld.width = 175;
			comHeadFld.wordWrap = true;
			comHeadFld.textColor = HEADCOLOR;
			comHeadFld.defaultTextFormat = textFormat;
			comHeadFld.text = loadCheck.data;
			addChild(comHeadFld);
			comHeadFld.x = 684,comHeadFld.y = 458;
		}
 
		protected function nowCom(e:Event):void
		{
			loadCheck = URLLoader(e.target);
			textFormat.font = "Arial";
			textFormat.size = 12;
			comFld.type = TextFieldType.DYNAMIC;
			comFld.width = 242;
			comFld.height = 164;
			comFld.wordWrap = true;
			comFld.textColor = BODYCOLOR;
			comFld.defaultTextFormat = textFormat;
			comFld.text = loadCheck.data;
			addChild(comFld);
			comFld.x = 684,comFld.y = 480;
		}
		//Load Image
		protected function loadImg(img:String):void
		{
			throw new IllegalOperationError("Abstract method: must be overridden in a subclass");
 
		}
	}
}

Each implemented method works the same. It gets the Event instance from the loading sequence (implemented in the Catalog class—a Concrete Product) and then puts it where it belongs and formats it.

Finally, the ConcreteProduct is the Catalog class. It loads all of the materials it needs and then uses the methods it inherited from the Product class to place the text and graphic.

?View Code ACTIONSCRIPT
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
package
{
	import flash.net.URLRequest;
	import flash.display.Loader;
	import flash.net.URLRequest;
	import flash.net.URLLoader;
	import flash.events.Event;
 
	public class Catalog extends Product
	{
		private var dp:String;
		private var nameText:String;
		private var typeText:String;
		private var sumHead:String;
		private var sumText:String;
		private var varyHead:String;
		private var varyText:String;
		private var usesHead:String;
		private var usesText:String;
		private var codeHead:String;
		private var codeText:String;
		private var comHead:String;
		private var comText:String;
		private var dpImage:String;
		private var url:URLRequest;
		private var loader:Loader;
		private var fileNow:URLRequest;
		private var txtLoader:URLLoader;
		private var typeLoader:URLLoader;
		private var sumHeadLoader:URLLoader;
		private var sumLoader:URLLoader;
		private var varyHeadLoader:URLLoader;
		private var varyLoader:URLLoader;
		private var usesHeadLoader:URLLoader;
		private var usesLoader:URLLoader;
		private var codeHeadLoader:URLLoader;
		private var codeLoader:URLLoader;
		private var comHeadLoader:URLLoader;
		private var comLoader:URLLoader;
		private var loadCheck:URLLoader;
 
		public function Catalog(dp:String)
		{
			this.dp=dp;
			dp+="/";
			nameText = dp + "name.txt";
			typeText = dp + "type.txt";
			sumHead = dp + "sumhead.txt";
			sumText = dp + "summary.txt";
			varyHead = dp + "varyhead.txt";
			varyText = dp + "vary.txt";
			usesHead = dp + "useshead.txt";
			usesText = dp + "uses.txt";
			codeHead = dp + "codehead.txt";
			codeText = dp + "code.txt";
			comHead = dp + "comhead.txt";
			comText = dp + "com.txt";
			dpImage = dp + "diagram.png";
 
			//All of these function are below
			loadInfo(nameText);
			loadType(typeText);
			loadSumHead(sumHead);
			loadSum(sumText);
			loadVaryHead(varyHead);
			loadVary(varyText);
			loadUsesHead(usesHead);
			loadUses(usesText);
			loadCodeHead(codeHead);
			loadCode(codeText);
			loadComHead(comHead);
			loadCom(comText);
			loadImg(dpImage);
		}
 
		override protected function loadInfo(txtInfo:String):void
		{
			txtLoader = new URLLoader();
			txtLoader.addEventListener(Event.COMPLETE,nowLoaded);
			fileNow = new URLRequest(txtInfo);
			txtLoader.load(fileNow);
		}
 
		override protected function loadType(txtInfo:String):void
		{
			typeLoader = new URLLoader();
			typeLoader.addEventListener(Event.COMPLETE,nowType);
			fileNow = new URLRequest(txtInfo);
			typeLoader.load(fileNow);
		}
 
		override protected function loadSumHead(txtInfo:String):void
		{
			sumHeadLoader = new URLLoader();
			sumHeadLoader.addEventListener(Event.COMPLETE,nowSumHead);
			fileNow = new URLRequest(txtInfo);
			sumHeadLoader.load(fileNow);
		}
 
		override protected function loadSum(txtInfo:String):void
		{
			sumLoader = new URLLoader();
			sumLoader.addEventListener(Event.COMPLETE,nowSum);
			fileNow = new URLRequest(txtInfo);
			sumLoader.load(fileNow);
		}
 
		override protected function loadVaryHead(txtInfo:String):void
		{
			varyHeadLoader = new URLLoader();
			varyHeadLoader.addEventListener(Event.COMPLETE,nowVaryHead);
			fileNow = new URLRequest(txtInfo);
			varyHeadLoader.load(fileNow);
		}
 
		override protected function loadVary(txtInfo:String):void
		{
			varyLoader = new URLLoader();
			varyLoader.addEventListener(Event.COMPLETE,nowVary);
			fileNow = new URLRequest(txtInfo);
			varyLoader.load(fileNow);
		}
 
		override protected function loadUsesHead(txtInfo:String):void
		{
			usesHeadLoader = new URLLoader();
			usesHeadLoader.addEventListener(Event.COMPLETE,nowUsesHead);
			fileNow = new URLRequest(txtInfo);
			usesHeadLoader.load(fileNow);
		}
 
		override protected function loadUses(txtInfo:String):void
		{
			usesLoader = new URLLoader();
			usesLoader.addEventListener(Event.COMPLETE,nowUses);
			fileNow = new URLRequest(txtInfo);
			usesLoader.load(fileNow);
		}
 
		override protected function loadCodeHead(txtInfo:String):void
		{
			codeHeadLoader = new URLLoader();
			codeHeadLoader.addEventListener(Event.COMPLETE,nowCodeHead);
			fileNow = new URLRequest(txtInfo);
			codeHeadLoader.load(fileNow);
		}
 
		override protected function loadCode(txtInfo:String):void
		{
			codeLoader = new URLLoader();
			codeLoader.addEventListener(Event.COMPLETE,nowCode);
			fileNow = new URLRequest(txtInfo);
			codeLoader.load(fileNow);
		}
 
		override protected function loadComHead(txtInfo:String):void
		{
			comHeadLoader = new URLLoader();
			comHeadLoader.addEventListener(Event.COMPLETE,nowComHead);
			fileNow = new URLRequest(txtInfo);
			comHeadLoader.load(fileNow);
		}
 
		override protected function loadCom(txtInfo:String):void
		{
			comLoader = new URLLoader();
			comLoader.addEventListener(Event.COMPLETE,nowCom);
			fileNow = new URLRequest(txtInfo);
			comLoader.load(fileNow);
		}
 
		//Load image
		override protected function loadImg(dpImage:String):void
		{
			url = new URLRequest(dpImage);
			loader=new Loader();
			loader.load(url);
			addChild(loader);
			loader.x = 128,loader.y = 34;
		}
	}
}

That’s the whole enchilada, and it is a big one. Both of the product classes are much bigger than I like, but the nature of the application requires it. However, even with all of the methods and instances in two different Factory Method class sets, there’s only a single conditional statement, and it’s in the Client—where it doesn’t count as part of the design pattern. (I could even eliminate it if I put in a dummy display sprite—but why go fanatic?)

Finishing Up

All that’s left are 17 more design patterns and some kind of splash page. I think that the splash page should have the different elements of the UML class diagrams—what the different arrows and symbols mean. If you can think of anything else, let us know. Also, play around with the AIR version and let me know if you have any additional features that you think would help. Also, if you want to pitch in and help fill in the different design patterns data, contact me and I’ll be glad to recruit you! (Is there such a thing as an online Hero Medal?)

Share

Related posts:

  1. Take a Design Pattern to Work Part IV: Establishing a Design Pattern Foundation
  2. Deciding on a Design Pattern: A Graphic and Text Catalog
  3. The Developing an AIR ActionScript 3.0 Design Pattern Catalog and the AIR Magic Table
Categories: Catalog, Factory Method, Tools
  1. catalog
    July 15, 2009 at 3:09 pm | #1

    hi,

    how about putting all the text data in a single xml file (or one xml file per design pattern) with different nodes for the different text types? and maybe a css style file with all text formating stuff. that would be much cleaner than a multitude of plain txt files and a lot of duplicated code with URLLoaders and textfield creation…

    and further I hope that you are going to put in all the design pattern data for us as I think a “do it yourself” empty AIR app would be not very appealing and helpful for most users ;)

  2. July 15, 2009 at 5:10 pm | #2

    Hi Mystery Person,

    I had thought of using XML files, but another project I am working uses XML files, and I felt better about using text files for this one. However, I still think it’s a good idea and it wouldn’t be a lot of work if you revised the Catalog project and re-did it with XML files. Please do so and send us your results. It would be dynamite!

    As for this project and getting help I was sort of hoping that we’d get some better graphics for the Class Diagrams. Also, doing some of the grunt work on the information for the classes is just a matter of dropping it into a text file. I’ll take any help I can get still, but I won’t force you to do them all yourself.

    Thanks for your great comment, and I hope to see your XML file idea put into action.

    Kindest regards,
    Bill

  1. No trackbacks yet.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>