5,661,954 members and growing! (14,863 online)
Email Password   helpLost your password?
Development Lifecycle » Design and Architecture » Design Patterns     Intermediate

The Flyweight Pattern

By Alberto Bar-Noy

This article discusses the Structural Pattern Flyweight, using a Visual C++ example.
C++/CLI, VC6, C++, Windows, .NETVisual Studio, VS6, Dev

Posted: 4 Oct 2001
Updated: 7 Oct 2001
Views: 57,806
Bookmarked: 18 times
Announcements
Loading...



Search    
Advanced Search
Sitemap
9 votes for this Article.
Popularity: 3.18 Rating: 3.33 out of 5
1 vote, 33.3%
1
0 votes, 0.0%
2
1 vote, 33.3%
3
0 votes, 0.0%
4
1 vote, 33.3%
5

Introduction

This article gives a brief description of the Flyweight pattern through the use of a data validator for user interfaces. The function implementation of the validator is not relevant and is not demonstrated here. The sample code with three validators given here was compiled in VC6 with SP5 in NT 4.0.

Flyweight Pattern

As described in the book Design Patterns: Elements of Reusable Object-Oriented Software by Erich Gamma et al. ( Addison-Wesley, 1995 ) at page 195 (Also called GoF: Gang of Four): "Use sharing to support large numbers of fine grained objects efficiently".

Let's say you are developing UIs with lots of data validations (a good example is an editable List Control or a Grid) and you need to validate data entered by the user. In MFC applications you would override the command handler fired after the user ends data entry and validate the data for each UI element separately. Using the Flyweight pattern you write the validators once and you can easily add more validators through the development of your code.

How it works

The Flyweight has a pool of objects (also called a factory) and a function that returns a pointer to one of these objects when requested to do so. The way to request an object is through a key (in this example the getValidator function) which receives the key of the object as a string and returns a pointer to it. That's it!!!

Code Sample

The purpose of the code in the demo project is to demonstrate the Flyweight pattern, therefore the implementation might not be exactly brilliant. All function implementations as well as class declarations are written together inside file DataValidator.h.

The CDataValidator base class

The CDataValidator class is the base class for all validators. Notice that the ValidateString function forces a validation algorithm by using two virtual functions CheckMinus and CheckStringOrder. This is called a Template Method. The description of this pattern as described in GoF at page 325 is: "Define the skeleton of an algorithm in an operation, deferring some steps to subclasses."

class CDataValidator
{
public:
    CDataValidator(){}
    virtual bool ValidateString(const CString& sToValidate)
    {
        ////Template Method

        if(!CheckMinus(sToValidate))
            return false;

        if(!CheckStringOrder(sToValidate))
            return false;
	////End Template Method

        return true;

    }

	//For edit boxes

    virtual bool ValidateChar  (const CString& cToValidate)=0;

protected:
	//////Checks for the right order of characters in a double

    bool CheckDoublesOrder(const CString& sToValidate)
    {
        if(sToValidate.IsEmpty())
            return false;

        if(sToValidate[0]=='-'&& sToValidate.GetLength()>2)
        {
            if(sToValidate[1]=='0' && sToValidate[2]!='.')
                return false;
        }
        else
        {
			if(sToValidate[0]=='0' && sToValidate.GetLength()>1)
			{
				if(sToValidate[1]!='.')
				return false;
			}
			return true;
        }
        return true;

    }
	//////Checks for the right order of characters in an int

    bool CheckIntsOrder(const CString& sToValidate)
    {
        if(sToValidate.IsEmpty())
            return false;

        if(sToValidate[0]=='-' && sToValidate.GetLength()>1)
        {
            if(sToValidate[1]=='0')
                return false;
        }
        else
        {
            if(sToValidate[0]=='0' && sToValidate.GetLength()>1)
                return false;
        }
        return true;
    }

	//checks for the right positioning of the minus character

    virtual bool CheckMinus(const CString& sToValidate)
    {
        int index = sToValidate.Find("-");
        if(index >0)
            return false;
        return true;
    }

    virtual bool CheckStringOrder(const CString& sToValidate)=0;

};

The CDataValidatorPool class

The pool holds all validator objects in an std::map (I used and STL map because it makes more sense to me). If an object does not exist the pointer returned by the getValidator function is NULL.

class CDataValidatorPool
{
public:
    CDataValidatorPool()
    {
        m_ValidatorPool["INT"] = new CIntValidator;
        m_ValidatorPool["DBL"] = new CDoubleValidator;
        m_ValidatorPool["STR"] = new CStringValidator;
    }

    ~CDataValidatorPool()
    {
        std::map<CString,CDataValidator* >::iterator Iter;

        for(Iter=m_ValidatorPool.begin();Iter!=m_ValidatorPool.end();++Iter)
        {
            delete m_ValidatorPool[Iter->first];
        }

        m_ValidatorPool.clear();
    }

    CDataValidator* getValidator(const CString& sValidatorName)
    {
		//Can be optimized to create objects only when asked for.

		//Objects can also be singletons or even reference counted


        if(m_ValidatorPool.find(sValidatorName)!=m_ValidatorPool.end())
            return m_ValidatorPool[sValidatorName];
        else
            return NULL;
    }

private:
      std::map<CString,CDataValidator* > m_ValidatorPool;
};

How to use it

If you want to use the code demonstrated here in your project insert the DataValidator.h file in your project, create a member variable of the class CDataValidatorPool and of you go.

Optimizations

There are a few optimizations to this model depending on your implementation:

  1. You can make the pool object a Singleton (GoF page 127 as well as The Singleton Pattern in this site).
  2. You can create the objects on demand at the getValidator function instead of up front in the constructor.
  3. Each object can be a Singleton.
  4. You can add a reference count to each object.

Copyright 2001 ITG Israel LTD. All Rights Reserved.

Enjoy Programming!!!

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Alberto Bar-Noy


Coventry University graduate (B.Sc.).
Programming in MFC,ATL,WIN32, a tiny bit of Perl and C++ at itginc.com in Israel.
Came to Israel from Greece.
Fluent in four languages: Greek, Hebrew, French and English (not including code Smile ).

Occupation: Web Developer
Location: Israel Israel

Other popular Design and Architecture articles:

Article Top
Sign Up to vote for this article
You must Sign In to use this message board.
FAQ FAQ Noise ToleranceSearch Search Messages 
 Layout  Per page   
 Msgs 1 to 11 of 11 (Total in Forum: 11) (Refresh)FirstPrevNext
Generalneed help.memberusafz7:35 26 Oct '06  
GeneralRe: need help.memberAlberto Bar-Noy9:11 26 Oct '06  
GeneralRe: need help.memberusafz9:37 26 Oct '06  
GeneralRe: need help.memberusafz7:23 13 Nov '06  
GeneralRe: need help.memberAlberto Bar-Noy5:16 14 Nov '06  
GeneralRe: need help.memberusafz5:25 14 Nov '06  
GeneralSome doubtsmemberTomasz Sowinski3:20 6 Oct '01  
GeneralRe: Some doubtsmemberAlberto Gattegno22:45 6 Oct '01  
GeneralRe: Some doubtsmemberTomasz Sowinski2:23 8 Oct '01  
GeneralRe: Some doubtsmemberNice Scroll Effect21:50 14 Oct '01  
GeneralImplementing validatorsmemberRavi Bhavnani4:50 5 Oct '01  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 7 Oct 2001
Editor: Chris Maunder
Copyright 2001 by Alberto Bar-Noy
Everything else Copyright © CodeProject, 1999-2008
Web20 | Advertise on the Code Project