Design patterns describe problems and solutions that occur over and over again in software design and development. Several people have developed ''Pattern Catalogs'' which describe the essential characteristics of both the problems and solutions. One famous catalog is the book ''Design Patters: Elements of Reusable Object-Oriented Software'' by Gamma, Helm, Johnson, and Vlissides. Online resources include the Patterns Home Page. [http://www.hillside.net/patterns/] In general, the essential elements of a pattern are * Pattern name * Problem description * Solution elements * Consequences or trade-offs But most pattern catalogs also include code snippets to illustrate how you would implement a particular solution. The code can't really be used in a library, but it can serve as an example for other developers. Most of the code snippets are for C++, Java, or Smalltalk. (Most of the patterns are for Object Oriented analysis and design.) Here is a place to list [[incr Tcl] code snippets implementing typical OO concepts. The code for a Factory, for example, might not be obvious because Incr Tcl doesn't naturally support abstract classes. RWT -- January 31, 2001 ---- '''Abstract Factory''' The ''Abstract Factory'' is described by Gamma et. al.. The Incr Tcl implementation illustrates both abstract classes and pure virtual methods. An abstract class cannot be instantiated - only subclass objects may actually be created. A pure virtual method is undefined in the parent class, but ''must'' be defined in the subclass. This example was posted to the Incr Tcl mailing list by Chad Smith. (Thanks Chad!) itcl::class Factory { constructor {} { # Keep this class from being instantiated. if {[namespace tail [info class]] == "Factory"} { error "Error: can't create Factory objects - abstract class." } # Verify that the derived class has implemented the # "status" method. This simulates pure virtual methods # in itcl (though at run-time only). if {[$this info function status -body] == ""} { error "Error: method 'status' undefined." } } protected method status {} {} } % Factory #auto Error: can't create Factory objects - abstract class. % % itcl::class WidgetFactory {inherit Factory} % WidgetFactory #auto Error: method 'status' undefined. % itcl::class MyFactory { inherit Factory method status {} {puts MyFactory::status} } % MyFactory #auto myFactory0 ---- '''Factory Method''' The ''Factory Method'' is described by Gamma et. al.. The Incr Tcl implementation illustrates creation of an object in the parent namespace. Gamma describes other interesting applications of ''Factory Method'', such as delegating object creation to subclasses. But this example just focuses on creating and returning the object. In some primitive languages like C++ and Java (smile) the pointer or handle namespace is flat. All pointers are considered equal. But in Incr Tcl, each class and object exist in a namespace. Normally, an object will create, manipulate, and destroy "working" objects in the course of executing its methods. These working objects exist within the namespace of the creating object, so they don't interfere with anybody else. In the case of a ''Factory Method", however, you really want to create the new object in the namespace in which the factory is called. That might usually be the global namespace, but it could be elsewhere. Note that in this ''Factory Method'', we use the [uplevel] command to create the object in the calling namespace. itcl::class Product { public variable someInterestingStuff } itcl::class Creator { method createProduct { } { return [uplevel Product #auto] } } ---- '''Singleton''' The ''Singleton'' is described by Gamma et. al.. This code snippet was posted on the Incr Tcl mailing list by Mark Wilson. (Thanks Mark!) class Singleton { private common _instance {} ;# static instance variable # # Define a "static method" Instance. # proc Instance {} { if { $_instance == {} } { set _instance [Singleton ::#auto] } return $_instance } # end of Instance constructor {} { set caller [info level [expr [info level] - 1]] if ![string match "Singleton::Instance" $caller] { error "Class Singleton can not be directly instantiated - use Instance" } } } To instantiate the singleton, do: set s [Singleton::Instance] ---- LV: Anyone remember http://www-dse.doc.ic.ac.uk/%7Enp2/patterns/tcl/ , in which Nat Pryce started collecting Tcl patterns? Also see http://st-www.cs.uiuc.edu/users/patterns/patterns.html ... I've not heard from Nat recently. ---- See also [Design patterns in Tcl]