Archive for the 'Patterns & Practices' Category

When to use "static"?

Contents

  • Introduction.
  • A C++ reference on “static”.
  • “Const” vs. “Static”.
  • C# “static”.
  • Conclusion.
  • References.

Introduction

This article is the outcome of a question that popped up in my mind when I was dealing with Factories and (therefore, together with) Singletons. One of the technologies I’m currently working on is the Composite Application Block (CAB) and the Smart Client Software Factory (SCSF). I mentioned this as in the CAB/SCSF there are functional classes called Services, which are allocated in containers (called WorkItems, but I mention the name just for reference) distributed in a tree-like hierarchy (from a root WorkItem to child WorkItems).

Services are treated liked Singletons: only one instance of a Service is available during the lifetime of a specific WorkItem. Moreover, once a child WorkItem is added (to the parent’s WorkItems collection), all Services are percolated to the Service collection of the child. So, a Service registered in the root is available throughout the whole application until the root WorkItem is terminated (which will occur once the application is ended). However, Services are not static nor follow the Singleton pattern (for a quick glimpse on the Singleton pattern click here)!

The bolded and underlined line is one of the reasons that moved me to start investigating on “static” (the other one, is Factories and its implementation as Singletons, which I’ll discuss in a next post :) ). The reason for this is that each child WorkItem may override a specific Service that is passed (from its parent WorkItem) into its Service collection, so, now, we may have more than one instance of a given Service type throughout the whole application, but there still can be one and only one instance of a Service in a specific WorkItem (I think this is the scope of “Singleton Service” in CAB/SCSF). Besides, Services are not static as they can be added and removed from the WorkItem at any time.

Enough of this introduction! Let’s get into the core subject! :)

A C++ reference on “static”

The static keyword specifies that the variable has static duration (it is allocated when the program begins and deallocated when the program ends) and initializes it to 0 unless another value is specified. So, as a descriptive term it refers to the lifetime of memory or storage locations, which I’ll mention the following types:

  • static
  • dynamic (heap)
  • auto (stack)

Static storage refers to memory locations that persist for the life of the program (i.e.: global variables), while stack storage comes and goes as functions are called (the call stack composed by “stack frames” corresponding to subroutine calls), and heap storage refers to memory locations allocated and deallocated using operators new and delete.

Objects and variables defined outside all blocks have static lifetime and external linkage (its name is visible from files other than the one in which it’s defined) by default, while a global object or variable that is explicitly declared as static has internal linkage (the names of objects and functions refer only to program elements inside their own translation units, they are not shared with other translation units).

Moreover, static can also be used in terms of visibility of objects. For example:

static int _number = 2;

means that _number is not visible outside the source file it was defined. When modifying a variable or function at file scope, the static keyword specifies that the variable or function has internal linkage. However, static meaning “local to a file”  has turned obsolete with the introduction of C++ namespaces, as an unnamed namespace is used to wrap the static declarations (some more info here).

Using C++, it is possible to have static members of a class which are shared across all object instances of that class.

class MyClass {
public:
    static int _id;
    static void sharedFunction();
};

int MyClass::_id = 0;
void MyClass::sharedFunction() {}

When modifying a data member in a class declaration, the static keyword specifies that one copy of the member is shared by all instances of the class (which must be initialized at file scope).

In the example above, once the data member MyClass::_id is set to 0, that value will be shared among all object instances of MyClass. So, in recursive code, a static object or variable is guaranteed to have the same state in different instances of a block of code, which can be useful to share information between object instances.

When modifying a member function in a class declaration, the static keyword specifies that the function can be called even when a class is not instantiated. A static member function cannot be declared with the keywords virtual, const, volatile, or const volatile, and can access only the names of static members, enumerators, and nested types of the class in which it is declared (it does not have a this pointer).

In the example, the function member MyClass::sharedFunction() can be used to provide utility functions to a class. This is done when the function is related to an operation of the class but it doesn’t operate on particular object instances of the class. This is because the function doesn’t (or doesn’t need to) operate on an object’s state.

If the function’s modifier is public, it’s made global, but if it only refers to (or “has sense” inside) the class it has been defined, it’s cleaner/better to have the function as part of its package, as follows:

class MyClass {
static void sharedFunction();

public:
static int _id;
};

Now, MyClass::sharedFunction()is private (of course, it can be added to the private section of the class) to MyClass and can only be used within its member functions, instead of by the whole program.

In addition to this, a variable declared static in a function retains its state between calls to that function:

#include

using namespace std;

class MyClass {
public:
    static int _id; 
    void nonSharedFunction(int);
};

int MyClass::_id = 0;
void MyClass::nonSharedFunction(int parameter) {
    static int sharedNumber = 4;
    sharedNumber += parameter;
    cout << sharedNumber << endl;
}

int main() {
MyClass* firstInstance = new MyClass();
MyClass* secondInstance = new MyClass();

firstInstance->nonSharedFunction(2);
secondInstance->nonSharedFunction(4);

cin.get();
return 0;
}

Output:

6
10

In this example, I changed the static sharedFunction() function to a non static function called nonSharedFunction(int parameter) which accepts an integer as a parameter. The nonSharedFunction(int parameter) contains a static variable (called sharedNumber) which will be shared among all instances of MyClass, so each call to nonSharedFunction(int parameter) will increase the value of sharedNumber.

“Const” vs. “Static”

This section is to briefly distinguish that, although const means static, static does not mean const. Constants and static values are allocated in the same memory section (the static storage) as both persist for the lifetime of the program. However, static values are not constant (unless you explicitly specify so ;) ) as shown in the last example of the A C++ reference on “static” section.

Both, const and static are used to “share” values, but you use const to preserve constant a certain value (such as URIs), while the static “shared” value may vary in time (for example, a data provider).

C# “static”

C# deals with static practically in the same way as C++. The example:

public class MyClass
{
    public static int _id = 0;

    public static void sharedFunction(int parameter) {
        int number = 4;
        number += parameter;
    }
}

Means:

  • The _id data member…
    • …will be allocated when the program begins and deallocated when the program ends.
    • …will be shared by all instances of MyClass.
    • …will be publicly accessible (unless we remove the public modifier).
    • …will be initialized to 0 (unless we specify another value).
  • The sharedFunction(int parameter) function member…
    • …will be allocated when the program begins and deallocated when the program ends.
    • …will be publicly accessible (unless we remove the public modifier) by Type, not by instance.
    • …will have no this pointer.
    • …will only be able to access static data members.
    • …cannot be marked as override, virtual or abstract.

Note that, this time, the function variable sharedNumber is called just number, as we cannot declare static function variables.

Moreover, if we declare a static class, all of its members must be static as well.

Conclusion

Well, let’s get into answering the question: “When to use “static”?”. Some people have the bad tendency of using static to declare “global” values, declaring an object’s state public and static so that they can modify it from wherever they want. This is a terrible practice! This breaks the concepts of encapsulation and, therefore, visibility. It makes the code “dirty” and hard to maintain and debug.

Another “code smell” is to declare a static class with static “homeless” methods. Some people cannot find a “home” for their utility methods and tend to declare a static class to store a whole bunch of (sometimes unrelated!) methods. Some valid static classes with static methods are Factories, as they store creation methods, which do not depend on a state (although some do, for example, those ones who need some kind of configuration for all creations).

In conclusion, static must be used, for example, in data members when we want to share information among all instances of the class that contains them, and in member functions when the function doesn’t need to operate on a particular state (i.e.: creation methods; and stateless methods, but packed in a class in which they “make sense” or are related to).

References

Design patterns

After a long time away from posting, as I couldn’t find the moment nor the subject, I’ve decided to do it again, motivated by the thread A post a day keeps the doctor away written by my dear workmate Angel “Java” Lopez.

What I lacked was the subject, as I was decided to make a strong comeback, with something in particular for everyone. I was able to find that subject during my study about design patterns. I searched… and searched… and searched, but the lack of content in the net was surprising (in particular, in some places where there were too many inconsistencies).

After reading some books, webs and blogs, I realized that what one had, another one was missing, so I’ve decided to make a concrete description of some of them.

However, I’d like to make clear that I’ll deal with what a design pattern is. When and how to choose one in particular, how they solve design problems and how a pattern is used (by this I mean, the steps the reader should follow to put one in practice, and not its implementation) are out of the scope of this topic.

Having said this, I’d like to say, too, that any type of comment or feedback will be welcome. This way, this topic could be corrected and updated so that it can provide a base source for any reader interested in this subject.

What’s a design pattern?

Well, now, let’s focus on the subject: design patterns. First of all, I’d like to do some kind of definition “inheritance“, going from the generic definitions to the specific ones.

Let’s start with the most abstract definitions:

  • Model or sample that is used to get another one of the same kind.
  • Accepted reference used to define a measure unit.
  • Model used as reference to measure or value another one of the same kind.

Peculiarly, these three definitions show a pattern, a common model; they point to the same thing. They indicate that a pattern is a reference used as a model to measure, value and make another one of the same kind. This is my interpretation. Simple and concrete, isn’t it? It seems to me that it is a correct definition to provide a base concept from which we will start to “inherit”.

Let’s continue with the pattern concept. in his book, A Timeless Way Of Building, Christopher Alexander indicates that “each pattern is a three-part rule, which expresses a relation between a certain context, a problem, and a solution.

As an element in the world, each pattern is a relationship between a certain context, a certain system of forces which occurs repeatedly in that context, and a certain spatial configuration which allows these forces to resolve themselves.

As an element of language, a pattern is an instruction, which shows how this spatial configuration can be used, over and over again, to resolve the given system of forces, wherever the context makes it relevant.

The pattern is, in short, at the same time a thing, which happens in the world, and the rule which tells us how to create that thing, and when we must create it. It is both a process and a thing; both a description of a thing which is alive, and a description of the process which will generate that thing.”

I’ll stop here to mark what made me quote these paragraphs. Alexander indicates that a pattern a three-part rule (context-problem-solution), a thing that indicates us how and when we must create it to resolve a given system in a relevant context. This shows that a pattern can describe a certain problem, a particular situation for that problem, and a solution in the same given context.

Now, let’s get into something more specific for our subject. Alexander tells us (in his book A Pattern Language) that “each pattern describes a problem which occurs over and over again in our environment, and then describes the core of the solution to that problem, in such a way that you can use this solution a million times over, without ever doing it the same way twice.“. This definition is pretty interesting. The first time I saw it was in the post The Bridge Pattern from the Mathew Nolton’s blog, in which Nolton remarks the part that says that a pattern describes “[...] the core of the solution to that problem […]”, emphasizing that understanding that problem can lead us to understand the why of when we should use which pattern. I mean, if we understand our problem, we will use a certain pattern and adapt it to our context.

Let’s get into what a design pattern is. Let’s see the definition provided by Erich Gamma (in his book Design patterns):

“A design pattern names, abstracts, and identifies the key aspects of a common design structure that make it useful for creating a reusable object-oriented design. The design pattern identifies the participating classes and instances, their roles and collaborations, and the distribution of responsibilities. Each design pattern focuses on a particular object-oriented design problem or issue. It describes when it applies, whether it can be applied in view of other design constraints, and the consequences and trade-offs of its use.”

This definition erases any possible doubt. It concretely explains what a design pattern is, but Gamma doesn’t stop there and explains that “[...] a pattern is like a template that can be applied in many different situations. Instead, the pattern provides an abstract description of a design problem and how a general arrangement of elements”. I think that with this I’ll be closing the concept. These statements add value to the definition as they indicate that a design pattern provides a template, a default format of a solution, a set of tools that we can use in a customized way to fit our particular situation. I mean, a design pattern deals with a particular problem, yes, but it’s up to us to adapt it to our particular case, our concrete context. To see this, you simply have to remember Alexander’s definition.

Having a clear concept, what else should we know about design patterns? Gamma tells us that a pattern generally has four essential elements:

  • The pattern name: it describes, in a word or two, a design problem, its solutions, and consequences.
  • The problem describes when to apply the pattern (it explains the problem and its context).
  • The solution describes the elements that make up the design, their relationships, responsibilities, and collaborations.
  • The consequences are the results and trade-offs of applying the pattern. They often concern space and time trade-offs, as well as the impact on a system’s flexibility, extensibility, or portability.

And then he classifies them according to their purpose (what the pattern does) and its scope (classes or objects):

  patterns

Scope

Class patterns deal with relationships between classes and its subclasses established through inheritance (static relationships, at compile-time). While object patterns deal with relationships among objects (dynamic relationships, at run-time).

Purpose

Creational Patterns

deal with the process of creating objects. Creational class patterns delegate some part of the object creation operations to subclasses, while creational object patterns delegate some part of the object creation operations to another object.

Structural Patterns deal with composition of classes or objects. Structural class patterns use inheritance to compose classes, while structural object patterns describe ways to assemble objects.

Behavioral Patterns characterize the ways in which classes or objects interact and distribute responsibility. Behavioral class patterns use inheritance to describe to a chain of actions or algorithms, while behavioral object patterns define how a group of objects interact to perform one task that no single object can perform on its own.

With this, I’ll be closing the subject. here, I’m leaving a list of patterns that, once I deal with each one, will have a link to its posts.

Creational Patterns:

  • Abstract Factory
  • Builder
  • Factory Method
  • Prototype
  • Singleton

Structural Patterns:

  • Adapter
  • Bridge
  • Composite
  • Decorator
  • Façade
  • Flyweight
  • Proxy

Behavioral Patterns:

  • Chain of Responsibility
  • Command
  • Interpreter
  • Iterator
  • Mediator
  • Memento
  • Observer

- Cheers, Nacho

PS: Some interesting references:

Ver este topic en español.