Java:
/*
* GUIFactory example
*/
abstract class GUIFactory
{
public static GUIFactory getFactory()
{
int sys = readFromConfigFile("OS_TYPE");
if (sys == 0)
{
return new WinFactory();
}
else
{
return new OSXFactory();
}
}
public abstract Button createButton();
}
class WinFactory extends GUIFactory
{
public Button createButton()
{
return new WinButton();
}
}
class OSXFactory extends GUIFactory
{
public Button createButton()
{
return new OSXButton();
}
}
abstract class Button
{
public abstract void paint();
}
class WinButton extends Button
{
public void paint()
{
System.out.println("I'm a WinButton: ");
}
}
class OSXButton extends Button
{
public void paint()
{
System.out.println("I'm a OSXButton: ");
}
}
public class Application
{
public static void main(String[] args)
{
GUIFactory factory = GUIFactory.getFactory();
Button button = factory.createButton();
button.paint();
}
// Output is either:
// "I'm a WinButton:"
// or:
// "I'm a OSXButton:"
}
[edit] C#
/*
* GUIFactory example
*/
abstract class GUIFactory
{
public static GUIFactory GetFactory()
{
int sys = ReadFromConfigFile("OS_TYPE");
if (sys == 0)
{
return new WinFactory();
}
else
{
return new OSXFactory();
}
}
public abstract Button CreateButton();
}
class WinFactory : GUIFactory
{
public override Button CreateButton()
{
return new WinButton();
}
}
class OSXFactory : GUIFactory
{
public override Button CreateButton()
{
return new OSXButton();
}
}
abstract class Button
{
public string Caption;
public abstract void Paint();
}
class WinButton : Button
{
public override void Paint()
{
Console.WriteLine("I'm a WinButton: " + Caption);
}
}
class OSXButton : Button
{
public override void Paint()
{
Console.WriteLine("I'm a OSXButton: " + Caption);
}
}
class Application
{
static void Main()
{
GUIFactory factory = GUIFactory.GetFactory();
Button button = factory.CreateButton();
button.Caption = "Play";
button.Paint();
}
// Output is either:
// "I'm a WinButton: Play"
// or:
// "I'm a OSXButton: Play"
}
Scheme:
;; this is the straight port:
(define (make-factory)
(case (magically-read-os-symbol)
((win95) (win95-factory))
((plan9) (plan9-factory))))
(define (win95-factory)
make-win95-button)
(define (plan9-factory)
make-plan9-button)
(define (make-plan9-button)
(lambda () (print "I'm button on plan 9 from bell labs")))
(define (make-win95-button)
(lambda () (print "I'm button on windows 95")))
;; app usage:
(((make-factory))) ; the first call makes the factory, the second makes the button, the third calls the button.
This is another version with duplication removed:
(define (make-factory)
(lambda ()
(make-button (magically-read-os-symbol))))
;; the button-maker can be separated on any level; to remove
;; duplication bring it closer (like the example below, to add
;; separation bring it further apart (like dispatching to return
;; separate top-level defines instead of one lambda)
(define (make-button os)
(lambda ()
(print "I'm a button on "
(case os
((win95) "windows 95")
((plan9) "plan 9 from bell labs")))))
;;; app usage:
(((make-factory))) ; ; the first call makes the factory, the second makes the button, the third calls the button.