Use reflection to realize dynamic factories in NET
Source http://msdn.microsoft.com
After several years of software development, the design pattern is gradually understood and adopted. There is always its solution to common specific issues, which have gradually been recognized by everyone. Many such solutions are summarized as design patterns to address many programming issues. Based on this, Microsoft provides a column to discuss various practical patterns to help you solve problems in the development process faster.
(Http://msdn.microsoft.com/msdnmag/issues/03/03/designpatterns/default.aspx)
One common use in design patterns: factory model. The advantage of factory model is to use dynamically create objects (or even rely on objects to create objects) to reduce the coupling between objects. However, when the factory method and other modes are used to create high-internal pelicable code, the factory method is not worth recommending. Use the .NET reflection mechanism to create a factory class (no part of the most commonly implemented implementation).
About two major principles in software design: I don't talk much from the advantage of high-end pacific low coupling.
Factory design pattern:
For example to explain the benefits of factory mode: For example, the object needs to send messages to the B object, and a must hold a reference to the B object to complete this function, that is, the B object must be initialized and a object can access him. The method of our longest use is to directly initialize the B object in the A object, directly hold a reference to the B object, so that A object must know how to initialize B objects, such as: Need to initialize parameters, etc. The programmers know the drawbacks of programs written in programming ideas.
How to solve the above problem.
The answer is to hand over the work of creating B objects to another class: C
That is, all the examples of a B-class that need to be unified from C will be used.
This is the function of the factory method.
Of course, we can't completely eliminate coupling, this method is to reduce the degree of coupling of the program, which is conducive to the modification and expansion of the program. The method of creating B is created above, and there is a better improvement, that is, the use of the interface, that is, what we often say: pure virtual factory, the degree of coupling is lower. You can refer to the specific reference.
There are three mains in the factory model. We need to distinguish: 1, factory 2, customers 3, products
Customers are: Any object that needs to be used in the factory.
The product is: a factory generated by the factory returns to the customer.
General method using factory mode
Factory model has many versions, and different practices have excellent and disadvantageous. We have the most commonly used factory model below to introduce factory models using reflex mechanisms.
According to an example:
If you have a program that manages computer parts, where:
InventoryMgr, is customer, warehouse administrator.
PartsFactory is a factory;
MonitorinvFactory is a display factory;
KeyboardInvFactory, is a keyboard factory;
IPartSinventory is the product returned above.
The UML map is as follows:
Below I explain the above picture:
Mainclass is used to send a class that requires a warehouse object request to IVENTORYMGR. For example, now we need to add the number of displays in the warehouse, you can send this request to IVENTORYMGR. code show as below:
Class mainclass {
Static void
Main
(String [] args) {
PartsFactory myfactory = null;
InventoryMgr myinvmgr = new inventorymgr (); foreach (string marg in args) {
Switch (marg) {
Case "Monitors":
Myfactory = new monitorinvfactory ();
Break;
Case "Keyboards":
Myfactory = new keyboardinvfactory ();
Break;
DEFAULT:
Break;
}
IF (MyFactory! = NULL)
Myinvmgr.replenishinventory (MyFactory);
Myfactory = null;
}
}
}
Class inventorymgr {
Public void replenishinventory (PartsFactory vFactory) {
Ipartsinventory partinv = vFactory.ReturnPartInventInventIndory ();
Partinv.restock ();
}
}
Interface ipartsinventory {
Void Restock ();
}
Class Monitorinventory: iPartsinventory {
Public void restock () {
Console.Writeline ("The Monitor Inventory Has Been Restocked);
}
}
Class keyboardinventory: iPartsinventory {
Public void restock () {
Console.Writeline ("The Keyboard Inventory Has Been Restocked);
}
}
Abstract class partsfactory {
Public Abstract Ipartsinventory ReturnPartInventory ();
}
Class MonitorinvFactory: PartsFactory {
Public override ipartsinventory returnpartinventory () {
Return (iPartsInventory) New Monitorinventory ();
}
}
Class keyboardinvfactory: PartsFactory {
Public override ipartsinventory returnpartinventory () {
Return (iPartsInventory) new keyboardinventory ();
}
}
The above code can be said to be a reasonable implementation of factory model, but some areas.
Everyone can see the code implementation of the above factory model from coupling and perspective. one by one:
Inventorymgr did not say, the degree of coupling is very low, and he uses the interface to block information for creating a specific class. Even if you add new parts (new plants), you won't affect him. This is: Typical examples of extension development, modified closing. At the same time, InventoryMGR also has low coupling in achieving different iPartSINVENTORY.
Where is the problem?
The problem is in mainclass, he violates the axiom of "don't talk to strangers".
It is used to create a factory for the creation of specific classes in MainClass. From the above code, it can be seen that MainClass actually does not know the specific factories before the parameter is not conveyed, and he is just a simple creation of a good class has given InventoryMgr. The above practitioners actually: Mainclass, MonitorinvFactory, KeyboardInvFactory et al. Should be unnecessary coupling and put together. Generally speaking: The principle of creating another object in an object is that this object needs to send messages to the object created, unless the task of this object is created and returned other objects. Factory mode is such an example.
Another drawback of Mainclass is that he is not high.
Mainclass should not consider using that specific class to handle the request, he is just a proxy for sending a message. The role of MainClass is just accepting a customer message request, and then communicates further to InventoryMGR. Use reflex mechanisms to better solve this problem.
We now look at another common approach to the factory method:
Do not use abstract factories to create objects, and create objects in specific factories.
This can simplify a lot of code.
Mainclass
InventoryMgr
PartsFactory
Have some changes
IPartSINVENTORY has not changed
Monitorinvfactory is no longer needed
KeyboardInvfactory no longer needs to be used by a specific plant instead.
The biggest change is to use an iterator: enminvparts.
code show as below:
Class mainclass {
Static void
Main
(String [] args) {
Inventorymgr invmgr = new inventorymgr ();
Foreach (String Marg in args) {
Switch (marg) {
Case "Monitors":
Invmgr.replenishinventory (Enminvparts.moniTors);
Break;
Case "Keyboards":
Invmgr.replenishinventory; Enmicvparts.Keyboards;
Break;
DEFAULT:
Break;
}
}
}
}
Public enum enminvparts: int {monitor = 1, keyboards = 2}
Class inventorymgr {
Public void replenishinventory (enminvparts inventorypart) {
PartsFactory Factory = New PartsFactory ();
Ipartsinventory ip = factory.returnPartInventory (InventoryPart);
Ip.restock ();
}
}
Class PartsFactory {
Public iPartsInventory ReturnPartInventory (Enminvparts Invpart) {
Ipartsinventory invType;
Switch (INVPART) {
Case enmicvparts.monitors:
INVTYPE = New Monitorinventory ();
Break;
Case enminvparts.keyboards:
InvType = new keyboardinventory ();
Break;
DEFAULT:
INVTYPE = NULL;
Break;
}
Return INVTYPE;
}
}
We now analyze the above code:
The drawbacks of MainClass mentioned above have been improved.
Mainclass will not be in and "said strangers to speak", but he has to decouple with the factory. Use enMinvparts to pack the client's request. The package requested by the client is reasonable, and he also briefly gives the message to InventoryMgr. Eye people can see: MAINCLASS's coupling and problems have passed to PartsFactory. And PartsFactory and iPartSinventory have also coupled.
Let's take a look at how the reflex mechanism achieves low coupling and this lofty goal.
Part One