工厂模式
本课属于 Coddy C# 学习旅程的“面向对象编程”单元。第 53 课,共 70 课。
工厂模式是一种创建型模式,它将对象的创建交给单独的方法或类。你不必在代码中直接使用 new,而是让工厂为你创建对象。这样可以集中管理创建逻辑,让代码更灵活。
设想这样一种情况:你需要创建不同类型的文档。如果没有工厂,你的代码就会与特定的类紧密耦合:
// 不使用工厂模式:创建逻辑分散在各处
IDocument doc;
if (type == "pdf")
doc = new PdfDocument();
else if (type == "word")
doc = new WordDocument();工厂将这项决策封装在一个地方:
public interface IDocument
{
void Open();
}
public class PdfDocument : IDocument
{
public void Open() => Console.WriteLine("Opening PDF");
}
public class WordDocument : IDocument
{
public void Open() => Console.WriteLine("Opening Word");
}
public class DocumentFactory
{
public IDocument Create(string type)
{
switch (type)
{
case "pdf":
return new PdfDocument();
case "word":
return new WordDocument();
default:
throw new ArgumentException("Unknown type");
}
}
}现在,客户端代码只需请求所需内容,无需了解具体的类:
var factory = new DocumentFactory();
IDocument doc = factory.Create("pdf");
doc.Open(); // 打开 PDF当你之后需要添加新类型时,工厂模式就能发挥优势。添加 SpreadsheetDocument 只需要修改工厂,而不必在创建文档的所有地方都进行修改。这种分离让你的代码库更易于维护和测试。
挑战
简单我们来使用工厂模式构建一个通知系统。你不必在代码中到处直接创建不同类型的通知,而是可以将创建逻辑集中在一个工厂类中,由它根据简单的字符串标识符决定要创建哪种通知。
你会将代码分成三个文件:
Notification.cs:在Notifications命名空间中定义INotification接口,其中包含一个返回字符串的Send(string message)方法。然后创建三个实现此接口的类:EmailNotification:返回"Email: {message}"SmsNotification:返回"SMS: {message}"PushNotification:返回"Push: {message}"
NotificationFactory.cs:在同一命名空间中创建NotificationFactory类,并添加Create(string type)方法,根据类型字符串返回相应的INotification:"email"返回一个EmailNotification"sms"返回一个SmsNotification"push"返回一个PushNotification
EmailNotification。Program.cs:创建一个工厂实例,并使用它根据输入创建通知,从而将所有部分组合起来。由工厂负责决定要实例化哪个具体类。
你会收到两个输入:
- 通知类型(例如,
sms) - 要发送的消息(例如,
Your order has shipped)
使用工厂创建相应的通知类型,然后调用它的 Send 方法传入消息,并打印结果。
例如,如果输入是 push 和 Meeting in 5 minutes,输出应为:
Push: Meeting in 5 minutes注意,主代码中不会使用 new EmailNotification() 或类似写法,而是直接向工厂请求所需的通知。如果之后添加 SlackNotification,你只需更新工厂,而不必修改每个创建通知的地方!
亲手试试
using System;
using Notifications;
class Program
{
public static void Main(string[] args)
{
// 读取输入
string type = Console.ReadLine();
string message = Console.ReadLine();
// TODO:创建一个 NotificationFactory 实例
// TODO:使用工厂创建对应的通知
// TODO:调用 Send 方法并打印结果
}
}
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
面向对象编程中的所有课
自己练习: C# 在线编译器