Asp.net generic skills-build reusable abstract factories

Source: Internet
Author: User
Abstract Factory mode abstracts factories and products. An Abstract Factory generates a set of Abstract products, while a specific Factory generates a specific combination of specific products. It can maintain the consistency of such related object combinations, so that users do not need to understand the specific implementation of factories and products.

Generics can be used not only as containers, but also as a means of code reuse. With the participation of generics, many designs may be more subtle and scalable. Today, I will demonstrate an abstract factory model that uses generic enhancement. We know that the Abstract Factory mode abstracts factories and products. An Abstract Factory generates a set of Abstract products, while a specific Factory generates a specific combination of specific products. It can maintain the consistency of such related object combinations, so that users do not need to understand the specific implementation of factories and products. The main weakness of traditional Abstract Factory is strong type dependence and weak reusability. An abstract factory is usually designed for a specific need and cannot be used in other scenarios where abstract factories are needed. In addition, although the abstract factory can delegate the actual production task to a specific type of factory, such delegation needs to be implemented through its own pure code, failing to take advantage of the abstract features provided by the language. Our task today is to compile a generic abstract factory that does not target specific product types and numbers. When you need a specific Abstract Factory, You can reuse it at any time without defining a special abstract factory implementation.

First, we start by generating a factory method for only one product, using this as the raw material for the abstract factory. Obviously, you can design such an interface as a template for the factory method:

Public interface ifacloud <T>
{
T Create ();
}
This factory produces a T type object. When you implement this factory, T should be the type of the abstract product-that is, the base class of the product. For example, we can implement an OpNewFactory implementation that uses a non-parameter constructor to create an object:

Public class OpNewFactory <TAbstractProduct, TProduct>: ifacloud <TAbstractProduct>
Where TProduct: TAbstractProduct, new ()
{
Public TAbstractProduct Create ()
{
Return new TProduct ();
}
}
From this example, we can see that you should only implement the ifacloud interface of the abstract type and generate the specific type. Now that we have finished the factory method template for a single product, we need to define the abstract factory interface for producing multiple products .. NET wildcard supports reload by the number of type parameters, that is, we can define the production of one, two, three ...... The same name is used for multiple Abstract Factory interfaces. (Khan, this is the so-called method that supports "any number") it is inevitable to copy the code, but don't worry, it's just a pure copy, it's very comfortable to use. Let's take the abstract factory that produces two types of products as an example. Can this be defined?

Public interface imo-actfactory <T1, T2>
{
T1 Create ();
T2 Create (); // compilation Error !!!
}
Oh no! Methods cannot distinguish between overload by return type, but only by parameter type overload. However, here we obviously cannot use T1 and T2 as parameters, because these methods are prepared to produce T1 and T2. How can we accept them as parameters? Is it possible to name Create1 and Create2? This is hard to accept. We hope that the production method can reflect the product type. How can it be called 1 and 2. To solve this problem, we introduced the TypeToken <T> type, which is defined as follows:

Public sealed class TypeToken <T>
{
Static private TypeToken <T> instanceValue = new TypeToken <T> ();
Static public TypeToken <T> Instance
{
Get {return instanceValue ;}
}

Private TypeToken (){}
}

This class has no members, and each type of real parameters can only create one instance, so the cost is very small. However, this small instance carries the type information of its type arguments, so it can be used as a basis for determining function overloading. We use TypeToken <T> as the basis for distinguishing the heavy loads of production functions. The implementation is as follows:

Public interface imo-actfactory <T1, T2>
{
T1 Create (TypeToken <T1> token );
T2 Create (TypeToken <T2> token );
}
Now we implement a specific factory for the abstract factory. A specific factory is implemented by combining a single factory that produces each product. Therefore, you only need to have a single factory of each type to directly combine to generate an abstract factory without defining a class to do this. Note: Each Abstract Factory interface of a number needs to generate a specific factory implementation. Here I only demonstrate how to generate two products:

Public class ConcreteFactory <T1, T2>: imo-actfactory <T1, T2>
{
Private ifacloud <T1> factory1;
Private ifacloud <T2> factory2;

Public ConcreteFactory (ifacloud <T1> f1, ifacloud <T2> f2)
{
Factory1 = f1;
Factory2 = f2;
}

Public T1 Create (TypeToken <T1> token)
{
Return factory1.Create ();
}

Public T2 Create (TypeToken <T2> token)
{
Return factory2.Create ();
}
}

Public static class ConcretFactory
{
Public static ConcreteFactory <T1, T2> NewFactory <T1, T2> (ifacloud <T1> f1, ifacloud <T2> f2)
{
Return new ConcreteFactory <T1, T2> (f1, f2 );
}
}

Note: I have declared a ConcretFactory class with no type parameters and used a static method to generate a generic ConcretFactory instance. This is because the generic method can be used to speculate on the type parameters, this eliminates the need to enter angle brackets or Of statements, but generic classes do not have this function. Now we are done! Let's use an example to demonstrate how this generic abstract factory works. Now let's assume that we need an abstract factory that produces PCs. We need to produce two abstract products: processor and memory. The abstraction and Implementation of the processor and memory are as follows:

Processor and Ram
Public abstract class Processor
{
Public abstract string Model {get ;}
}

Public abstract class Ram
{
Public abstract int Frequency {get ;}
}

Public class PentiumProcessor: Processor
{
Public override string Model
{
Get {return "Pentium Extreme Edition 955 ";}
}
}

Public class AthlonProcessor: Processor
{
Public override string Model
{
Get {return "Athlon 64X2 FX-60 ";}
}
}

Public class DDRRam: Ram
{
Public override int Frequency
{
Get {return 400 ;}
}
}

Public class DDR2Ram: Ram
{
Public override int Frequency
{
Get {return 533 ;}
}
}

The following code demonstrates how to generate the desired Abstract Factory interface as needed and quickly combine the existing single product factory into a specific factory implementation.

Class Program
{
Static IAbstractFactory <Processor, Ram> ComputerFactory (string type)
{
If (type = "Intel ")
{
Return ConcretFactory. NewFactory (new OpNewFactory <Processor, PentiumProcessor> (),
New OpNewFactory <Ram, DDR2Ram> ());
}
Else if (type = "AMD ")
{
Return ConcretFactory. NewFactory (new OpNewFactory <Processor, AthlonProcessor> (),
New OpNewFactory <Ram, DDRRam> ());
}

// Unknown type
Return null;
}

Static void Main (string [] args)
{
// Yield a computer of Intel
Imo-actfactory <Processor, Ram> factory1 = ComputerFactory ("Intel ");

Ram ram1 = factory1.Create (TypeToken <Ram>. Instance );
Processor cup1 = factory1.Create (TypeToken <Processor>. Instance );

Console. WriteLine ("An Intel Computer ");
Console. WriteLine ("CPU Model: {0}", cup1.Model );
Console. WriteLine ("Memory Frequency: {0} MHz", ram1.Frequency );

Console. WriteLine ();

// Yield a computer of AMD
Imo-actfactory <Processor, Ram> factory2 = ComputerFactory ("AMD ");

Ram ram2 = factory2.Create (TypeToken <Ram>. Instance );
Processor cup2 = factory2.Create (TypeToken <Processor>. Instance );

Console. WriteLine ("An AMD Computer ");
Console. WriteLine ("CPU Model: {0}", cup2.Model );
Console. WriteLine ("Memory Frequency: {0} MHz", ram2.Frequency );
}
}

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.