在软件开发中,经常会遇到需要根据不同条件创建不同对象的情况。如果这些对象的创建逻辑没有遵循设计模式,那么代码将变得复杂,并且未来进行扩展时也会非常困难。在这种情况下,可以考虑使用工厂模式来抽象对象创建的复杂性,使得未来的添加变得轻松。
工厂模式属于创建型模式,它处理对象的创建。在本文中,将尝试通过一个简单的C#控制台应用程序来学习工厂模式。
在编写代码时,可能会遇到基于某些条件创建对象的情况。例如,如果实现如下,那么添加新的日志选项将需要在客户端代码库中进行大量的代码更改,这不是一个好的实践。
为了更好地理解,可以创建一个简单的日志工厂,它将帮助客户端根据他们的选择记录消息到不同的选项。
首先,需要创建一个接口或抽象类作为所有将在工厂中创建实例的类的基类。在这里,使用了一个名为ILogger的接口,它有一个Log方法。
public interface ILogger
{
void Log(string message);
}
现在,将在所有希望从日志工厂返回的类中实现这个ILogger。在这里,理想情况下Log方法应该有将消息记录到文件的实际方法,但为了演示目的,只是添加了一个控制台消息。
class FileLogger : ILogger
{
public void Log(string message)
{
Console.WriteLine("{0} - Logged in File.", message);
}
}
以同样的方式实现ILogger到DatabaseLogger,同时添加Log方法定义。
class DatabaseLogger : ILogger
{
public void Log(string message)
{
Console.WriteLine("{0} - Logged in Database.", message);
}
}
EventViewerLogger也实现了ILogger,并且根据类型添加了Log方法定义。可以添加新的日志类,这些类与这些日志类相同。
class EventViewerLogger : ILogger
{
public void Log(string message)
{
Console.WriteLine("{0} - Logged in EventViewer.", message);
}
}
创建一个枚举以轻松识别LoggerType。如果有新的LoggerType,那么可以在这里添加它。
enum LoggerType
{
File,
Database,
EventViewer
}
最后,到达了LoggerFactory。现在这个工厂将根据枚举值负责对象的创建,并将创建的实例返回给客户端代码,该实例将是ILogger类型。
class LoggerFactory
{
public static ILogger Get(LoggerType type)
{
switch (type)
{
case LoggerType.Database:
return new DatabaseLogger();
case LoggerType.EventViewer:
return new EventViewerLogger();
case LoggerType.File:
default:
return new FileLogger();
}
}
}
如果查看上面的代码,可以看到对象创建逻辑在工厂中被抽象化,并且对象是根据请求的对象类型创建的。由于返回类型是接口ILogger,客户端代码不需要担心新添加到工厂的对象。
编写了客户端代码来使用这个工厂,如下所示:
static void Main(string[] args)
{
ILogger logger1 = LoggerFactory.Get(LoggerType.Database);
logger1.Log("Message from Main");
ILogger logger2 = LoggerFactory.Get(LoggerType.File);
logger2.Log("Message from Main");
ILogger logger3 = LoggerFactory.Get(LoggerType.EventViewer);
logger3.Log("Message from Main");
Console.ReadKey();
}