The Design of Software (CLOSED)

A public forum for discussing the design of software, from the user interface to the code architecture. Now closed.

The "Design of Software" discussion group has been merged with the main Joel on Software discussion group.

The archives will remain online indefinitely.

How should I handle data types in a Facade Pattern?

Hi all

I'm designing a facade for a framework in java. The main purpose of the facade is to offer a single entry point to the framework and hide the complexity of understanding which class does what in the framework. It also has some glue code to make those classes to work together.

My main concers is regarding the classes used as arguments and return valees in the methods exposed by facade. Should I expose in the facade's methods the same classes or should I encapsulate them in a kind of proxy classes defined in the same package than the facade?

I suppose that the answer depends on how many of such classes are defined behind the Facade and how complex is to encapsulate them (for instance, how many methods and attributes they have).

Thanks in advance

Pablo
Pablo Chacin Send private email
Thursday, May 24, 2007
 
 
Don't let the facade expose what it is hiding in the first place.

Don't create leaky abstractions: http://www.joelonsoftware.com/articles/LeakyAbstractions.html
Jakob Magiera
Thursday, May 24, 2007
 
 
Personally I think that proxy classes as you've described would be an indirection too far. If you later decide that your framework needs to use different method parameter classes internally then you can always introduce the proxying behind your façade without affecting the client API.
John Topley Send private email
Thursday, May 24, 2007
 
 
> should I encapsulate them in a kind of proxy classes defined in the same package than the facade?

IMO if you don't define them in the facade, and instead reuse implementation classes, then the facade isn't insulating the end-user from internal implementation details; so perhaps something like:

class Facade
{
  class FooParameters
  {
    ...
  }
  class BarParameters
  {
    ...
  }
  void foo(FooParameters fooParameters) { ... }
  void bar(BarParameters barParameters) { ... }
}

Logically it's Ok for the implementation to use facade classes, but not vice versa.

Physically though that may be problematic, causing a cyclic dependency where the implementation depends on facade and the facade depends on the implementation. So, perhaps something like:

* Lowest layer: Facade parameters (depends on nothing)

* Middle layer: Implementation (depends on facade parameters)

* Upper layer: Facade (depends on facade parameters and on implementation)

* Topmost layer: User (depends on facade and on facade parameters)
Christopher Wells Send private email
Thursday, May 24, 2007
 
 
John

Maybe I'm misunderstanding your comment, but it seams to be contradictory. First, you say:
>Personally I think that proxy classes as you've described would
>be an indirection too far.

Then
> If you later decide that your framework needs to use different
> method parameter classes internally then you can always
>introduce the proxying behind your façade without affecting the
>client API.

But if I don't introduce this additional level of indirection in my facade (but instead expose the low level classes), how could later maintain the client API?

I mean, suppose I exposed class X and later I change it in the framework to class Y. How could I maintain the class X in the client API if is not longner available in the framework?

The problem I see is mainly with packages. Supose that class was defined in package A and the facade is in package B. Then, when I change class X in package A, I can't just define it in package B because it will be a different class!

Thursday, May 24, 2007
 
 
last comment is mine. I forgot to sign it.
Pablo Chacin Send private email
Thursday, May 24, 2007
 
 
Pablo,

That's a good point that I hadn't thought of. Please feel free to discard my suggestion! :-)
John Topley Send private email
Thursday, May 24, 2007
 
 
Think about the Facade owning the interfaces. The client consumes them, the business classes behind implement them.

This makes the implementation depend on the facade which seems inverted. If your goal is a business model that can be used by many facades, then it doesn't work. If you want a facade that could front changeable or pluggable implementations, then it's just right.

What's the most stable thing about your system? I'm  suggesting the facade's public interfaces to clients. Once you publish an interface, changing it can cause great pain.
Stan James Send private email
Thursday, May 24, 2007
 
 
Stan

I don't really understand why this should be true
>This makes the implementation depend on the facade which
>seems inverted.

I'm not intending to change the implementation. Implementation will depend on its own classes (in my example above, ClassX) but facade will not expose them, but its own classes, which basically wrap implementation classes. Do you see anything wrong with it? How could this lead to a dependency of the implementation on the facade?

Pablo
Pablo Chacin Send private email
Thursday, May 24, 2007
 
 
> How could this lead to a dependency of the implementation on the facade?

You might have something like ...

//implement a facde method by delegating to an implementation method

void Facade::foo(FacadeParameters perameters)
{
  Implementation::implement_foo(parameters);
}

... if you do this then the Implementation::implement_foo method would accept (i.e. depend on) the FacadeParameters type.
Christopher Wells Send private email
Friday, May 25, 2007
 
 
void Facade::foo(FacadeParameters perameters)
{
  Implementation::implement_foo(parameters.toImplParam());
}

Without a doubt, the origional implementation types shouldn't be exposed.

Friday, May 25, 2007
 
 
The whole point with the Facade is to simplify the access of your framework.
You must ask yourself how much you have gained if you need to crate a bunch of new "complicated" objects for every method call on your Facade object. If your wrapper objects are simple, why not pass in standard data types?
You are also decoupling the user of the Facade from any internal classes if you don't expose them. You do get all the benefits that you would from using a "normal" interface, but the key with the Facade is simplification.
I also believe you can use (wrapper) objects as input/return data types if they (the objects) are used "naturally" by the client. I.e. I am not only creating this kind of objects to be able to call one method in the Facade or I now have an object returned which I can't use without hacking it to bits...
The client will be dependent on the Facade. But you have to be dependent on something. Should you also be dependent on the wrappers? Rather one thing than 5 or 15.
Johan Nilsson Send private email
Friday, May 25, 2007
 
 
IMO, a facade is a service level interface. That means both single entry point and hidden framework complexity but it also implies a coarse grained interface.

The facade interface is not a 101 mapping to framework APIs and interface; on the contrary. The facade should provide high level services. For example:


Service Interface:
  Receipt changeEngineOil(Car car, Key carKeys);

Service implementation:
  Receipt changeEngineOil(Car car, Key carKeys) {
      final Mechanic mechanic = allocateMechanicToCar(car);
      new Thread() {
          public void run() {
              mechanic.getCar(car);
              driveCarOnRamp(mechanic, car, carKeys);
              changeEngineOil(mechanic, car);
              driveCarToParking(mechanic, car, carKeys);
              mechanic.returnCar(car);
      }.start();
      return prepareReceipt(car);
  }

The implementation uses the Mechanic, Car, Key fine grained interfaces.
Dino Send private email
Friday, May 25, 2007
 
 
Your example shows the Car and Key classes being used in the Facade and in the implementation.
Christopher Wells Send private email
Friday, May 25, 2007
 
 
Hi Dino

I agree with your idea of facade as coarse grained functinality on top of the framework. As i mentioned in my original posting, the facade also has some glue code to put together fine grained functionality.

However, I'll still have the data type dependency on one particular implementation.

In this regard, I agree with Johan's suggestion
>I also believe you can use (wrapper) objects as
>input/return data types if they (the objects) are used
>"naturally" by the client. I.e. I am not only creating
>this kind of objects to be able to call one method
> in the Facade or I now have an object returned which
>I can't use without hacking it to bits...

So, in the same line of though with the idea of coarse grained functionality, facade data types will be also coarse grained and will put together, when needed, some fine grain data objects and expose them in terms that are meaningful to user.

Thanks to all for your insighful comments.
Pablo Chacin Send private email
Sunday, May 27, 2007
 
 
@Christopher,

Of course the Car and the Key are interfaces used by the service. After all the Car and the Key are the objects the service is going to operate on (data flow computing) and provided externally.
Dino Send private email
Monday, May 28, 2007
 
 

This topic is archived. No further replies will be accepted.

Other recent topics Other recent topics
 
Powered by FogBugz