Intent: Provides a coarse grained facade on fine grained objects to improve efficiency over a network.
See
http://www.martinfowler.com/isa/distributedFacade.html and
http://www7b.boulder.ibm.com/wsdd/library/techarticles/0106_brown/sessionfacades.html
The
SessionFacade pattern is also a logical extension of the
GangOfFour FacadePattern, extrapolated to live in an EJB world. I've used session facades to have various methods on a session bean control 'workflow' for a certain subset of business logic. (i.e. a 'placeOrder' method can control several different processes needed to place an order.) While I don't know if network efficiency was the primary intent, using the
SessionFacade pattern to control coarse grained workflow does make client design and code simpler and far easier to write.
A
SessionFacade can correspond tightly to a
UseCase or
ActivityDiagram, but one does not typically want a one-to-one correlation. (i.e. don't have one bean - one method style of design, which the mapping might lend itself to.) --
ChadThompson
In a recent talk,
MartinFowler said he was renaming this as
RemoteFacade for his book.
Is using session facade object oriented? It separates the business logic from the business entities.
Well, I could say that it simply isolates the persistence implementation from the
UserInterface. In any case, I think you'll find that we always recommend that all of the business logic sits behind the facade -- where did you get a different impression of the pattern? --
KyleBrown
You are right. It's not the facade, it's the session beans. Many EJB books recommend implementing the business logic in session beans instead of the entity beans.
The issue is that there are different kinds of "business logic" - domain logic, and application logic. Domain logic is logic that is naturally associated with a
DomainObject - such as a recipe knowing how to compute the nutrition profile of a serving of itself. Application logic has to do with application-specific workflow - such as sending emails, or enqueuing MOM messages, when a new recipe is added to a database. If you put application logic in a
DomainObject, the
DomainObject becomes less reusable from application to application. If you put domain logic in some other place besides a
DomainModel, you may have to duplicate it to "reuse" it. If
EntityBeans are intended as a way to implement
DomainModels, then they shouldn't contain application logic, as shouldn't
PlainOldJavaObject implementations of
DomainModels. So you need another place to put application logic. A
ServiceLayer is an appropriate place to put this kind of logic, and
SessionBeans make a good implementation choice for a
ServiceLayer. However the intention of
ServiceLayer is completely different than the intention of
SessionFacade.
ServiceLayer is all about defining an
ApplicationBoundary and coordinating a system's transactional response to stimuli arriving in use cases.
SessionFacade is all about reducing remote invocations on
EntityBeans, and its very existence demonstrates that making
DomainObjects remotable is a dubious idea. I wrote much more about
ServiceLayer and its difference from
SessionFacade in my chapter in
MartinFowler's
PatternsOfEnterpriseApplicationArchitecture. --
RandyStafford
This sounds very interesting. However, I have a bit of a problem with an architecture, which places the domain objects on the server side only. What about fat clients? Id like to implement my domain objects in a way which would allow their usage on both the server and the client. So when a cook edits their recipe, the client can immediately compute the nutrition profile and the server side recipe will be updated when the user commits their work. And of course, I want to WriteOnceRunEverywhere. So how can I use EntityBeans as a way to implement my DomainObjects? I see only two possibilities: Either I implement it as a PlainOldJavaObject and let some clever generator generate the EJB and the client objects from my domain object, or I implement the domain objects as EntityBeans and use a client side EJB container which will synchronise its state with the server.
Why assume distribution? I have a bit of a problem with architectures that are distributed when they don't need to be. The pain of distribution should be considered when choosing between a web UI and a "rich" UI. If you have to have distribution, you can "allow usage" of domain objects "on the client" in several ways: implement them in a remotely invokable way and invoke them remotely, or make sure they are completely serializable, or use
HalfObjectPlusProtocol, or use
DataTransferObjects (which allow indirect "usage" at best), or find/build/use some mechanism like
GemStone's "synchronized replicates" (for Smalltalk - AFAIK nothing like that exists in the J2EE app server world). --
RandyStafford
Yes of course, all these are techniques, how to allow usage of domain objects on the client. But why should I think about about technical aspects of the system, when I am developing the domain objects? Wouldnt this reduce the reusability of my domain model implementation? Why should I think about serialization, synchronization, distribution and stuff when implementing the class Recipe?
That's a good point. I think
SeparationOfConcerns is definitely appropriate, starting with the essential aspects of the
DomainModel - the abstractions, relationships, responsibilities, etc. - and worrying about distribution, concurrency, persistence, separately. I think
RonJeffries and
KyleBrown had a similar discussion on
UnderstandingDistributedSystems. --RS
CategoryPattern