// 具体创建者将重写工厂方法以改变其所返回的产品类型。 class WindowsDialog extends Dialog is method createButton():Button is return new WindowsButton()
class WebDialog extends Dialog is method createButton():Button is return new HTMLButton()
// 产品接口中将声明所有具体产品都必须实现的操作。 interface Button is method render() method onClick(f)
// 具体产品需提供产品接口的各种实现。 class WindowsButton implements Button is method render(a, b) is // 根据 Windows 样式渲染按钮。 method onClick(f) is // 绑定本地操作系统点击事件。
class HTMLButton implements Button is method render(a, b) is // 返回一个按钮的 HTML 表述。 method onClick(f) is // 绑定网络浏览器的点击事件。
class Application is field dialog: Dialog
// 程序根据当前配置或环境设定选择创建者的类型。 method initialize() is config = readApplicationConfigFile()
if (config.OS == "Windows") then dialog = new WindowsDialog() elseif (config.OS == "Web") then dialog = new WebDialog() else throw new Exception("错误!未知的操作系统。")
namespaceRefactoringGuru.DesignPatterns.FactoryMethod.Conceptual { // The Creator class declares the factory method that is supposed to return // an object of a Product class. The Creator's subclasses usually provide // the implementation of this method. abstractclassCreator { // Note that the Creator may also provide some default implementation of // the factory method. publicabstract IProduct FactoryMethod();
// Also note that, despite its name, the Creator's primary // responsibility is not creating products. Usually, it contains some // core business logic that relies on Product objects, returned by the // factory method. Subclasses can indirectly change that business logic // by overriding the factory method and returning a different type of // product from it. publicstringSomeOperation() { // Call the factory method to create a Product object. var product = FactoryMethod(); // Now, use the product. var result = "Creator: The same creator's code has just worked with " + product.Operation();
return result; } }
// Concrete Creators override the factory method in order to change the // resulting product's type. classConcreteCreator1 : Creator { // Note that the signature of the method still uses the abstract product // type, even though the concrete product is actually returned from the // method. This way the Creator can stay independent of concrete product // classes. publicoverride IProduct FactoryMethod() { returnnew ConcreteProduct1(); } }
// The Product interface declares the operations that all concrete products // must implement. publicinterfaceIProduct { stringOperation(); }
// Concrete Products provide various implementations of the Product // interface. classConcreteProduct1 : IProduct { publicstringOperation() { return"{Result of ConcreteProduct1}"; } }
classClient { publicvoidMain() { Console.WriteLine("App: Launched with the ConcreteCreator1."); ClientCode(new ConcreteCreator1()); Console.WriteLine("");
Console.WriteLine("App: Launched with the ConcreteCreator2."); ClientCode(new ConcreteCreator2()); }
// The client code works with an instance of a concrete creator, albeit // through its base interface. As long as the client keeps working with // the creator via the base interface, you can pass it any creator's // subclass. publicvoidClientCode(Creator creator) { // ... Console.WriteLine("Client: I'm not aware of the creator's class," + "but it still works.\n" + creator.SomeOperation()); // ... } }
classProgram { staticvoidMain(string[] args) { new Client().Main(); } } }
Output.txt: 执行结果
1 2 3 4 5 6 7
App: Launched with the ConcreteCreator1. Client: I'm not aware of the creator's class, but it still works. Creator: The same creator's code has just worked with {Result of ConcreteProduct1}
App: Launched with the ConcreteCreator2. Client: I'm not aware of the creator's class, but it still works. Creator: The same creator's code has just worked with {Result of ConcreteProduct2}
在 C++ 中使用模式
复杂度: ★☆☆
流行度: ★★★
使用示例: 工厂方法模式在 C++ 代码中得到了广泛使用。 当你需要在代码中提供高层次的灵活性时, 该模式会非常实用。
/** * Concrete Products provide various implementations of the Product interface. */ classConcreteProduct1 : public Product { public: std::string Operation()constoverride{ return"{Result of the ConcreteProduct1}"; } }; classConcreteProduct2 : public Product { public: std::string Operation()constoverride{ return"{Result of the ConcreteProduct2}"; } };
/** * The Creator class declares the factory method that is supposed to return an * object of a Product class. The Creator's subclasses usually provide the * implementation of this method. */
classCreator { /** * Note that the Creator may also provide some default implementation of the * factory method. */ public: virtual ~Creator(){}; virtual Product* FactoryMethod()const= 0; /** * Also note that, despite its name, the Creator's primary responsibility is * not creating products. Usually, it contains some core business logic that * relies on Product objects, returned by the factory method. Subclasses can * indirectly change that business logic by overriding the factory method and * returning a different type of product from it. */
std::string SomeOperation()const{ // Call the factory method to create a Product object. Product* product = this->FactoryMethod(); // Now, use the product. std::string result = "Creator: The same creator's code has just worked with " + product->Operation(); delete product; return result; } };
/** * Concrete Creators override the factory method in order to change the * resulting product's type. */ classConcreteCreator1 : public Creator { /** * Note that the signature of the method still uses the abstract product type, * even though the concrete product is actually returned from the method. This * way the Creator can stay independent of concrete product classes. */ public: Product* FactoryMethod()constoverride{ returnnewConcreteProduct1(); } };
/** * The client code works with an instance of a concrete creator, albeit through * its base interface. As long as the client keeps working with the creator via * the base interface, you can pass it any creator's subclass. */ voidClientCode(const Creator& creator){ // ... std::cout << "Client: I'm not aware of the creator's class, but it still works.\n" << creator.SomeOperation() << std::endl; // ... }
/** * The Application picks a creator's type depending on the configuration or * environment. */
intmain(){ std::cout << "App: Launched with the ConcreteCreator1.\n"; Creator* creator = newConcreteCreator1(); ClientCode(*creator); std::cout << std::endl; std::cout << "App: Launched with the ConcreteCreator2.\n"; Creator* creator2 = newConcreteCreator2(); ClientCode(*creator2);
delete creator; delete creator2; return0; }
Output.txt: 执行结果
1 2 3 4 5 6 7
App: Launched with the ConcreteCreator1. Client: I'm not aware of the creator's class, but it still works. Creator: The same creator's code has just worked with {Result of the ConcreteProduct1}
App: Launched with the ConcreteCreator2. Client: I'm not aware of the creator's class, but it still works. Creator: The same creator's code has just worked with {Result of the ConcreteProduct2}
/** * Base factory class. Note that "factory" is merely a role for the class. It * should have some core business logic which needs different products to be * created. */ publicabstractclassDialog {
/** * The concrete factory is usually chosen depending on configuration or * environment options. */ staticvoidconfigure() { if (System.getProperty("os.name").equals("Windows 10")) { dialog = newWindowsDialog(); } else { dialog = newHtmlDialog(); } }
/** * All of the client code should work with factories and products through * abstract interfaces. This way it does not care which factory it works * with and what kind of product it returns. */ staticvoidrunBusinessLogic() { dialog.renderWindow(); } }
/** * The Creator class declares the factory method that is supposed to return an * object of a Product class. The Creator's subclasses usually provide the * implementation of this method. */ abstractclassCreator { /** * Note that the Creator may also provide some default implementation of the * factory method. */ abstractpublicfunctionfactoryMethod(): Product;
/** * Also note that, despite its name, the Creator's primary responsibility is * not creating products. Usually, it contains some core business logic that * relies on Product objects, returned by the factory method. Subclasses can * indirectly change that business logic by overriding the factory method * and returning a different type of product from it. */ publicfunctionsomeOperation(): string { // Call the factory method to create a Product object. $product = $this->factoryMethod(); // Now, use the product. $result = "Creator: The same creator's code has just worked with " . $product->operation();
return$result; } }
/** * Concrete Creators override the factory method in order to change the * resulting product's type. */ classConcreteCreator1extendsCreator { /** * Note that the signature of the method still uses the abstract product * type, even though the concrete product is actually returned from the * method. This way the Creator can stay independent of concrete product * classes. */ publicfunctionfactoryMethod(): Product { returnnewConcreteProduct1(); } }
/** * The Product interface declares the operations that all concrete products must * implement. */ interfaceProduct { publicfunctionoperation(): string; }
/** * Concrete Products provide various implementations of the Product interface. */ classConcreteProduct1implementsProduct { publicfunctionoperation(): string { return"{Result of the ConcreteProduct1}"; } }
classConcreteProduct2implementsProduct { publicfunctionoperation(): string { return"{Result of the ConcreteProduct2}"; } }
/** * The client code works with an instance of a concrete creator, albeit through * its base interface. As long as the client keeps working with the creator via * the base interface, you can pass it any creator's subclass. */ functionclientCode(Creator $creator) { // ... echo"Client: I'm not aware of the creator's class, but it still works.\n" . $creator->someOperation(); // ... }
/** * The Application picks a creator's type depending on the configuration or * environment. */ echo"App: Launched with the ConcreteCreator1.\n"; clientCode(newConcreteCreator1()); echo"\n\n";
echo"App: Launched with the ConcreteCreator2.\n"; clientCode(newConcreteCreator2());
Output.txt: 执行结果
1 2 3 4 5 6 7
App: Launched with the ConcreteCreator1. Client: I'm not aware of the creator's class, but it still works. Creator: The same creator's code has just worked with {Result of the ConcreteProduct1}
App: Launched with the ConcreteCreator2. Client: I'm not aware of the creator's class, but it still works. Creator: The same creator's code has just worked with {Result of the ConcreteProduct2}
/** * The Creator declares a factory method that can be used as a substitution for * the direct constructor calls of products, for instance: * * - Before: $p = new FacebookConnector(); * - After: $p = $this->getSocialNetwork; * * This allows changing the type of the product being created by * SocialNetworkPoster's subclasses. */ abstractclassSocialNetworkPoster { /** * The actual factory method. Note that it returns the abstract connector. * This lets subclasses return any concrete connectors without breaking the * superclass' contract. */ abstractpublicfunctiongetSocialNetwork(): SocialNetworkConnector;
/** * When the factory method is used inside the Creator's business logic, the * subclasses may alter the logic indirectly by returning different types of * the connector from the factory method. */ publicfunctionpost($content): void { // Call the factory method to create a Product object... $network = $this->getSocialNetwork(); // ...then use it as you will. $network->logIn(); $network->createPost($content); $network->logout(); } }
/** * This Concrete Creator supports Facebook. Remember that this class also * inherits the 'post' method from the parent class. Concrete Creators are the * classes that the Client actually uses. */ classFacebookPosterextendsSocialNetworkPoster { private$login, $password;
publicfunctionlogIn(): void { echo"Send HTTP API request to log in user $this->email with " . "password $this->password\n"; }
publicfunctionlogOut(): void { echo"Send HTTP API request to log out user $this->email\n"; }
publicfunctioncreatePost($content): void { echo"Send HTTP API requests to create a post in LinkedIn timeline.\n"; } }
/** * The client code can work with any subclass of SocialNetworkPoster since it * doesn't depend on concrete classes. */ functionclientCode(SocialNetworkPoster $creator) { // ... $creator->post("Hello world!"); $creator->post("I had a large hamburger this morning!"); // ... }
/** * During the initialization phase, the app can decide which social network it * wants to work with, create an object of the proper subclass, and pass it to * the client code. */ echo"Testing ConcreteCreator1:\n"; clientCode(newFacebookPoster("john_smith", "******")); echo"\n\n";
Testing ConcreteCreator1: Send HTTP API request to log in user john_smith with password ****** Send HTTP API requests to create a post in Facebook timeline. Send HTTP API request to log out user john_smith Send HTTP API request to log in user john_smith with password ****** Send HTTP API requests to create a post in Facebook timeline. Send HTTP API request to log out user john_smith
Testing ConcreteCreator2: Send HTTP API request to log in user john_smith@example.com with password ****** Send HTTP API requests to create a post in LinkedIn timeline. Send HTTP API request to log out user john_smith@example.com Send HTTP API request to log in user john_smith@example.com with password ****** Send HTTP API requests to create a post in LinkedIn timeline. Send HTTP API request to log out user john_smith@example.com
from __future__ import annotations from abc import ABC, abstractmethod
classCreator(ABC): """ The Creator class declares the factory method that is supposed to return an object of a Product class. The Creator's subclasses usually provide the implementation of this method. """
@abstractmethod deffactory_method(self): """ Note that the Creator may also provide some default implementation of the factory method. """ pass
defsome_operation(self) -> str: """ Also note that, despite its name, the Creator's primary responsibility is not creating products. Usually, it contains some core business logic that relies on Product objects, returned by the factory method. Subclasses can indirectly change that business logic by overriding the factory method and returning a different type of product from it. """
# Call the factory method to create a Product object. product = self.factory_method()
# Now, use the product. result = f"Creator: The same creator's code has just worked with {product.operation()}"
return result
""" Concrete Creators override the factory method in order to change the resulting product's type. """
classConcreteCreator1(Creator): """ Note that the signature of the method still uses the abstract product type, even though the concrete product is actually returned from the method. This way the Creator can stay independent of concrete product classes. """
classProduct(ABC): """ The Product interface declares the operations that all concrete products must implement. """
@abstractmethod defoperation(self) -> str: pass
""" Concrete Products provide various implementations of the Product interface. """
classConcreteProduct1(Product): defoperation(self) -> str: return"{Result of the ConcreteProduct1}"
classConcreteProduct2(Product): defoperation(self) -> str: return"{Result of the ConcreteProduct2}"
defclient_code(creator: Creator) -> None: """ The client code works with an instance of a concrete creator, albeit through its base interface. As long as the client keeps working with the creator via the base interface, you can pass it any creator's subclass. """
print(f"Client: I'm not aware of the creator's class, but it still works.\n" f"{creator.some_operation()}", end="")
if __name__ == "__main__": print("App: Launched with the ConcreteCreator1.") client_code(ConcreteCreator1()) print("\n")
print("App: Launched with the ConcreteCreator2.") client_code(ConcreteCreator2())
Output.txt: 执行结果
1 2 3 4 5 6 7
App: Launched with the ConcreteCreator1. Client: I'm not aware of the creator's class, but it still works. Creator: The same creator's code has just worked with {Result of the ConcreteProduct1}
App: Launched with the ConcreteCreator2. Client: I'm not aware of the creator's class, but it still works. Creator: The same creator's code has just worked with {Result of the ConcreteProduct2}
# The Creator class declares the factory method that is supposed to return an # object of a Product class. The Creator's subclasses usually provide the # implementation of this method. classCreator # Note that the Creator may also provide some default implementation of the # factory method. deffactory_method raise NotImplementedError, "#{self.class} has not implemented method '#{__method__}'" end
# Also note that, despite its name, the Creator's primary responsibility is # not creating products. Usually, it contains some core business logic that # relies on Product objects, returned by the factory method. Subclasses can # indirectly change that business logic by overriding the factory method and # returning a different type of product from it. defsome_operation # Call the factory method to create a Product object. product = factory_method
# Now, use the product. result = "Creator: The same creator's code has just worked with #{product.operation}"
result end end
# Concrete Creators override the factory method in order to change the resulting # product's type. classConcreteCreator1 < Creator # Note that the signature of the method still uses the abstract product type, # even though the concrete product is actually returned from the method. This # way the Creator can stay independent of concrete product classes. deffactory_method ConcreteProduct1.new end end
classConcreteCreator2 < Creator # @return [ConcreteProduct2] deffactory_method ConcreteProduct2.new end end
# The Product interface declares the operations that all concrete products must # implement. classProduct # return [String] defoperation raise NotImplementedError, "#{self.class} has not implemented method '#{__method__}'" end end
# Concrete Products provide various implementations of the Product interface. classConcreteProduct1 < Product # @return [String] defoperation '{Result of the ConcreteProduct1}' end end
classConcreteProduct2 < Product # @return [String] defoperation '{Result of the ConcreteProduct2}' end end
# The client code works with an instance of a concrete creator, albeit through # its base interface. As long as the client keeps working with the creator via # the base interface, you can pass it any creator's subclass. defclient_code(creator) print "Client: I'm not aware of the creator's class, but it still works.\n"\ "#{creator.some_operation}" end
puts 'App: Launched with the ConcreteCreator1.' client_code(ConcreteCreator1.new) puts "\n\n"
puts 'App: Launched with the ConcreteCreator2.' client_code(ConcreteCreator2.new)
output.txt: 执行结果
1 2 3 4 5 6 7
App: Launched with the ConcreteCreator1. Client: I'm not aware of the creator's class, but it still works. Creator: The same creator's code has just worked with {Result of the ConcreteProduct1}
App: Launched with the ConcreteCreator2. Client: I'm not aware of the creator's class, but it still works. Creator: The same creator's code has just worked with {Result of the ConcreteProduct2}
在 Swift 中使用模式
复杂度: ★☆☆
流行度: ★★★
使用示例: 工厂方法模式在 Swift 代码中得到了广泛使用。 当你需要在代码中提供高层次的灵活性时, 该模式会非常实用。
/// The Creator protocol declares the factory method that's supposed to return a /// new object of a Product class. The Creator's subclasses usually provide the /// implementation of this method. protocolCreator {
/// Note that the Creator may also provide some default implementation of /// the factory method. funcfactoryMethod() -> Product
/// Also note that, despite its name, the Creator's primary responsibility /// is not creating products. Usually, it contains some core business logic /// that relies on Product objects, returned by the factory method. /// Subclasses can indirectly change that business logic by overriding the /// factory method and returning a different type of product from it. funcsomeOperation() -> String }
/// This extension implements the default behavior of the Creator. This behavior /// can be overridden in subclasses. extensionCreator {
funcsomeOperation() -> String { // Call the factory method to create a Product object. let product = factoryMethod()
// Now, use the product. return"Creator: The same creator's code has just worked with "+ product.operation() } }
/// Concrete Creators override the factory method in order to change the /// resulting product's type. classConcreteCreator1: Creator {
/// Note that the signature of the method still uses the abstract product /// type, even though the concrete product is actually returned from the /// method. This way the Creator can stay independent of concrete product /// classes. publicfuncfactoryMethod() -> Product { returnConcreteProduct1() } }
/// The Product protocol declares the operations that all concrete products must /// implement. protocolProduct {
funcoperation() -> String }
/// Concrete Products provide various implementations of the Product protocol. classConcreteProduct1: Product {
funcoperation() -> String { return"{Result of the ConcreteProduct1}" } }
classConcreteProduct2: Product {
funcoperation() -> String { return"{Result of the ConcreteProduct2}" } }
/// The client code works with an instance of a concrete creator, albeit through /// its base protocol. As long as the client keeps working with the creator via /// the base protocol, you can pass it any creator's subclass. classClient { // ... staticfuncsomeClientCode(creator: Creator) { print("Client: I'm not aware of the creator's class, but it still works.\n" + creator.someOperation()) } // ... }
/// Let's see how it all works together. classFactoryMethodConceptual: XCTestCase {
functestFactoryMethodConceptual() {
/// The Application picks a creator's type depending on the /// configuration or environment.
print("App: Launched with the ConcreteCreator1.") Client.someClientCode(creator: ConcreteCreator1())
print("\nApp: Launched with the ConcreteCreator2.") Client.someClientCode(creator: ConcreteCreator2()) } }
Output.txt: 执行结果
1 2 3 4 5 6 7
App: Launched with the ConcreteCreator1. Client: I'm not aware of the creator's class, but it still works. Creator: The same creator's code has just worked with {Result of the ConcreteProduct1}
App: Launched with the ConcreteCreator2. Client: I'm not aware of the creator's class, but it still works. Creator: The same creator's code has just worked with {Result of the ConcreteProduct2}
/** * The Creator class declares the factory method that is supposed to return an * object of a Product class. The Creator's subclasses usually provide the * implementation of this method. */ abstractclassCreator { /** * Note that the Creator may also provide some default implementation of the * factory method. */ publicabstractfactoryMethod(): Product;
/** * Also note that, despite its name, the Creator's primary responsibility is * not creating products. Usually, it contains some core business logic that * relies on Product objects, returned by the factory method. Subclasses can * indirectly change that business logic by overriding the factory method * and returning a different type of product from it. */ publicsomeOperation(): string { // Call the factory method to create a Product object. const product = this.factoryMethod(); // Now, use the product. return`Creator: The same creator's code has just worked with ${product.operation()}`; } }
/** * Concrete Creators override the factory method in order to change the * resulting product's type. */ classConcreteCreator1extendsCreator { /** * Note that the signature of the method still uses the abstract product * type, even though the concrete product is actually returned from the * method. This way the Creator can stay independent of concrete product * classes. */ publicfactoryMethod(): Product { returnnewConcreteProduct1(); } }
/** * The Product interface declares the operations that all concrete products must * implement. */ interfaceProduct { operation(): string; }
/** * Concrete Products provide various implementations of the Product interface. */ classConcreteProduct1implementsProduct { publicoperation(): string { return'{Result of the ConcreteProduct1}'; } }
classConcreteProduct2implementsProduct { publicoperation(): string { return'{Result of the ConcreteProduct2}'; } }
/** * The client code works with an instance of a concrete creator, albeit through * its base interface. As long as the client keeps working with the creator via * the base interface, you can pass it any creator's subclass. */ functionclientCode(creator: Creator) { // ... console.log('Client: I\'m not aware of the creator\'s class, but it still works.'); console.log(creator.someOperation()); // ... }
/** * The Application picks a creator's type depending on the configuration or * environment. */ console.log('App: Launched with the ConcreteCreator1.'); clientCode(newConcreteCreator1()); console.log('');
console.log('App: Launched with the ConcreteCreator2.'); clientCode(newConcreteCreator2());
Output.txt: 执行结果
1 2 3 4 5 6 7
App: Launched with the ConcreteCreator1. Client: I'm not aware of the creator's class, but it still works. Creator: The same creator's code has just worked with {Result of the ConcreteProduct1}
App: Launched with the ConcreteCreator2. Client: I'm not aware of the creator's class, but it still works. Creator: The same creator's code has just worked with {Result of the ConcreteProduct2}
概念示例
由于 Go 中缺少类和继承等 OOP 特性, 所以无法使用 Go 来实现经典的工厂方法模式。 不过, 我们仍然能实现模式的基础版本, 即简单工厂。