Sign in to follow this  
CodeCriminal

Abstract Factory question

Recommended Posts

CodeCriminal    290
Hi all, i recently purchased Design Patterns: Elements of Reusable Object-Orientated Software and i would like to apply the abstract factory pattern for my windows UI's Heres an example of what i want to accomplish:
WindowsFactory WndFactory( hInstance, .. );
//...
IWindow* Window = WndFactory.CreateWindow( ... );
IButton* Button = WndFactory.CreateButton( ... );
ICheckBox* CheckBox = WndFactory.CreateCheckBox( ... ); // notice here that a
//check box is just a styled button in the windows API, but i provide a function and interface to handle creating and using CheckBox's directly making code easier to read and use.
Anywho, what i want to know is, how do i hide the implementation classes from clients of my code ( almost certainly, just myself )?, Im not sure if it explains how to do this in the book, but it does say that the pattern should be used when implementation should be hidden from client programmers ( though, this is not the reason im using the pattern for ). Thanks all! ~CC

Share this post


Link to post
Share on other sites
Shakedown    230
When it says "implementation should be hidden from the users," that simply means that the process of object construction is encapsulated within a function call (i.e., WndFactory::CreateWindow). Obviously this hides the implementation from the users because they don't see (nor do they need to) the construction of an IWindow object.

So there really isn't anything that you need to explicitly do to hide the implementation, rather that is what applying the pattern will do for you.

Share this post


Link to post
Share on other sites
Ezbez    1164
It goes a little further than that, Shakedown. Not only does this hide implementation details of the actual construction, but it also hides details about which implementation of the constructed class is being used. If you have a group of classes which, let's say, are rendering classes and they depend on which renderer you're using: OpenGL vs. DirectX. Each rendering class is an abstract base class with two derived classes: an OpenGL implementation and a DirectX implementation. Creating a factory class lets you seamlessly construct all your rendering objects using the correct base classes. Clearly, it's problematic if you mix OpenGL and DirectX classes so the factory will make one type but not the other.

So here we're abstracting out implementation with a double approach:
1) Each class which depends upon OpenGL or DirectX presents its interface only through an abstract base class. The abstract base classes do not display implementation details, by nature of being abstract.
2) The factory hides the implementation detail of choosing which implementation of the rendering classes are appropriate. The factory object itself is an abstract base class with two derived classes, one for OpenGL and one for DirectX.

In this approach, you only need to know whether you're using OpenGL or DirectX in one spot: creation of the factory object. There you would get a pointer to an abstract factory class and give it a new instance of either the OpenGL or the DirectX factory.

In short, the abstract base classes expose an interface while the concrete, derived classes implement the interface.

Does that help?

Share this post


Link to post
Share on other sites
Ravyne    14300
ShakeDown's only got part of the story.

An abstract factory returns an abstract interface -- meaning that, in your example, there may be more than one concrete factory for buttons and windows: CSimpleButtonFactory, CFancyButtonFactory which correspond to more than one concrete button type: CSimpleButton, CFancyButton which are both returned to you via a pointer to their base interface class IButton.

IButton's job, as an abstract base class, is to provide an interface to the services common and necessary to all concrete buttons.

This Wikipedia Article gives a good example of applying the Abstract Factory Pattern to a GUI system, where it is used to create Concrete Objects which target different Operating Systems.

If this is not functionality you need, then perhaps a simple factory is enough if you merely want to encapsulate details of an objects creation.

Share this post


Link to post
Share on other sites
CodeCriminal    290
Ok, thanks [smile]
I was thinking of having something like in the wiki-pedia page but at the moment its only the one factory that produces Windows UI elements.

Just one more thing, is it safe to call delete on this inside a member function? something along the lines of

// concrete class
class Window
{
public:
...
void Dispose( ) { delete this; }
};



seeing as that class will only ever be allocated memory dynamicly?
Thanks again

Share this post


Link to post
Share on other sites
Ravyne    14300
Yes, it may be ok to say "delete this;", given the constraints outlined here. It is best avoided if you can, however, given that it is such a can of worms.

I've done it once before, but one of my goals for refactoring that particular code is to get rid of it if possible.

Share this post


Link to post
Share on other sites
Ravyne    14300
You can't really assume, and can't really know unless this information is published somewhere (and is accurate, of course) -- furthermore, it doesn't matter to you because you are merely a client of that API set; what you need to concern yourself with is properly following the create/destroy protocol they have implemented with IUnknown's AddRef/Release methods (which, more generally, is a COM interface thing, its not specific to DirectX.)

Anyhow, they only reason you could need to know specifically what DirectX does is in order to circumvent it, which would surely lead to trouble. For informational purposes, it seems reasonable that that could be an approach they may have taken, but there are any number of other approaches available.

Share this post


Link to post
Share on other sites
Zahlman    1682
Quote:
Original post by CodeCriminal
Does directx obey those constraints with its IUnknown::Release( ) method?
I assume direct 3d objects are instiated dynamically with new


DirectX provides some kind of smart pointer, IIRC. You probably want to use that.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this