. NET generic techniques to create reusable abstract factories

Source: Internet
Author: User
The technique generics can be used not only to make containers, but also to provide a means of reusing code. With the participation of generics, many designs may be more subtle and extensible. Today I'm going to demonstrate an abstract factory pattern that leverages generics enhancements. As we know, abstract factories (Abstracts Factory) are all abstractions of factories and products, an abstract factory generates a set of abstract products, and a specific factory produces a specific combination of specific products. It maintains the consistency of the associated object portfolio and makes it unnecessary for users to understand the specific implementation of the plant and the product. The main weakness of traditional abstract factory is the strong type dependence and the weak reusability. An abstract factory is usually designed for a specific need and is not usually used in other situations where abstract factories are needed. And although abstract factories can delegate actual production tasks to a particular type of factory, the delegation needs to be implemented through its own pure code, without taking advantage of the abstract features provided by the language. Our task today is to write a generic abstract factory that is not specific to a particular product type and number, and when you need a specific abstract factory, you can reuse it without having to define a specific abstract factory implementation at any time.

We start with a factory method that produces only one product, which is used as the raw material for the abstract factory. Obviously, you can design such an interface as a template for a factory method:

public interface ifactory<t>
{
T Create ();
}
This factory produces an object of type T. When you implement this factory, you should let T be the type of abstract product-the base class that the product is generic to. For example, we can implement a opnewfactory implementation that uses parameterless constructors to create objects:

public class Opnewfactory<tabstractproduct, tproduct>: ifactory<tabstractproduct>
where Tproduct:tabstractproduct, New ()
{
Public Tabstractproduct Create ()
{
return new Tproduct ();
}
}
As you can see from this example, you should only implement an abstract type of ifactory interface and generate specific types. Now that we've finished the factory method template for a single product, we're going to start defining the abstract factory interface that produces multiple products. NET generics support overloading by the number of type parameters, that is, we can define the production of one, two, three ... A number of abstract factory interfaces, which use the same name. (Khan, this is the so-called support "any number of" method) here is unavoidable to copy code, but do not worry, pure copy, the use of the time is very comfortable oh. We introduce an abstract factory that produces two types of products. Can it be defined as this?

Public interface Iabstractfactory<t1, t2>
{
T1 Create ();
T2 Create (); Compile error!!!
}
Oh no! Methods cannot distinguish overloads with return types, only by parameter type overloads. However, we obviously cannot use T1 and T2 as parameters, because these methods are prepared for the production of T1 and T2, how can we accept them as parameters? Is it to be named Create1 and Create2? This is difficult to accept, we hope that production methods can reflect the type of products, how can 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 argument can only create one instance, so the cost is minimal. But this little instance has type information with its type arguments, so it can be used as a basis for judging function overloads. We use typetoken<t> as the basis to differentiate the production function overload, and realize the following:

Public interface Iabstractfactory<t1, t2>
{
T1 Create (typetoken<t1> token);
T2 Create (typetoken<t2> token);
}
We now implement specific factories for abstract factories. The specific factory is to use the production of each product of a single factory to combine to achieve. So as long as you have each type of single factory you can directly combine to generate abstract factories without having to define a class to do this. Note that for each number of abstract factory interfaces it is necessary to generate a specific factory implementation, and here I will only demonstrate for the generation of two products:

public class Concretefactory<t1, t2>: Iabstractfactory<t1, t2>
{
Private ifactory<t1> Factory1;
Private ifactory<t2> Factory2;

Public Concretefactory (ifactory<t1> F1, ifactory<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> (ifactory<t1> F1, ifactory<t2> F2)
{
return new CONCRETEFACTORY&LT;T1, t2> (f1, F2);
}
}
Notice that I have also declared a Concretfactory class with no type parameters, using a static method to generate an instance of the generic concretfactory, because the generic method can speculate on the type argument so that we don't have to enter the angle bracket or the statement of the form. Generic classes do not have this functionality. Now it's done! We use an example to illustrate the work of this generic abstract factory. Now let's say we need an abstract factory that produces PCs, and we need to produce two of abstract products: processors and memory. The abstract and specific implementation of the processor and memory is 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 X2 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 at will and quickly assemble a specific factory implementation from an existing single product factory.

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
Iabstractfactory<processor, ram> factory1 = computerfactory ("Intel");

Ram ram1 = Factory1. Create (TYPETOKEN&LT;RAM&GT;. Instance);
Processor cup1 = Factory1. Create (TYPETOKEN&LT;PROCESSOR&GT;. 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
Iabstractfactory<processor, ram> factory2 = computerfactory ("AMD");

Ram ram2 = Factory2. Create (TYPETOKEN&LT;RAM&GT;. Instance);
Processor cup2 = Factory2. Create (TYPETOKEN&LT;PROCESSOR&GT;. Instance);

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

Using generic technology, we have successfully enhanced an abstract factory that was inherently less reusable, demonstrating the value of generics in improving abstraction and code reuse.

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.