|
Home Page Climbing Programming Biking Running Web In this section |
I was designing a software module for my employer recently and was given the name of an individual who, I was told, would be able to help me. In explaining the domain I was attempting to model he began saying things like: "That sounds like a mdel-controller-viewer pattern" or "That'll be a Singleton" in reply. As work progressed I began to see that patterns were nothing more than an abstract design. Admittedly some appeared very abstract but none the less there was a link, albeit tenuous between this strange jargon and what I was attempting to design. One problem was that all the descriptions of patterns centered around OO languages such as C++ or Java. Now I have done some programming in those languages but my skillset in them is hardly up to industrial strength. So not only had I to understand the patterns I also had to understand the OO jargon they were being described in. Everything did click into place though. So, what is a pattern? Well as with many things in software it did not originate in computer science, this idea came from architecture. The basic definition is that it is a generalised, abstract design. Whereas often a design is wedded to a particular problem or domain, a pattern is the recognition that many designs are not unique, though the problems they attempt to solve are, and have a general, well, "pattern". The patterns range from the simple to the complex. Some are only really applicable to OO languages that have the built-in operators and language constructs to perform; some are possible in languages such as C with some hard work; the remainder may be applied to all languages The following list is an attempt to describe some of the standard patterns in C. We start with the simplest and proceed from there. In the course of implementing my original module I moved my style of writing C programs from a structured, modular style to one that imitates an object oriented style. I say "imitated" as the extras that you get for free in a language such as C++ have to be done explitly in C. An example of this is the "new" operator. This comes about partly as a result of function overloading, you declare new on a type and code is generated that creates that type, initialised to your wish. In C you have to write the constructor and initialisation functions yourself, giving them unique names within your code. In the following code snippets rather than declare a specific class, oops dropped into OO speak there!, the generic type " T* " is used to indicate a pointer to an opaque type(object). Substitute what type you will. SingletonThe Singleton is one of the patterns in the GOF book. The Singleton is used when you want only one of something, even though many parts of your code may try to create it, you only WANT one! An example would be manager code for windowing system or a memory manager. There is no point in having two of either of these, all hell would break loose! The method of achieving this is remarkably similar in both OO languages and non-OO ones.
static T *instance = 0;
T* T_instance(void)
{
if(!instance)
{
instance = T_new();
}
return instance;
}
See, I told you it was simple! The code above creates a pointer to the required opaque type the first time that it is called. From that time onwards it will return the same pointer rather than create a new one. This of course assumes that nowhere in the rest of the code is T_new() called. In fact one of the constraints on the Singleton pattern is that whenever one is required the T_instance function or method is called and not the T_new() method. Of course the singleton in your code may have more methods than _new, _instance and _delete! In order to access the singleton the following means allows the methods to avoid having to have maintain an external reference to the instance of the singleton. Which of course would be against the idea of it!
void T_someMethod(T *self)
{
if(self)
{
/* Do whatever you want to do here */
}
return;
}
And a typical call would be: T_someMethod(T_instance()); There is a slight inefficiency here in that each time a method of the singleton is called the _instance method must be used as (one of) the parameter(s). This is because we should not keep references to singletons so must retrieve the original reference each time we wish to use it. |
|