Detailed Design Pattern: Factory Method Pattern

 

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:

ü (1) Logger : Logger interface, acting as an abstract product role
ü (2) DatabaseLogger : database logger, acting as a specific product role
ü (3) FileLogger : file logger, acting as a specific product role
ü (4) LoggerFactory : logger factory interface, acting as an abstract factory
ü (5) DatabaseLoggerFactory : database logger factory class, acting as a specific factory role
ü (6) FileLoggerFactory : File logger factory class, acting as a specific factory role
ü (7) Program : client test class

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!

Guess you like

Origin blog.csdn.net/daobaqin/article/details/127155639