Definition of a pattern
The façade mode (facade pattern) is also called the appearance pattern, defined as follows:
Provide a unified interface to a set of interfaces in a subsystem. Facade defines a highet-level interface that makes the subsystem easier to use.
Requires that a subsystem's external communication with its internal must be done through a single unified object. Façade mode provides a high-level interface that makes subsystems easier to use.
Type
Structure class
Usage Scenarios for patterns
- Provide an interface to a complex module or subsystem for external access
subsystem is relatively independent-external access to the subsystem as long as the black box operation can
For example, the calculation of interest, more complex and is a dynamic process of change, but for the people who use the system, he only need to enter the amount and deposit period, others do not want to care, you need to get a result. At this point, the façade mode can provide only one access interface to get results. Very suitable.
Prevention of risk spread by low-level personnel
For example, a low level of technical personnel involved in the development of the project, in order to reduce the impact of personal code on the overall project risk, the general practice is restricting, can be developed in the specified subsystem, and then provide a façade interface for access operations.
UML Class Diagram
The façade pattern focuses on the uniform object, which is the interface that provides an access subsystem, except for this interface, which does not allow any access to the subsystem's behavior to occur. The UML of its general class diagram is as follows:
Subsystem classes is a short name for all classes of a subsystem, which may represent a class or a collection of dozens of objects. To put it simply, the façade system in the façade is the only channel inside the outside access subsystem, no matter how disorganized inside the subsystem, as long as there are façade objects in, you can do "respectability, veneer."
The façade mode is as follows:
Role description Facade Façade role
The client can invoke the method of this role. This role knows all the functions and responsibilities of the subsystem. In general, this role delegates all requests from the client to the appropriate subsystem, meaning that the role has no actual business logic, just a delegate class.
subsystem Classes Subsystem Role
You can have one or more subsystems at the same time. Each subsystem is not a single class, but a collection of classes. The subsystem does not know the presence of the façade. For subsystems, the façade is just another client.
The common source of the pattern
SUBSYSTEM Classes SUBSYSTEM:
publicclass ClassA { publicvoiddoSomethingA(){ System.out.println("ClassA---doSomethingA"); }}
publicclass ClassB { publicvoiddoSomethingB(){ System.out.println("ClassB---doSomethingB"); }}
publicclass ClassC { publicvoiddoSomethingC(){ System.out.println("ClassC---doSomethingC"); }}
facade– Façade object:
Public classFacade {PrivateClassA A =NewClassA ();PrivateClassB B =NewClassB ();PrivateClassC C =NewClassC (); Public void MethodA(){ This. A.dosomethinga (); } Public void MethodB(){ This. B.DOSOMETHINGB (); } Public void METHODC(){ This. C.DOSOMETHINGC (); }}
Client:
publicclass Client { publicstaticvoidmain(String[] args) { // TODO Auto-generated method stub new Facade(); facade.methodA(); facade.methodB(); facade.methodC(); }}
Output Result:
ClassA---doSomethingAClassB---doSomethingBClassC---doSomethingC
Advantages
Reduce system interdependencies
Think about, if we do not use the façade mode, the external access directly into the internal subsystem, is a strong coupling between each other, mutual dependence and association, is not acceptable to the system design, the appearance of the façade pattern is a good solution to this problem, all dependencies are on the façade object dependency, and subsystem independent.
Increased flexibility of the system
With less reliance, flexibility naturally increases. No matter how the subsystem changes, as long as it does not affect the façade object, you can freely modify.
Improve security
Want to let you access the subsystem of which business to open which logic, not open on the façade object, we can not access, security naturally improved.
Disadvantages
The biggest disadvantage of the façade mode is that it does not conform to the opening and closing principle, and closes to the extension. Façade mode in the face of the object is the weight of the weight, once the system put into production, if found there are errors, how do you solve? Completely comply with the open and closed prototype, there is no way to solve. Inherited? Overwrite? are not used. The only thing that can be done is to modify the code of the façade object, which is quite a risk. Please pay attention to it.
Precautions
- A subsystem can have multiple facades
- The façade does not refer to the business logic within the subsystem
Mode implementation in Android source code
Façade mode, as a structural class design pattern, can be understood as a user-exposed interface, which makes it very convenient for users to call their internal methods directly to achieve access and invocation of all subsystems (that is, other classes). This means that users often use a unified interface to implement access and invocation of other classes.
So when Android was developed, did we have this situation?
We are not in the development, often have the following actions:
Use a context object to send a broadcast-use the Sendbroadcast method of the façade object context to implement access to the Activitymanagernative class.
Use a context object to start the service-use the StartService method of the façade object context to implement access to the Activitymanagernative class.
Use a context object to start activity-using the StartActivity method of the façade object context to implement access to Mmainthread.getinstrumentation ().
Use a context object to get packagemanager information-access to the Applicationpackagemanager class is implemented using the Getpackagemanager () method of the façade object context.
Wait a minute.
In other words, the example of the façade pattern at Android development is the context class.
We look at the context class:
Public Abstract class Context {...... Public AbstractAssetmanagergetassets();/** Return A Resources instance for your application ' s package. * / Public AbstractResourcesgetresources();/** Return Packagemanager instance to find global package information. * Public AbstractPackagemanagerGetpackagemanager();/** Return A Contentresolver instance for your application ' s package. * / Public AbstractContentresolverGetcontentresolver(); ...... Public Abstract void Sendbroadcast(Intent Intent); Public AbstractComponentNameStartService(Intent service); Public Abstract void startactivity(Intent Intent); ......}
From the code point of view, the Context is just an abstract class that defines a number of abstract interfaces and quantification. There are two of other implementation classes: Contextimpl and Contextwrapper.
First look at the Contextimpl class, which inherits the abstract class context, realizes its concrete method, acts as a façade object, facilitates the user to all three party class access.
Class Contextimpl extends Context {FinalActivitythread Mmainthread;FinalLOADEDAPK Mpackageinfo;Private FinalIBinder Mactivitytoken;Private FinalUserhandle Muser;Private FinalApplicationcontentresolver Mcontentresolver;Private FinalString Mbasepackagename;Private FinalString Moppackagename;Private FinalResourcesmanager Mresourcesmanager;Private FinalResources mresources;Private FinalDisplay Mdisplay;//May be NULL if default display Private FinalDisplayadjustments mdisplayadjustments =NewDisplayadjustments ();Private Final Booleanmrestricted;PrivateContext Moutercontext;Private intMthemeresource =0;PrivateResources.theme Mtheme =NULL;PrivatePackagemanager Mpackagemanager;PrivateContext Mreceiverrestrictedcontext =NULL; ......//Get specific context StaticContextimpl Getimpl (Context context) {context Nextcontext; while(ContextinstanceofContextwrapper) && (nextcontext= ((contextwrapper) context). Getbasecontext ())! =NULL) {context = Nextcontext; }return(Contextimpl) context; }//Get Assetmanager @Override PublicAssetmanagergetassets() {returnGetresources (). Getassets (); }//access to resources @Override PublicResourcesgetresources() {returnMresources; }//Get Packagemanager @Override PublicPackagemanagerGetpackagemanager() {if(Mpackagemanager! =NULL) {returnMpackagemanager; } ipackagemanager PM = Activitythread.getpackagemanager ();if(PM! =NULL) {//doesn ' t matter if we make more than one instance. return(Mpackagemanager =NewApplicationpackagemanager ( This, PM)); }return NULL; }//Get Contentresolver @Override PublicContentresolverGetcontentresolver() {returnMcontentresolver; }//Get Looper @Override PublicLooperGetmainlooper() {returnMmainthread.getlooper (); }//Get context @Override PublicContextGetapplicationcontext() {return(Mpackageinfo! =NULL) ? Mpackageinfo.getapplication (): Mmainthread.getapplication (); } ......//Send broadcast Public void Sendbroadcast(Intent Intent) {warnifcallingfromsystemprocess (); String Resolvedtype = intent.resolvetypeifneeded (Getcontentresolver ());Try{intent.preparetoleaveprocess (); Activitymanagernative.getdefault (). Broadcastintent (Mmainthread.getapplicationthread (), intent, resolve DType,NULL, ACTIVITY.RESULT_OK,NULL,NULL,NULL, Appopsmanager.op_none,NULL,false,false, GetUserId ()); }Catch(RemoteException e) {Throw NewRuntimeException ("Failure from System", e); } }//Start the operation of the service implementation method, the key is to call Activitymanagernative.getdefault (). StartService PrivateComponentNameStartservicecommon(Intent service, Userhandle user) {Try{validateserviceintent (service); Service.preparetoleaveprocess (); ComponentName cn = Activitymanagernative.getdefault (). StartService (Mmainthread.getapplicationthread (), Ser Vice, service.resolvetypeifneeded (Getcontentresolver ()), Getoppackagename (), User.getidentifie R ());if(CN! =NULL) {if(Cn.getpackagename (). Equals ("!")) {Throw NewSecurityException ("not allowed to start service"+ Service +"without permission"+ Cn.getclassname ()); }Else if(Cn.getpackagename (). Equals ("!!")) {Throw NewSecurityException ("Unable to start service"+ Service +": "+ Cn.getclassname ()); } }returncn }Catch(RemoteException e) {Throw NewRuntimeException ("Failure from System", e); } }//Start activity, the key is to call Method Mmainthread.getinstrumentation (). Execstartactivity Public void startactivity(Intent Intent, Bundle options) {warnifcallingfromsystemprocess ();if((Intent.getflags () &intent.flag_activity_new_task) = =0) {Throw NewAndroidruntimeexception ("Calling StartActivity () from outside of an Activity"+"context requires the Flag_activity_new_task FLAG."+"Is this really, what are you want?"); } mmainthread.getinstrumentation (). Execstartactivity (Getoutercontext (), Mmainthread.getapplicationt Hread (),NULL, (Activity)NULL, Intent,-1, options); }......}
Then look at the Contextwrapper class:
publicclass ContextWrapper extends Context { Context mBase; publicContextWrapper(Context base) { mBase = base; } ...... publicgetBaseContext() { return mBase; } @Override publicgetAssets() { return mBase.getAssets(); } ......}
All of these methods are simply called mbase corresponding to the method you can.
Another two of the façade mode, we can see one eye on the understanding.
Façade mode (Contextimpl and Contextwrapper), is indeed a façade, its real value is to provide a unified interface to access the internal system classes, very convenient for users to access the system inside. As a structural class design pattern, this is really a struct class that acts as a façade in all classes.
Resources
(1). Design pattern of Zen-23rd chapter Façade mode
(2) Façade mode
Https://github.com/simple-android-framework/android_design_patterns_analysis/tree/master/facade/elsdnwn
Design pattern of the façade mode---facade pattern