Usage examples: The Facade pattern is commonly used in apps written in C#. It’s especially handy when working with complex libraries and APIs.
Identification: Facade can be recognized in a class that has a simple interface, but delegates most of the work to other classes. Usually, facades manage the full life cycle of objects they use.
Conceptual Example
This example illustrates the structure of the Facade design pattern. It focuses on answering these questions:
What classes does it consist of?
What roles do these classes play?
In what way the elements of the pattern are related?
Program.cs: Conceptual example
usingSystem;namespaceRefactoringGuru.DesignPatterns.Facade.Conceptual{ // The Facade class provides a simple interface to the complex logic of one // or several subsystems. The Facade delegates the client requests to the // appropriate objects within the subsystem. The Facade is also responsible // for managing their lifecycle. All of this shields the client from the // undesired complexity of the subsystem.publicclassFacade {protectedSubsystem1 _subsystem1;protectedSubsystem2 _subsystem2;publicFacade(Subsystem1 subsystem1,Subsystem2 subsystem2) {this._subsystem1= subsystem1;this._subsystem2= subsystem2; } // The Facade's methods are convenient shortcuts to the sophisticated // functionality of the subsystems. However, clients get only to a // fraction of a subsystem's capabilities.publicstringOperation() {string result ="Facade initializes subsystems:\n"; result +=this._subsystem1.operation1(); result +=this._subsystem2.operation1(); result +="Facade orders subsystems to perform the action:\n"; result +=this._subsystem1.operationN(); result +=this._subsystem2.operationZ();return result; } } // The Subsystem can accept requests either from the facade or client // directly. In any case, to the Subsystem, the Facade is yet another // client, and it's not a part of the Subsystem.publicclassSubsystem1 {publicstringoperation1() {return"Subsystem1: Ready!\n"; }publicstringoperationN() {return"Subsystem1: Go!\n"; } } // Some facades can work with multiple subsystems at the same time.publicclassSubsystem2 {publicstringoperation1() {return"Subsystem2: Get ready!\n"; }publicstringoperationZ() {return"Subsystem2: Fire!\n"; } }classClient { // The client code works with complex subsystems through a simple // interface provided by the Facade. When a facade manages the lifecycle // of the subsystem, the client might not even know about the existence // of the subsystem. This approach lets you keep the complexity under // control.publicstaticvoidClientCode(Facade facade) {Console.Write(facade.Operation()); } }classProgram {staticvoidMain(string[] args) { // The client code may have some of the subsystem's objects already // created. In this case, it might be worthwhile to initialize the // Facade with these objects instead of letting the Facade create // new instances.Subsystem1 subsystem1 =newSubsystem1();Subsystem2 subsystem2 =newSubsystem2();Facade facade =newFacade(subsystem1, subsystem2);Client.ClientCode(facade); } }}
Output.txt: Execution result
Facade initializes subsystems:
Subsystem1: Ready!
Subsystem2: Get ready!
Facade orders subsystems to perform the action:
Subsystem1: Go!
Subsystem2: Fire!