This is in continuation to the previous post. Please note that this post will be a long one, so if you have time, keep reading.
It states “Simplifying the communication between a higher level interface with the complex sub-system”. What it means is that in many complex systems, there are a bunch of sub-systems lying around which are important components. Now each of those sub-systems communicate on their own to the outside world or with another bunch of sub-systems in some ways. The way of communication could be 1-1 or via other components specifically designed for that.
Now having so many complex sub-systems in a system and handling the communication between them is not easy as you might think. The easy way to solve the problem of communication between sub-system components with the outside world is to have a 1:1 link. But don’t you think it is very complex and tedious to have this kind of connections? Doesn’t this remind you of the old telephonic operator switching systems?
Yes, 1:1 is highly impossible, and having a system like that designed does require a lot of work to be done, plus the maintenance cost is very huge. Another way is to have a component specifically designed to act as a mediator between the 1:1 link so that we can reduce the direct dependency. But think realistically, you have to design or customize many such independent components which have to co-exist with these sub-systems in order to just facilitate the mediator job. When you read these lines, please think of real world complex software projects like telephone switching systems, network management, supply chain management, stock markets, etc.
By using this pattern, we are able to develop complex systems having complex sub-systems which can communicate well and easily with other systems/sub-system, thus reducing the overall complexity as well as less dependency among them. Without this pattern, as said above, our software structure would grow enormous and very complex.
You might first think that the divide and rule concept might sound fine wherein you can divide complex sub-systems into simpler sub-systems and then have communication with them or with others. But I must tell you here that no matter what level you bring down the structure of complexity into simpler sub-components, you are increasing the communication network between them. A complex system is of no use if sub-systems inside it does not communicate well, right?
Based on the requirements, your sub-systems should communicate well with others anywhere or everywhere. If communication is not given much importance, then your system fails because either you have made the communication network so ugly which in turn you yourself failed to understand, or due to over complexity, they are not communicating properly, which again boils down to not understanding ourselves how to identify any problems.
I remember an example of a simplistic communication between complex sub-systems while I was watching a rocket development show on Discovery, wherein a failure of communication between two different communication sub-systems led to a disaster as per NASA. It was learned later that by not having a proper flow of communication between them which was more simplistic and less tight coupled, they could have reduced the overall complexity in developing the rocket (I guess Apollo 2, not sure) itself and understanding the workflow.
Let us see a sample code simulating this pattern, as always I wrote a very simplistic program.
As you can see from the above code, it is pretty obvious that I have taken a car manufacturing management software as an example here. As per that, we have a car body sub-system class which has a
AddCarBody() method which in turn does some very complex processes like body type, color, chassis, interiors, etc., which are not exposed outside.
Next, I have another sub-system called a Car Engine Sub system as shown:
As you can see from the above code,
EngineSubSystem has a
AddEngine method which is
public. But this method does much more complex work which is not exposed outside, for example: fuel injection, piston monitoring, air filtration process, etc., sub-systems, which independently are complex in nature.
Let me take another complex sub-system in this management software called
ShippingSubSystem as shown:
As per the above code,
ShippingSubSystem exposes only one method called
ShipToCargo() method, which internally does a lot more processes like billing, inventory update, packaging, distribution, etc.
So now to make all these complex sub-systems work together easily and simplistically as per this pattern, let's look at the code below:
As you can see from this class, the communication between this sub-system and the other sub-systems, viz.
Engine, etc., has been greatly simplified. At this point of time, we need not know how each of those sub-systems work in detail. There can be many more sub-systems which can be integrated as and when needed in this class without changes anywhere else in the system. Thus we have achieved a big leap in simplifying the communication between these sub-systems and reduced a much tight integration between other sub-systems, thus reducing the overall complexity of the system.
Now let us see the usage code part of it. By now, you would have already guessed it. Still, let me show you just how to make it complete.
static void Main(string args)
ICarFacade carInterface = new CarFacade();
A picture speaks more than words, so let me show you a picture which sums up pretty much where it can be used. Already the above How section would have given you a fair idea. One more example would be better I feel, with a difference of having this pattern and without it.
As you can see from the above image, a typical system having complex sub-system objects would look like this. In this structure, the Facade pattern is not implemented. As I have shown in the picture, these sub-systems can be a part of the finance management system or a shopping system like Amazon, ebay, etc., wherein any transaction from the client objects would require an update to the billing process, ordering system, and other sub-systems. If there was no pattern implemented (as shown in this picture), then the client object would have been tied hard to these sub-systems and thus every client object will have knowledge on the internal structures of the system’s sub-system modules.
As you can see, not only the over all structuring looks complex, even the communication pattern looks messy, thus having many drawbacks in this design, like every new client object requires to have in-depth knowledge on the system it is talking to. If you want to remove a sub-system, you need to change the client objects as well which is nearly impossible. Any small modification to either side of this system leads to major chaos.
After introducing the Facade pattern, the above image gets simplified to:
Hope you understand the effect of the Facade pattern in the above image. In this design model, everything is very flexible in structure. The client objects need not worry about to whom they are interacting with and the same with the Facade system. Even the internal communication structure is minimized.
So the bottom line is, the structure of the system now looks very clean and crisp. Even the internal sub-systems can be changed without worrying about the outside world. If there is any removal of the sub-system components, in this case the Ordering System (may be a down time or out of scope reasons), only the Facade component needs to be notified and not all the client objects. The same is true for client object changes.
Other examples would be:
- Customer service support system
- Library management system
- Bank accounting system
- Business processing system
- Employee hiring process system
Well, that’s all. I am sorry if it’s too lengthy, but I wanted to make every point clear.
Look out for my next post in continuation to this.
Thanks for reading.
P.S.: Your valuable comments and votes are well appreciated.