By Lon (Alonzo) Hosford
This is the print center Factory design pattern from chapter 2 of William Sanders and Chandima Cumaranatunge Actionscript 3.0 Design Patterns.
Learn More
This is an ActionScript project created in Flex Builder and updated to Flex Builder 4. Download the example code. You can build this with the free Flex SDK by using the code in the src folder. Same for Flash CS3 and CS4. You need to create a Flash Document in the src folder and set the document class to Chapter02_Factory_PrintCenters
. For your convenience you can download a Flash CS4 ready to go example.
This includes a basic Actionscript debugger console to display tracing statements on stage. Each class sends messages to the console to show their methods working. These messages help you follow the relationships in the Factory design pattern.
Application Class – Chapter02_Factory_PrintCenters
This is the client class. The class instantiates HighVolPrinterCenter
and LowVolPrinterCenter
classes and calls their print()
method inherited from the PrintCenter
class. The basic idea is the same as the minimalist example to uncouple the product classes from the clientInkJetPrintJob
and WorkgroupPrintJob
.
/**
* Demonstrates a more concrete example of decoupling the client, this file, from the products.
* In this case the products are print jobs on various printers. The print jobs are not coupled
* to the client. Clients interface with creator classes representing a type of print center.
* The product classes doing the work are created by the print center creator classes.
* <p>
* This is part one of the example.
* </p>
* */
package
{
import com.lonhosford.util.debug.lite.DebugConsole;
import flash.display.Sprite;
import printcenters.HighVolPrinterCenter;
import printcenters.LowVolPrinterCenter;
import printcenters.PrintCenter;
// {SET STAGE SIZE AND SPEED HERE}
[SWF(width=500, height = 300, frameRate = 30)]
public class Chapter02_Factory_PrintCenters extends Sprite
{
private var debugConsole:DebugConsole = DebugConsole.getInstance();
public function Chapter02_Factory_PrintCenters()
{
stage.addChild(debugConsole);
debugConsole.width = stage.stageWidth;
debugConsole.height = stage.stageHeight;
debugConsole.write("Actionscript 3.0 Design Patterns");
debugConsole.write("William Sanders & Chandima Cumaranatunge");
debugConsole.write("Chapter 2 Print Centers Example - Part 1");
debugConsole.write("\n");
debugConsole.write("\nPrint LongThesis.doc to high volume printer.");
var pcHighVol:PrintCenter = new HighVolPrinterCenter();
pcHighVol.print("LongThesis.doc");
debugConsole.write("\nPrint ShortVita.doc to low volume printer.");
var pcLowVol:PrintCenter = new LowVolPrinterCenter();
pcLowVol.print("ShortVita.doc");
}
}
}
PrintCenter Class
This class provides a “factory method” interface to each of its subclasses LowVolPrintCenter
and HighVolPrintCenter
. The line 25 shows the createPrintJob()()
method. The factory method cannot be called from a client class. The method throws an IllegalOperationError
to prevent that coding option.
[ad name=”Google Adsense”]
The createPrintJob()()
method returns a IPrintJob
interface. Each Creator subclass will return its own product all having a createPrintJob()()
method defined by the IPrintJob
interface discussed later in this post. This PrintCenter
class then uses the product class start()
method on line 19.
package printcenters
{
import flash.errors.IllegalOperationError;
/**
* Handles file printing.
* */
public class PrintCenter
{
public function PrintCenter()
{
}
/**
* Simulate printing a file.
* @param fileName Name of file to print.
* */
public function print(fileName:String):void
{
var printjob:IPrintJob = this.createPrintJob();
printjob.start(fileName);
}
/**
* Creates the IPrintJob products.
* @throws flash.errors.IllegalOperationError Must override in subclass.
* */
protected function createPrintJob():IPrintJob
{
throw new IllegalOperationError("PrintCenter.createPrintJob() - override in subclass");
return null;
}
}
}
LowVolPrinterCenter Class
This is a class the client classes use. The PrintCenter
super class contains the print()
method clients use to print a document. The LowVolPrinterCenter
then creates the correct IPrintJob
class to do the work. In this case it is the InkJetPrintJob
class. If programming requires using another IPrintJob class, the change does not impact the print()
method interface client classes use.
package printcenters
{
import com.lonhosford.util.debug.lite.Debugger;
/**
* LowVolPrinterCenter creator class
* */
public class LowVolPrinterCenter extends PrintCenter
{
private var debugger:Debugger = Debugger.getInstance();
public function LowVolPrinterCenter()
{
debugger.write("LowVolPrinterCenter() - This is a creator.")
}
/**
* Create InkJetPrintJob object.
* @return InkJetPrintJob
* */
override protected function createPrintJob():IPrintJob
{
debugger.write("LowVolPrinterCenter.createPrintJob()");
return new InkJetPrintJob();
}
}
}
HighVolPrinterCenter Class
This is a second subclass to the PrintCenter
class. It uses the IPrintJob
class WorkgroupPrintJob
.
package printcenters
{
import com.lonhosford.util.debug.lite.Debugger;
/**
* HighVolPrinterCenter creator class
* */
public class HighVolPrinterCenter extends PrintCenter
{
private var debugger:Debugger = Debugger.getInstance();
public function HighVolPrinterCenter()
{
debugger.write("HighVolPrinterCenter() - This is a creator.")
}
/**
* Create WorkgroupPrintJob object.
* @return WorkgroupPrintJob
* */
override protected function createPrintJob():IPrintJob
{
debugger.write("HighVolPrinterCenter.createPrintJob()");
return new WorkgroupPrintJob();
}
}
}
[ad name=”Google Adsense”]
Now there are two PrintCenter classes available to client programs. Both use the print()
method to print documents. Next we look at the IPrintJob
classes starting with the interface.
IPrintJob Interface
This interface defines one method start()
for all IPrintJob
classes to implement.
package printcenters
{
/**
* Sets the interface for print job product classes
* */
public interface IPrintJob
{
/**
* @param fileName Name of file to print.
* */
function start(fileName:String):void;
}
}
InkJetPrintJob Class
This class implements the IPrintJob
interface and includes the required start()
method on line 18.
package printcenters
{
import com.lonhosford.util.debug.lite.Debugger;
/**
* InkJetPrintJob product class
* */
internal class InkJetPrintJob implements IPrintJob
{
private var debugger:Debugger = Debugger.getInstance();
public function InkJetPrintJob()
{
debugger.write("InkJetPrintJob()")
}
/**
* Simulate starting an InkJetPrintJob
* @param fileName Name of file to print.
* */
public function start(fileName:String):void
{
debugger.write("InkJetPrintJob.start() - fileName:" + fileName);
}
}
}
WorkgroupPrintJob Class
Like the InkJetPrintJob
class this class implements the IPrintJob
interface and includes the required start()
method on line 18.
package printcenters
{
import com.lonhosford.util.debug.lite.Debugger;
/**
* WorkgroupPrintJob product class
* */
internal class WorkgroupPrintJob implements IPrintJob
{
private var debugger:Debugger = Debugger.getInstance();
public function WorkgroupPrintJob()
{
debugger.write("WorkgroupPrintJob()")
}
/**
* Simulate starting an WorkgroupPrintJob
* @param fileName Name of file to print.
* */
public function start(fileName:String):void
{
debugger.write ("WorkgroupPrintJob.start() - fileName:" + fileName);
}
}
}
Adding to the PrintCenter class
It is relatively easy to add another PrintCenter
class. Here is the FancyPrintCenter
class that creates the IProduct
class MultifunctionPrintJob
. Create the classes in the and see if you can add them to the application Chapter02_Factory_PrintCenters
class.
FancyPrinterCenter class
package printcenters
{
import com.lonhosford.util.debug.lite.Debugger;
/**
* FancyPrinterCenter creator class
* */
public class FancyPrinterCenter extends PrintCenter
{
private var debugger:Debugger = Debugger.getInstance();
public function FancyPrinterCenter()
{
debugger.write("FancyPrinterCenter() - This is a creator.")
}
/**
* Create IPrintJob object.
* @return MultiFunctionPrintJob
* */
override protected function createPrintJob():IPrintJob
{
debugger.write("FancyPrinterCenter.createPrintJob()");
return new MultiFunctionPrintJob();
}
}
}
MultiFunctionPrintJob class
package printcenters
{
import com.lonhosford.util.debug.lite.Debugger;
/**
* MultiFunctionPrintJob product class
* */
internal class MultiFunctionPrintJob implements IPrintJob
{
private var debugger:Debugger = Debugger.getInstance();
public function MultiFunctionPrintJob()
{
debugger.write("MultiFunctionPrintJob()")
}
/**
* Simulate starting an MultiFunctionPrintJob
* @param fileName Name of file to print.
* */
public function start(fileName:String):void
{
debugger.write ("MultiFunctionPrintJob.start() - fileName:" + fileName);
}
}
}
Part 2 introduces parameters for selection product classes.