Comparison
Using design patterns can make our code more flexible, easier to scale, and easier to maintain. Various object-oriented programming languages provide essentially the same mechanisms: classes, inheritance, derivation, polymorphism, and so on. But also have their own characteristics, C # Reflection mechanism is a very important tool, good use can play a large role in practice.
Let's take a look at an example:
My program needs a series of objects, such as Apple,orange ..., in order to use them, we must in the program according to user requirements, and then call the new operator to generate them, so that the client program to know the corresponding class information, the generated code is clearly not flexible. We can not use the specific classes in the code, but only to explain what we need, and then we can get the object we want?
Oh, we all look at design patterns, listen, a lot of people are there preaching about how good they are, and we'll see how to use them to solve the problem. The goal is clear, so let's see which one meets our requirements. Gof's "design pattern" have seen it, indefinitely to see some, then we see can not "gather" up? J Well, our program is thinking about how objects are created, and creating patterns should fit the requirements. Then we'll look at the "intent" section of each pattern. Oh, the first seems to hit the lottery, abstract factory, we look at it, "provide a set of interfaces to create a series of related or interdependent objects without specifying their specific classes", at least "no need to specify their specific classes" to meet our requirements. Let's look at the structure of it:
Our problem seems to not be so complicated, only orange,apple and so on (should be product), they are obviously a class, are fruit, we as long as a production of fruit factory can, the left side of the inheritance level, There's only one fruitfactroy to see. No, forget it. Orthodox unorthodox, practical on the line J
Some of the following things are clearly what we need:
public interface Ifruit
{
}
public class Orange:ifruit
{
Public Orange ()
{
Console.WriteLine ("An Orange Is got!");
}
}
public class Apple:ifruit
{
Public Apple ()
{
Console.WriteLine ("An Apple is got!");
}
}
What should our fruitfactory be like? The above structure diagram it gives is createproducta, that good, I will makeorange, there is a CREATEPRODUCTB, I makeorange not yet??
public class Fruitfactory
{
Public Orange Makeorange ()
{
return new Orange ();
}
Public Apple makeapple ()
{
Return to New Apple ();
}
}
How do you use this factory? Let's write the following code:
String fruitname = Console.ReadLine ();
Ifruit myfruit = null;
Fruitfactory myfruitfactory = new Fruitfactory ();
Switch (fruitname)
{
Case "Orange":
Myfruit = Myfruitfactory.makeorange ();
Break
Case "Apple":
Myfruit = Myfruitfactory.makeapple ();
Break
Default
Break
}
Compile the run, and then enter what you want in the console, hehe, success. Immersed in the happiness of your complacent.
But wait, it seems not perfect, if I want pear, I have to add the judgment in the switch of the client code, and add the Makepear method to the factory method, it seems not elegant. A little better, in the factory only provide a method, Makefruit, and then pass in a parameter name, representing the name of the fruit we want, so it seems that the switch in our client code can be done, on the contrary, in the fruitfactory seems to need a, What are you waiting for? Realize it.
Fruitfactory:
public class Fruitfactory
{
Public Ifruit Makefruit (string Name)
{
Switch (Name)
{
Case "Orange":
return new Orange ();
Case "Apple":
Return to New Apple ();
Default
return null;
}
}
}
Customer Code:
String fruitname = Console.ReadLine ();
Ifruit Myfruit;
Fruitfactory myfruitfactory = new Fruitfactory ();
Myfruit = Myfruitfactory.makefruit (fruitname);
It looks a lot better, at least not a long list of judgment codes in my client code.
Ah Q Spirit again at work, we immersed in the joy of success. Well, the code seems to be OK, there should be no improvement. But there seems to be another voice saying:
"Except for a little ..."
Well Wait, what? ”
"Fruitfactory also have switch ah, looks also ugly ah!" ”
"Well, it must be watching refactoring" or "TDD", how demanding! Anyway idle is also idle, see can change? ”
Since it is not conditional judgment, only the name of the fruit passed in, if name = "Apple", to generate an Apple object, I need new Apple (), if I can so much good: new Makeittoclass (Name), to convert the string into a class. Although there is no such syntax in C #, the corresponding mechanism is provided, and that is reflection. One of the important classes is the System.Type class, which plays a central role in reflection. We can use the methods, fields, properties, and nested classes of the type object to find all the information about that type.
Another important class is System.activator, which contains specific methods for creating object types locally or remotely, or for obtaining references to existing remote objects.
We can first use the type class to get the type information of the class name specified by name, and then use Activator to create the object based on this information. What are you waiting for?
public class Fruitfactory
{
Public Ifruit Makefruit (string Name)
{
Ifruit myfruit = null;
Try
{
Type type = Type.GetType (name,true);
Myfruit = (ifruit) activator.createinstance (type);
}
catch (TypeLoadException e)
Console.WriteLine ("I dont know this kind of fruit,exception caught-{0}", e.message);
return myfruit;
}
}
After such treatment, add new fruit, we do not need to modify the client code, and the factory code does not need to modify, how, cool!