Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Pro .NET 2.0 Code And Design Standards In CSharp (2006) [eng]

.pdf
Скачиваний:
34
Добавлен:
16.08.2013
Размер:
3.43 Mб
Скачать

186C H A P T E R 1 0 C R E AT I O N A L PAT T E R N S

A number of Radiator objects derived from the abstract Radiator class

An abstract RadiatorCap class

A number of RadiatorCap objects derived from the abstract Radiator class

A WorkOrder class

Client code that, through passing a set of abstract factories to an instance of a WorkOrder, is able to indirectly control the creation of sets of factories (Briscoe, Detroit, and McCord) that build sets of products (Radiators and RadiatorCaps)

Now let’s code the Abstract Factory pattern.

Pattern Code

The essence of the design lies in the way in which the abstract RadiatorFactory class leverages abstract classes (Radiator and RadiatorCap), delegating or deferring implementation and coupling to RadiatorFactory objects. The WorkOrder class plays the role of a context that enables the client to distance itself from the build process. Notice that it is when the RadiatorFactory class is implemented or instantiated that there is the first commitment to a set of factories types (Briscoe, Detroit, and McCord). In turn, these factory types commit to an implementation of a set of product types (Radiators and RadiatorCaps). Observe the regimentation of control throughout the design: the sets of like products are encapsulated within a given factory, which itself is treated as an abstraction through which the client indirectly manipulates the whole process without being coupled to factory or product types.

RadiatorFactory Class

public abstract class RadiatorFactory

{

public abstract Radiator BuildRadiator(); public abstract RadiatorCap BuildRadiatorCap();

}

BriscoeRadiatorFactory Class

public class BriscoeRadiatorFactory: RadiatorFactory

{

public override Radiator BuildRadiator()

{

Radiator rad = new BriscoeRadiator(); rad.RadiatorBrand();

return rad;

}

C H A P T E R 1 0 C R E AT I O N A L PAT T E R N S

187

public override RadiatorCap BuildRadiatorCap()

{

RadiatorCap cap = new BriscoeRadiatorCap(); cap.RadiatorCapBrand();

return cap;

}

public BriscoeRadiatorFactory() {;}

}

DetroitRadiatorFactory Class

public class DetroitRadiatorFactory: RadiatorFactory

{

public override Radiator BuildRadiator()

{

Radiator rad = new DetroitRadiator(); rad.RadiatorBrand();

return rad;

}

public override RadiatorCap BuildRadiatorCap()

{

RadiatorCap cap = new DetroitRadiatorCap(); cap.RadiatorCapBrand();

return cap;

}

public DetroitRadiatorFactory() {;}

}

McCordRadiatorFactory Class

public class McCordRadiatorFactory: RadiatorFactory

{

public override Radiator BuildRadiator()

{

Radiator rad = new McCordRadiator(); rad.RadiatorBrand();

return rad;

}

public override RadiatorCap BuildRadiatorCap()

188 C H A P T E R 1 0 C R E AT I O N A L PAT T E R N S

{

RadiatorCap cap = new McCordRadiatorCap(); cap.RadiatorCapBrand();

return cap;

}

public McCordRadiatorFactory() {;}

}

Radiator Class

public abstract class Radiator

{

public abstract void RadiatorBrand();

}

BriscoeRadiator Class

public class BriscoeRadiator: Radiator

{

public override void RadiatorBrand()

{

Console.WriteLine ("Briscoe Radiator.");

}

public BriscoeRadiator() {;}

}

DetroitRadiator Class

public class DetroitRadiator:Radiator

{

public override void RadiatorBrand()

{

Console.WriteLine ("Detroit Radiator.");

}

public DetroitRadiator() {;}

}

C H A P T E R 1 0 C R E AT I O N A L PAT T E R N S

189

McCordRadiator Class

public class McCordRadiator: Radiator

{

public override void RadiatorBrand()

{

Console.WriteLine ("McCord Radiator.");

}

public McCordRadiator() {;}

}

RadiatorCap Class

public abstract class RadiatorCap

{

public abstract void RadiatorCapBrand();

}

BriscoeRadiatorCap Class

public class BriscoeRadiatorCap: RadiatorCap

{

public override void RadiatorCapBrand()

{

Console.WriteLine("Briscoe Radiator cap.");

}

public BriscoeRadiatorCap() {;}

}

DetroitRadiatorCap Class

public class DetroitRadiatorCap: RadiatorCap

{

public override void RadiatorCapBrand()

{

Console.WriteLine("Detroit Radiator cap.");

}

190 C H A P T E R 1 0 C R E AT I O N A L PAT T E R N S

public DetroitRadiatorCap() {;}

}

McCordRadiatorCap Class

public class McCordRadiatorCap: RadiatorCap

{

public override void RadiatorCapBrand()

{

Console.WriteLine("McCord Radiator cap.");

}

public McCordRadiatorCap() {;}

}

WorkOrder Class

public class WorkOrder

{

public void AssembleRadiator(Factory fact)

{

Radiator rad = fact.BuildRadiator(); RadiatorCap cap = fact.BuildRadiatorCap(); this.Assemble();

}

private void Assemble()

{

Console.WriteLine ("Assembling Radiator and cap."); Console.WriteLine();

}

public WorkOrder() {;}

}

Client Code

In the client code, we see the Abstract Factory pattern at work. We test the effectiveness of the design pattern, which enables client code to indirectly control the build process through a set of factories and a set of products, while ensuring that it is decoupled from factory and product implementations.

C H A P T E R 1 0 C R E AT I O N A L PAT T E R N S

191

class Client

{

static void Main(string[] args)

{

Factory factoryOne = new BriscoeRadiatorFactory(); WorkOrder workOne = new WorkOrder(); workOne.AssembleRadiator(factory1);

/* With the Abstract Factory pattern, The Model T domain can easily

switch suppliers. It simply stops calling the Briscoe Radiator

factory, and commences calling the Detroit and McCord Radiator

factories, to supply radiators. For each new supplier, respective

Radiator, Cap and Factory classes need to be added. Which is a good

thing, because shortly after changing from Briscoe, The Model T

domain made a further change and began to fit only Ford radiators.*/

Factory factoryTwo = new DetroitRadiatorFactory(); WorkOrder workTwo = new WorkOrder(); workTwo.AssembleRadiator(factoryTwo);

Factory factoryThree = new McCordRadiatorFactory(); WorkOrder workThree = new WorkOrder(); workThree.AssembleRadiator(factoryThree);

}

}

Console Output

Briscoe Radiator.

Briscoe Radiator cap.

Assembling Radiator and cap.

Detroit Radiator.

Detroit Radiator cap.

Assembling Radiator and cap.

192C H A P T E R 1 0 C R E AT I O N A L PAT T E R N S

McCord Radiator. MsCord Radiator cap.

Assembling Radiator and cap.

Press any key to continue

The Standard: Abstract Factory Design Pattern

The standard acknowledges the use of the Abstract Factory design pattern when there is a requirement not to couple the client to an implementation that creates sets or families of object, yet to let the client indirectly control the build process.

Factory Method Pattern

A Factory Method pattern encapsulates a design feature when a class can’t foresee what objects it will be required to create and so delegates the task to subclasses. In everyday life, examples of a factory pattern include a translation service that delegates the task of translating news stories to a variety of specialist language translators; or a visual display controller that delegates the task of displaying data to display objects, which in turn display data in text or graphic format.

What

A Factory Method pattern is a design that defines an interface for creating objects but delegates the choice of what objects to create to subclasses.

Where

A Factory Method pattern is used where there is a design problem where a creator class is required to be decoupled from creating specific objects.

Why

In many domains there is a requirement for flexibility in creating a variety of objects and to localize the functionality to a set of specialized subclasses.

How

The creator class delegates to its subclasses, which override its factory method to create specific types, which in turn create content objects.

C H A P T E R 1 0 C R E AT I O N A L PAT T E R N S

193

Pattern Example

In the Model T domain, there is client code that manages composing two publications: a new car catalog and an owners’ technical manual.

The part of the problem we are focusing on is how to efficiently coordinate the tasks of creating different content and different arrangements in different publications: a page in a catalog is arranged with features and picture content, whereas a page in a technical manual is arranged with technical, picture, and instruction content.

To code this routine, we create an abstract page class (Page) that includes an abstract factory method (AddContent()) that the subclasses (CatalogPage and ManualPage) will override as they make a choice on which content to add to the respective page. An abstract Content class offers an interface to manage the creation of content by subclasses (FeaturesContent, InstructionContent,

PictureContent, and TechnicalContent). The factory method (AddContent()), which resides in the Page sub-classes (CatalogPage and ManualPage), makes the choice of what Content classes to instantiate in the respective page. That is the Factory Method pattern!

We shall now look at the Factory Method pattern in a UML diagram (see Figure 10-2) and then implement the pattern in code.

UML

Figure 10-2. Factory Method pattern

194 C H A P T E R 1 0 C R E AT I O N A L PAT T E R N S

Key Code Ingredients

The code for the Factory Method pattern has the following key ingredients:

An abstract Content class

Several classes that derive from Content class

FeaturesContent class

InstructionContent class

PictureContent class

TechnicalContent class

An abstract Page class

An abstract factory method

Several classes that derive from Page class

CatalogPage class

An override of the factory method

ManualPage class

An override of the factory method

Client class

A call to the factory method of an instantiated Page class Now let’s code the Factory Method pattern.

Pattern Code

The essence of the design lies in the Page class, where the factory method (AddContent()) is modified as abstract, which enables flexibility in the design of subclasses. Notice the role of Content class: it merely acts as an interface from which specialized content is derived (picture content and technical content, etc.). The subclasses (CatalogPage and ManualPage) specialize the class by choosing content and sequencing the arrangement of content on the page.

Content Class

public abstract class Content

{

public abstract void SomeContent();

}

C H A P T E R 1 0 C R E AT I O N A L PAT T E R N S

195

FeaturesContent Class

public class FeaturesContent: Content

{

public override void SomeContent()

{

Console.WriteLine("Technical content.");

}

public FeaturesContent() {;}

}

InstructionContent Class

public class InstructionContent: Content

{

public override void SomeContent()

{

Console.WriteLine("Instruction content.");

}

public InstructionContent() {;}

}

PictureContent Class

public class PictureContent: Content

{

public override void SomeContent()

{

Console.WriteLine("Picture content.");

}

public PictureContent() {;}

}

Соседние файлы в предмете Программирование на C++