Simple Factory & Factory approach
It's always been confusing. Simple factory, factory method, abstract factory The difference between the three design patterns, is not not understand its differences, but always memory confusion, silly points are not clear, so then re-summed up the difference, and recorded, next time confusion, you can take out to see. This section first says simple factory and factory methods, and the next section is about abstract factories.
The factory method actually contains a simple factory, a simple factory is also called a static factory method,
Simple Factory class diagram
The simple factory model, also known as the static factory method pattern, is one of the factory method patterns, and the essence of the simple factory pattern is that a factory class dynamically determines which product class (these product classes inherit from a parent class or interface) should be created based on the parameters passed in. Note that the factory class passed in parameters, which is the basis of the factory class new product, can be a string, or it can be its own definition of an enum or an int value.
Take a car factory, for example, can produce 3 different types of cars, SUV,SEDAN,MPV, each car has a drive method. If you do not use a simple factory but create it directly, as in the example below.
Public classUser { Public StaticSUV SUV; Public Static void Main(string[] args) {suv=NewSUV (); Suv.drive (); }}class suv{ Public void Drive() {System. out. println ("SUV is driving"); }}class sedan{ Public void Drive() {System. out. println ("Sedan is driving"); }}class mpv{ Public void Drive() {System. out. println ("MPV is driving"); }}
At first glance there is no problem, want any product, then directly create a new one, but the problem is, for the use of the product class, can only hold the object of the corresponding product, such as the above example, I hold the object of the SUV, and then the object of the new SUV, when a new product, and need to replace the SUV. You also need to modify the principals used. This enables the use of the product's main body and product tightly coupled together. Not conducive to code reuse and expansion.
Modify the above code slightly to abstract all vehicles into a vehicle interface, let the user hold a vehicle object, create a new factory class, and, depending on the parameters passed in, return different objects for use by the user. And the function of the factory class to create the product is static, so there is no need to create a factory class first.
Code:
Interface vehicle{ Public void Drive();} Class SUV implements Vehicle {@Override Public void Drive() {System.out.println ("SUV is driving"); }}class Sedan implements vehicle{@Override Public void Drive() {System.out.println ("Sedan is driving"); }}class MPV implements vehicle{@Override Public void Drive() {System.out.println ("MPV is driving"); }}enumvehcletype{SUV,SEDAN,MPV} Public class simplefactory { Public StaticVehiclemakevehicle(Vehcletype type) {Switch(type) { CaseSuv:return NewSUV (); CaseSedanreturn NewSedan (); CaseMpv:return NewMPV ();default: Break; }return NULL; }}
Test code:
publicclass User { publicstatic Vehicle mVehicle; publicstaticvoidmain(String[] args) { mVehicle=SimpleFactory.makeVehicle(VehcleType.suv); mVehicle.drive(); }}
That's better. But some things are not good enough, such as:
When I need to produce a new type of car, like a convertible convertible. But when I was in simplefactory.makevehicle, there was no such model, so I needed to modify the Simplefactory class to add a case judgment and create a new convertible object. But we do not want to simplefactory this factory class open to users, it also caused no way to increase the model. How can we let the user arbitrarily increase the model? This expands the factory approach pattern.
Factory mode (Factory method)
To continue the above, user can only know a vehicle interface object and a factory interface object, for the SUV it implements the vehicle interface, but also needs suvfactory to implement the factory interface and create it, so for the user, You only need to create a Suvfactory object and then create an SUV object from the Suvfactory class. If the customer wants to add a convertible product themselves. That only needs to implement its own convertible class and Convertiblefactory class. And then produce it in the same way.
Class diagram
Code: Vehicle-related
Public interface Vehicle { Public void Drive();} Class SUV implements Vehicle {@Override Public void Drive() {System.out.println ("SUV is driving"); }}class Sedan implements vehicle{@Override Public void Drive() {System.out.println ("Sedan is driving"); }}class MPV implements vehicle{@Override Public void Drive() {System.out.println ("MPV is driving"); }}
Factory-related
Public interface Factory { PublicVehiclemakevehicle();} Class Suvfactory implements factory{@Override PublicVehiclemakevehicle() {return NewSUV (); }}class Sedanfactory implements factory{@Override PublicVehiclemakevehicle() {return NewSedan (); }}class Mpvfactory implements factory{@Override PublicVehiclemakevehicle() {return NewMPV (); }}
Customer class:
public class User {
public static Vehicle mvehicle;
public static Factory mfactory;
public static void Main (string[] args) {
Mfactory=new suvfactory ();
Mvehicle=mfactory.makevehicle ();
Mvehicle.drive ();
}
}
At this point, we want to change the production of convertible vehicles, only need to increase the convertible and corresponding factories, and modify the implementation of the Customer class can:
class Convertible implements Vehicle{ @Override publicvoiddrive(){ System.out.println("Convertible is driving"); }}
class ConvertibleFactory implements Factory{ @Override publicmakeVehicle() { returnnew Convertible(); }}
public class user { public static Vehicle mvehicle; public static Factory mfactory; public static void main (string[] args) {Mfactory=new convertiblefactory (); Mvehicle=mfactory.makevehicle (); Mvehicle.drive (); }}
At this time, the production is convertible products.
The application of the design pattern is determined by its usage scenario, and the simple factory upgrade to the factory method is due to the need to encapsulate the factory class, provide maximum freedom and extensibility to the customer class, but also encapsulate the internal logic of the factory.
But it's not that simple factories have no factory method, when the customer class user itself is also part of the internal package, we can easily modify the factory class, or the product may be small increase, such as phone, originally only Gsmphone,cdmaphone, after a long time, Suddenly, the cdmaltephone, it is only in the factory class to increase the production of this class. Perhaps a new xxxphone will be coming a few years from now.
Factory methods in Android simple factory
Android source has a lot of use of factory methods, most of which are static factory methods, that is, the first simple factory, also said before, the use of what factory is based on demand, static Factory method is a special case of factory methods, although not as flexible as the factory method, But the static factory approach is quick and easy for many people who do not need to create multiple factories to build their products.
For example, Bitmapfactory reads from a file and creates a new Bitmap object through the public static Bitmap DecodeFile (String pathName) static method.
Also such as phonefactory in telephony, created by static method of public static void Makedefaultphones (context context), And get created by Phonefactory.getdefaultphone ().
And Networkstatsfactory,webviewfactory, these are simple factory applications.
In addition to the framework, many system applications also use the factory method, not listed.
Factory method
The Threadfactory class in the Java library, as an abstract factory, is defined as follows:
publicinterface ThreadFactory { Thread newThread(Runnable r);}
Asynctask, which is commonly used in Android, creates a new factory (and the implementation of backgroundloaderthreadfactory in MMS applications, similar):
privatestaticfinal ThreadFactory new ThreadFactory() { privatefinalnew AtomicInteger(1); publicnewThread(Runnable r) { returnnew"AsyncTask #" + mCount.getAndIncrement()); } };
The use of threadfactory is generally used as a parameter in the new Threadpoolexecutor, and Getthreadfactory () is called in Threadpoolexecutor. Newthread () to create a new worker thread, This runnable can be understood as abstract products, while thread is a specific product.
Design Patterns in Android-factory method mode