Gentle Reader:This is Part 3 of a four-part series of posts on introducing design patterns and OOP into the work place. Reading Parts 1 and 2 will provide the context for this part. Also, taking a look at No Time for OOP and Design Patterns will give you the background on this series. More so than most posts, we invite your comments.
Doing the Loosen Up
Few of you remember Archie Bell and the Drells, but their song, Tighten Up was a big hit back in the day. With design patterns, we want to do the opposite, Loosen Up. At this point, we’re going to do the Loosen Up. So put on your dancing shoes and look at the post No New is Good New. The purpose of the post is to get us to think about relationships between objects in a programming design. The dictum, program to an interface and not an implementation is invoked, and the post discusses different kinds of relationships found in design pattern diagrams. If you’re not sure about the issues involved, that post will help understand the next step in introducing design patterns to work.
At this stage in the series, we have arrived at one of the pillars of OOP, inheritance. Figure 1 shows a simple diagram of where we are now in refactoring the original application that used ActionScript on the Timeline.

Figure 1: Inheritance from a parent class
As you saw, inheritance allows developers to use the properties and methods of existing classes and in so doing saves time and adds consistency. However, a standard inheritance model also requires the client to instantiate all of the child classes that must be used. True, the instantiation can be through the parent class by initially typing the objects as the parent class rather than the child class as the following shows:
private var hci:Staff;
hci = new HCI();
The purpose of instantiating the parent is to make the link more general and flexible without breaking encapsulation. If the parent class changes, the objects typed to the parent have a better chance of working well without modification.
As noted in the post about using the new statement, each new statement may limit your flexibility. If a change is made to the object, your Client or some other part of your program may have to be modified to accommodate the change. One way to deal with that is to follow the dictum,
Identify the aspects that vary and separate them from what stays the same
So what varies in the program? That’s easy—the staff does. The Client chooses one of three Staff types (children). So how do we separate them? One solution is the use of a simple factory. Basically, a simple factory separates the Client from the instantiation process. Whatever you want, you ask the simple factory instead of instantiating the requested object. The Client instantiates a single factory object, and the factory object instantiates the objects by the Client. In that way, the Client needs to only instantiate a single object rather than any number made up of the child subclasses. Figure 2 shows this new model:

Figure 2: Adding a Simple Factory
At this point, you may be thinking, finally a design pattern! However, the simple factory is not a design pattern but instead a programming operation or mode. As we will see, the simple factory can be used in a Factory Method design pattern, but it’s also used in the Flyweight pattern. Some of the other operations you will find with design pattern names include singleton, observer and template method. (See pp. 66 to 68 for an introduction to the concepts at work here in the factory. Also, Chapter 9 explains the template method as an operation and a design pattern.)
By focusing on the more specific operation instead of the entire design pattern, we’re better able to clearly see what the operation is up to. If you understand the operations, you can more easily introduce them into the workplace as a simple and useful tool. The important task is create a site with as few locked up relations as possible. Do the Loosen Up.
Separating the Parts that Vary from those that Stay the Same
The Client in the example program has the following operation to select among the available choices:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | staffNow = e.target.label.toLowerCase(); switch (staffNow) { case "developer" : develop = new Developer(); addChild(develop); lastClass = develop; break; case "designer" : design = new Designer(); addChild(design); lastClass = design; break; case "hci" : hci = new HCI(); addChild(hci); lastClass = hci; break; } |
By removing this portion of the code from the Client and moving it to a simple factory class, we can extract just the part where change occurs. The following code shows this new Factory class:
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 | package { import flash.display.Sprite; public class Factory { private var design:Staff; private var develop:Staff; private var hci:Staff; public function makeStaff(staffNow:String):Sprite { switch (staffNow) { case "designer" : return ( new Designer() ); break; case "developer" : return ( new Developer() ); break; case "hci" : return ( new HCI() ); break; default : return null; } } } } |
Note that the private variables with the names of the requested objects are also moved to the Factory. The Client no longer needs them because the Factory is going to be doing the instantiation. Now that the changing aspects were removed from the Client class, we’ll change the Client to make the requests from the Factory class.
Before doing that though, note that the makeStaff() method returns a Sprite instead of the class object. Chandima suggested this because you will be able to place it on the stage. Otherwise, you’d have to use a bit more convoluted approach (which I unfortunately mastered) to insure that the graphics and text appear on the page. Now, in looking at the Client, we see only a single Factory instance instantiated instead of three Staff classes:
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 | package { import flash.display.Sprite; import fl.controls.Button; import flash.events.MouseEvent; //Client Class public class Client extends Sprite { private var logo:Sprite = new Logo(); private var splash:Sprite = new Splash(); private var desBtn:Button = new Button(); private var devBtn:Button = new Button(); private var hciBtn:Button = new Button(); private var staffNow:String; private var staffDisplay:Sprite; private var factory:Factory=new Factory(); public function Client() { desBtn.label = "Designer"; desBtn.addEventListener(MouseEvent.CLICK,selectStaff); addChild(desBtn); desBtn.x = 424,desBtn.y = 66; devBtn.label = "Developer"; devBtn.addEventListener(MouseEvent.CLICK,selectStaff); addChild(devBtn); devBtn.x = 424,devBtn.y = 116; hciBtn.label = "HCI"; hciBtn.addEventListener(MouseEvent.CLICK,selectStaff); addChild(hciBtn); hciBtn.x = 424,hciBtn.y = 166; logo.x = 16,logo.y = 16; logo.width = 150,logo.height = 121.5; addChild(logo); splash.x = 32,splash.y = 168; addChild(splash); } private function selectStaff(e:MouseEvent):void { splash.visible=false; staffNow = e.target.label.toLowerCase(); if (staffDisplay) { removeChild(staffDisplay); } staffDisplay = factory.makeStaff(staffNow); addChild(staffDisplay); } } } |
Now suppose that the Staff and the Staff child classes all change. What’s going to happen to the Client? Nothing. All the Client is requesting and the Factory returning is a Sprite. So the Staff and its children classes can change all they want. The Client needs to change nothing. In addition, the Client only instantiates a single instance; not of the Staff class but of the Factory. The following code is the Staff class and its children.
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 | //Staff Class package { import flash.display.Loader; import flash.net.URLRequest; import flash.net.URLLoader; import flash.display.Sprite; import flash.text.TextField; import flash.events.Event; import flash.text.TextFieldType; import flash.text.TextFormat; //Parent class public class Staff extends Sprite { private var loader:Loader; private var url:URLRequest; private var fileNow:URLRequest; private var txtLoader:URLLoader; private var loadCheck:URLLoader; private var textField:TextField = new TextField(); private var textFormat:TextFormat = new TextFormat(); public function Staff() { textField.type = TextFieldType.DYNAMIC; textField.wordWrap = true; textField.textColor = 0x007700; textFormat.font = "Arial Black"; textFormat.size = 16; textField.defaultTextFormat = textFormat; } protected function loadInfo(txtInfo:String):void { txtLoader = new URLLoader(); txtLoader.addEventListener(Event.COMPLETE,nowLoaded); fileNow = new URLRequest(txtInfo); txtLoader.load(fileNow); } private function nowLoaded(e:Event):void { loadCheck = URLLoader(e.target); textField.text = loadCheck.data; textField.width = 200; addChild(textField); textField.x = 180,textField.y = 331; } protected function loadImg(img:String):void { url = new URLRequest(img); loader=new Loader(); loader.load(url); addChild(loader); loader.x = 150,loader.y = 130; } } } //Child classes //Designer package { public class Designer extends Staff { private var staffText:String; private var staffImg:String; public function Designer() { staffText = "text/designer.txt"; staffImg = "images/designer.png"; loadInfo(staffText); loadImg(staffImg); } } } //Developer package { public class Developer extends Staff { private var staffText:String; private var staffImg:String; public function Developer() { staffText = "text/developer.txt"; staffImg = "images/developer.png"; loadInfo(staffText); loadImg(staffImg); } } } //HCI package { public class HCI extends Staff { private var staffText:String; private var staffImg:String; public function HCI() { staffText = "text/hci.txt"; staffImg = "images/hci.png"; loadInfo(staffText); loadImg(staffImg); } } } |
As you can see, the Staff class and its children are almost identical to the previous incarnations in Part II of this series. The child classes were changed to include private variables and the invocations of the main operations appear far more polymorphic (they’re all identical), but those changes are just cosmetic to reinforce OOP thinking. Also, a subtle but important change is in changing the typing of the logo and splash page to Sprites type in the Client. This provides an opportunity for you to see if you can work out the operations needed to click the logo and have the splash page appear. Of course, you’ll want to move the request to the Factory class, and if you can do this, you probably are well on your way to sneaking in some good OOP and a pre-design pattern mode into the workplace. Click the button to download the entire application:
Playing Nicely in the Sandbox
Several years back a hugely talented artist and I worked together on a project. It began as a mutual admiration relationship and ended in the worse case of angst and misery I can remember. Neither of us liked the other at the end of the project, and the project suffered because of our conflict. To this day I regret the relationship’s destruction. For lack of a better explanation, we had two diametrically opposed ideas of what would best serve the goals of the project and we both assumed that the other was seeking the same goal as we were.
He created animations using Flash and included ActionScript on the Timeline, in buttons, in movie clips and God knows where else. (I don’t think I ever found them all.) Naturally, the Flash app kept growing and the pre-loader I made had to dance the dance of the seven veils to keep the viewer from desperately hammering the Back button. The Library was full of Tween symbols (Tween 1, Tween 2, etc.) that meant something was moved before it was converted to a symbol or some other screw up. Undaunted, the artist soldiered on and eventually created a huge animation that was a wonder to behold. (Of course you could rotate the tires on your car while waiting for the SWF to load.)
The introductory animation was exactly what the clueless project manager had wanted. (I think he said something like, “Dazzle me!”) Unfortunately, after viewing this dazzling behemoth a couple of times, it lost its charm and so as is often the case, the project had a big fat white elephant sitting at the doorstep to be side stepped with a Skip Intro button.
I could go on and on, but the purpose is not to tell tales of woe about non-developers in real world project development. As many of you must know, working in jobs with projects and datelines is more complex than simply putting together good code. For me, the three key elements for a successful Web site are:
- Good graphics (visible)
- Good UI (visible)
- Good Programming (invisible)
Jennifer Tidwell (who rudely completed degrees from both MIT and Massachusetts College of Art just to make the rest of us look bad) found that good graphics were seen as the most trustworthy element of a Web site. So whether we like it or not, we have to have sites with good graphics, and if you’re a developer, assume you have no graphic or artistic skills. (I know of exceptions—like Jennifer—, and if you’re one of them, you don’t need to tell me.) The fact of the matter is we should do everything we can to use our programming skills to ensure that the graphics can be viewed as intended by the artist. Part of that task may be making sure that the artists keep their mitts off the code.
A few years ago I went to an HCI meeting in London. Two things came out of that meeting. First, HCI is essential to a successful Web site. Second, the HCI folks feel that they do not get the respect they deserve. In fact, they feel that they get none at all. UI and navigation needs to be well planned and coded. Coding HCI is like anything else, and it can get seriously complex with a big online business site. Given that design patterns and OOP have their greatest value with large-scale projects that are constantly changing, if you find the right pattern with the UI system, you’ll be a happy developer and so will the HCI folks.
The biggest enemies of good HCI are graphic artists. Seriously. A graphic artist gets tied into looking good and the HCI folks into finding stuff. A few years ago MOMA (New York City’s Museum of Modern Art) had a Web site with a navigation system that looked like a Rubik’s Cube and was about as easy to use. Each block in the cube was an unlabelled trigger and when you clicked on it, you were given a popup telling you what you’ve found. (This occurs shortly before you hit the back button on your browser.) The folks at MOMA probably listened to someone who convinced them that people love to explore Websites. Oddly, the site functioned spiffily which indicated some good code under the hood. So for users who had nothing to do for the rest of their lives, they could explore MOMA’s Rubik navigation system. Since then they discovered that patrons of the arts need to find where they can donate money and art shoppers need to find stuff to buy. If you go to the site now, you’ll see the war between the dancing baloney that makes up the header (unfortunately done in Flash), and the Puritanical UI that allows you to find stuff. (Imagine the discussions that must go on at that site between designers, developers and HCI folks! And you thought you had problems.)
Not Sucking
If you have nothing better to do (and the fact that you’re reading this blog indicates as much), pay a visit to Web Pages that Suck. While the keeper of the site prides himself on being the august voice of good Web sites, his own site suffers from ambiguity. Nevertheless, he has a real knack for identifying bad Web sites, and if you dig around you’ll find some good tips on navigation and making Web sites that work—actually avoiding ones that don’t work. He coined the term Mystery Meat Navigation and his examples of such navigation reinforce the necessity for good HCI people on board your staff. (However, the guy becomes almost apoplectic over Flash, so be forewarned.)
So what does this all have to do bringing a design pattern and good OOP practices to work? Everything! You have to deal realistically with people who have their hands full. Your paycheck and your programming skills are tied to their success. By starting with a few good OOP practices you can work your way to the doorstep of design patterns to improve your code at work. You have to work with designers and HCI folks to create good Website; so be aware of what they must accomplish. By the same token, you need to develop good code to present attractive graphics and for the navigation system to operate smoothly. So while helping others in your workaday mix to accomplish their goals, don’t forget your own.

The Take a Design Pattern to Work Part III : Loosening Up by William B. Sanders, unless otherwise expressly stated, is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.
Related posts:


Bill Sanders
Nice read.
I think you should refactor your post to put the second part (Playing Nicely in the Sandbox) in its own post, to be consistant with the one topic / one post principle.
hehe
Keep on the good work
Hi Zedia,
Well, yeah, I suppose I could have done a better job tying in the second part with the first. I’m trying to keep the idea that the messy, busy, non-idealistic, practical world of getting stuff out the door is full of chaos. Into this, how can we introduce seamless practices that really do work to generate a structure that actually can handle the chaos.
There’s an old saying:
That’s the principle I blog with.
Take care,
Bill
I’ve always thought a site called “WebPagesThatSuck” should certainly suck — at least some, but not enough to really qualify for my own site. I don’t get apoplectic over Flash — I love National Geographic, for instance. I get apoplectic over badly implemented Flash like:
http://www.torchia.com/
http://www.zaha-hadid.com/
http://www.ushida-findlay.com/main.html
http://www.juliegarwood.com/
http://www.connextproject.com/
http://now.sprint.com/widget/
http://www.youtube.com/v/_lrTgbk55ZE
I think it’s wonderful you’re trying to teach people how to use Flash correctly. We need more like you.
Kind regards,
Vincent Flanders
Hi Vincent,
Since I’ve been going to your site for years, I have seen good examples where you have condemned Flash because of some idiotic use of it. (You had a tissy fit over the tool and not its user.) Also, the lame excuse that a site called “WebPagesThatSuck” should certainly suck is…well…lame. I cannot tell you how many times I’ve gone to your site to find good examples of something wrong in HCI and have been frustrated by the junkyard style navigation you have piled up over the years. I am afraid that your site represents the old saw,
Believe it or not, your site is far more valuable than you probably realize. It is a resource for overblown, thoughtless Websites that can be used as examples of horrible HCI and bloated designer/developer egos. As such, it’s an excellent learning tool. However, when I use it to illustrate a point and cannot find something because of the Where’s Waldo navigation system that has emerged over the years I’m caught up short.
I’m sure you’re familiar with Edward Tufte’s work, and you might want to consult it for some guidance for information design. Even better, read your own advice.
Your obedient servant,
Bill
Thank you so much for this wonderful series.
FYI
There is a typo on the simplefactory.zip download link (an extra char at the end).
Hi Eric,
Thanks for the heads up on the typo. I fixed it and added a button so that it’s easier for readers to see.
Kindest regards,
Bill