Today we will take a look at the factory method pattern that is used very frequently. After reading the principles, we will give the implementation source codes of .NET and JAVA.
definition:
Factory Method Pattern: Define an interface for creating objects, but let subclasses decide which class to instantiate . The factory method pattern lets a class defer instantiation to its subclasses .
Factory Method Pattern: Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.
Referred to as the Factory Pattern (Factory Pattern)
Also known as Virtual Constructor Pattern or Polymorphic Factory Pattern
The factory parent class is responsible for defining the public interface for creating product objects , while the factory subclass is responsible for generating specific product objects
The purpose is to delay the instantiation of the product class to the factory subclass , that is, to determine which specific product class should be instantiated through the factory subclass
analyze:
• No longer provide a factory class to be responsible for the creation of all subclasses in a unified manner, but instead hand over the creation process of specific subclasses to special factory subclasses to complete
• If a new subclass type appears, you only need to define a specific factory class for this new type of subclass to create an instance of the new subclass
Class Diagram:
The factory method pattern contains the following 4 roles:
Product (abstract product)
ConcreteProduct (specific product)
Factory (abstract factory)
ConcreteFactory (concrete factory)
applicability:
1. When a class does not know the class of the object it must create. 2. When a class wants its subclasses to specify the objects it creates. 3. When * delegating object creation responsibility to one of multiple helper * classes, and * wanting to localize the information which helper subclass is the proxy.
advantage:
The factory method is used to create the products that customers need, while also hiding from customers the details of which specific product class will be instantiated
The factory can independently determine which product object to create , and the details of how to create this object are completely encapsulated inside the specific factory
When adding new products to the system, it fully complies with the principle of opening and closing
shortcoming:
The number of classes in the system will increase in pairs , which increases the complexity of the system to a certain extent and will bring some additional overhead to the system
Increased abstraction and difficulty of understanding the system
Case 1: (.NET code)
The code listing includes:
Program.cs source code
using System;
using System.Configuration;
using System.Reflection;
namespace FactoryMethodSample
{
class Program
{
static void Main(string[] args)
{
LoggerFactory factory;
Logger logger;
//读取配置文件
string factoryString = ConfigurationManager.AppSettings["factory"];
//反射生成对象
factory = (LoggerFactory)Assembly.Load("FactoryMethodSample").CreateInstance(factoryString);
logger = factory.CreateLogger();
logger.WriteLog();
Console.Read();
}
}
}
Logger.cs
namespace FactoryMethodSample
{
interface Logger
{
void WriteLog();
}
}
FileLogger.cs
using System;
namespace FactoryMethodSample
{
class FileLogger : Logger
{
public void WriteLog()
{
Console.WriteLine("文件日志记录。");
}
}
}
DatabaseLogger.cs
using System;
namespace FactoryMethodSample
{
class DatabaseLogger : Logger
{
public void WriteLog()
{
Console.WriteLine("数据库日志记录。");
}
}
}
LoggerFactory.cs
namespace FactoryMethodSample
{
interface LoggerFactory
{
Logger CreateLogger();
}
}
FileLoggerFactory.cs
namespace FactoryMethodSample
{
class FileLoggerFactory : LoggerFactory
{
public Logger CreateLogger()
{
//创建文件日志记录器对象
Logger logger = new FileLogger();
//创建文件,代码省略
return logger;
}
}
}
DatabaseLoggerFactory.cs
namespace FactoryMethodSample
{
class DatabaseLoggerFactory : LoggerFactory
{
public Logger CreateLogger()
{
//连接数据库,代码省略
//创建数据库日志记录器对象
Logger logger = new DatabaseLogger();
//初始化数据库日志记录器,代码省略
return logger;
}
}
}
App.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="factory" value="FactoryMethodSample.FileLoggerFactory"/>
</appSettings>
</configuration>
Case 2: (JAVA code)
Product
public interface Work {
void doWork();
}
ConcreteProduct
public class StudentWork implements Work {
public void doWork() {
System.out.println("学生*作业!");
}
}
public class TeacherWork implements Work {
public void doWork() {
System.out.println("老师审批作业!");
}
}
Creator
public interface IWorkFactory {
Work getWork();
}
ConcreteCreator
public class StudentWorkFactory implements IWorkFactory {
public Work getWork() {
return new StudentWork();
}
}
public class TeacherWorkFactory implements IWorkFactory {
public Work getWork() {
return new TeacherWork();
}
}
Test
public class Test {
public static void main(String[] args) {
IWorkFactory studentWorkFactory = new StudentWorkFactory();
studentWorkFactory.getWork().doWork();
IWorkFactory teacherWorkFactory = new TeacherWorkFactory();
teacherWorkFactory.getWork().doWork();
}
}
The program runs and returns the result:
Students do their homework! The teacher approves the homework!