namespaceRefactoringGuru.DesignPatterns.AbstractFactory.Conceptual { // The Abstract Factory interface declares a set of methods that return // different abstract products. These products are called a family and are // related by a high-level theme or concept. Products of one family are // usually able to collaborate among themselves. A family of products may // have several variants, but the products of one variant are incompatible // with products of another. publicinterfaceIAbstractFactory { IAbstractProductA CreateProductA();
IAbstractProductB CreateProductB(); }
// Concrete Factories produce a family of products that belong to a single // variant. The factory guarantees that resulting products are compatible. // Note that signatures of the Concrete Factory's methods return an abstract // product, while inside the method a concrete product is instantiated. classConcreteFactory1 : IAbstractFactory { public IAbstractProductA CreateProductA() { returnnew ConcreteProductA1(); }
public IAbstractProductB CreateProductB() { returnnew ConcreteProductB1(); } }
// Each Concrete Factory has a corresponding product variant. classConcreteFactory2 : IAbstractFactory { public IAbstractProductA CreateProductA() { returnnew ConcreteProductA2(); }
public IAbstractProductB CreateProductB() { returnnew ConcreteProductB2(); } }
// Each distinct product of a product family should have a base interface. // All variants of the product must implement this interface. publicinterfaceIAbstractProductA { stringUsefulFunctionA(); }
// Concrete Products are created by corresponding Concrete Factories. classConcreteProductA1 : IAbstractProductA { publicstringUsefulFunctionA() { return"The result of the product A1."; } }
classConcreteProductA2 : IAbstractProductA { publicstringUsefulFunctionA() { return"The result of the product A2."; } }
// Here's the the base interface of another product. All products can // interact with each other, but proper interaction is possible only between // products of the same concrete variant. publicinterfaceIAbstractProductB { // Product B is able to do its own thing... stringUsefulFunctionB();
// ...but it also can collaborate with the ProductA. // // The Abstract Factory makes sure that all products it creates are of // the same variant and thus, compatible. stringAnotherUsefulFunctionB(IAbstractProductA collaborator); }
// Concrete Products are created by corresponding Concrete Factories. classConcreteProductB1 : IAbstractProductB { publicstringUsefulFunctionB() { return"The result of the product B1."; }
// The variant, Product B1, is only able to work correctly with the // variant, Product A1. Nevertheless, it accepts any instance of // AbstractProductA as an argument. publicstringAnotherUsefulFunctionB(IAbstractProductA collaborator) { var result = collaborator.UsefulFunctionA();
return$"The result of the B1 collaborating with the ({result})"; } }
classConcreteProductB2 : IAbstractProductB { publicstringUsefulFunctionB() { return"The result of the product B2."; }
// The variant, Product B2, is only able to work correctly with the // variant, Product A2. Nevertheless, it accepts any instance of // AbstractProductA as an argument. publicstringAnotherUsefulFunctionB(IAbstractProductA collaborator) { var result = collaborator.UsefulFunctionA();
return$"The result of the B2 collaborating with the ({result})"; } }
// The client code works with factories and products only through abstract // types: AbstractFactory and AbstractProduct. This lets you pass any // factory or product subclass to the client code without breaking it. classClient { publicvoidMain() { // The client code can work with any concrete factory class. Console.WriteLine("Client: Testing client code with the first factory type..."); ClientMethod(new ConcreteFactory1()); Console.WriteLine();
Console.WriteLine("Client: Testing the same client code with the second factory type..."); ClientMethod(new ConcreteFactory2()); }
publicvoidClientMethod(IAbstractFactory factory) { var productA = factory.CreateProductA(); var productB = factory.CreateProductB();
classProgram { staticvoidMain(string[] args) { new Client().Main(); } } }
执行结果:
1 2 3 4 5 6 7
Client: Testing client code with the first factory type... The result of the product B1. The result of the B1 collaborating with the (The result of the product A1.)
Client: Testing the same client code with the second factory type... The result of the product B2. The result of the B2 collaborating with the (The result of the product A2.)