views:

2380

answers:

6

I have checked with the wikipedia article, and it seems like it is missing the c++ version of a code example. I am not able to fully appreciate the Facade pattern without this, can you please help explain it to me using C++?

+1  A: 

I've done a search and replace on the C# example. This might not help you, because if you understand C++ then you should be able to understand the C# as it uses the same constructs and keywords (classes, functions, namespaces, public, etc)

// "Subsystem ClassA" 
#include <iostream>
class SubSystemOne
{
public:
    void MethodOne()
    {
     std::cout << " SubSystemOne Method" << std::endl;
    }
}

// Subsystem ClassB" 

class SubSystemTwo
{
public:
    void MethodTwo()
    {
     std::cout << " SubSystemTwo Method" << std::endl;
    }
}

// Subsystem ClassC" 

class SubSystemThree
{
public:
    void MethodThree()
    {
      std::cout << " SubSystemThree Method" << std::endl;
    }
}

// Subsystem ClassD" 

class SubSystemFour
{
public:
    void MethodFour()
    {
     std::cout << " SubSystemFour Method" << std::endl;
    }
}

// "Facade" 

class Facade
{
    SubSystemOne one;
    SubSystemTwo two;
    SubSystemThree three;
    SubSystemFour four;

public:
    Facade()
    {
    }

    void MethodA()
    {
     std::cout << "\nMethodA() ---- " << std::endl;
     one.MethodOne();
     two.MethodTwo();
     four.MethodFour();
    }
    void MethodB()
    {
     std::cout << "\nMethodB() ---- " << std::endl;
     two.MethodTwo();
     three.MethodThree();
    }
}

int Main()
{
    Facade facade = new Facade();

    facade.MethodA();
    facade.MethodB();

    return 0;
}
Dave Hillier
+2  A: 

In one sense, a Facade is just an API for clients that wants to interact with something hidden.

The Facade is useful when exposing a simple C API for something that's implemented in C++ or simply more complex than the API. Or to get a fixed barrier between a client and a library when the library needs to go through numerous iterative updates and you want to affect the client as little as possible. For instance, if a C based library needs to be updated internally to C++ or something else, or just swapped for something completely different, then the Facade is a good middle-layer for the client.

Johann Gerell
A: 

There are C++ examples for Facade at this excellent site on design patterns.

jamesh
+9  A: 

Facade pattern: provides a unified - simplified interface to a complex subsystem or set of interfaces. It provides a higher level interface simultaneously decoupling the client from the complex subsystem.

An example to help you understand .. a cab driver. You tell the cab driver 'Take me to PointX' (unified simplified high-level interface) who then begins on a sequence of actions (turns the key, changes gears, presses the accelerator, etc...) to perform the task. He abstracts away the complexity of underlying subsystems (gearbox, engine, etc.) so that you don't have to worry about them. The driver also decouples you from the actual vehicle used... you do not directly interface with the car. You could potentially give him a Merc but your interface to the Driver would still be TakeMeTo( X ).. you're not tied down to any specific model/make of the car.

In a real world example, you'll find facades where you interface with third party components or libraries. You don't want your code to depend on a specific vendor, so you introduce a facade interface to decouple. Also you'll simplify this interface, e.g. your facade interface would have a method called SendData( string ) but internally the implementation may call n methods on m sub-packages in a specific order to get the task done. This is what the diagram on the wikipedia page shows.

e.g. Translating an example to C++ and keeping it tiny

sResource = LWCPPSimple::get("http://www.perl.org")

Here the fictitious Library For WWW in C++ is a facade that unifies protocol, network and parsing aspects of the problem so that I can concentrate on my primary focus of fetching the resource. The get method hides/encapsulates/keeps-in-one-place the complexity (and in some cases ugliness) of HTTP, FTP and other varied protocols, request-response, connection management, etc. Also if tomorrow the creators of LWCPPSimple find a way to make get() to be twice as fast, I get the performance benefits for free. My client code doesn't have to change.

Gishu
Wow. I like this explanation. I mean, I knew what a Facade is, but this is just great.
Thomas Owens
glad you liked it :)
Gishu
Great Explanation, can go well with this code example answer. http://stackoverflow.com/questions/249581/explain-facade-pattern-with-c-example#249995
Schalk Versteeg
Please stop using analogies. You could have easily said, class A uses class B which uses class C and class A cannot use class C directly.
omouse
@omouse, if I could downvote your comment, I would. Not only are analogies a useful aid to explanation, but your one-sentence explanation of the facade pattern is not even correct.
Mike Daniels
@Mike Daniels, how isn't it correct? you have one class indirectly using many others via "simplified" functions. Analogies are useful but can break down.
omouse
@omouse, your one-sentence explanation implies that there is some reason A could not use C directly. That's not always the case.
Mike Daniels
@omouse - a lot of people I've spoken with seem to like examples; they are 'stickier' than prose. They mentally associate the example to the concept and are then able to recollect it far better than just reading prose. But to each his own mode of learning.. you are entitled to your opinion.
Gishu
+6  A: 
class Engine
{

public:
    void Start() { }

};

class Headlights
{

public:
    void TurnOn() { }

};

//  That's your facade.
class Car
{

private:
    Engine engine;
    Headlights headlights;

public:
    void TurnIgnitionKeyOn()
    {
     headlights.TurnOn();
     engine.Start();
    }

};

int Main(int argc, char *argv[])
{
    //  Consuming facade.
    Car car;
    car.TurnIgnitionKeyOn();

    return 0;
}
A: 
class A {
    private B b; // Class A uses Class B, the "interface"
    public int f() { return b.g(); }
};

class B {
    private C c; // class B uses class C, a "subsystem"
    private ... ...; // other subsystems can be added
    public int g() { c.h(); return c.i(); }
};

class C { // a subsystem
    public void h() { ... }
    public int i() { return x; }
};

Class A will not directly use any methods or directly affect the state of class C or any other subsystem that class B contains. Only one subsystem is shown here because it doesn't matter how many subsystems there are.

omouse